lprng-3.8.B/0000777000131400013140000000000011531672402007664 500000000000000lprng-3.8.B/TODO0000644000131400013140000000052111531672127010272 00000000000000Sun Jun 23 14:05:30 PDT 2002 Done Jobs/Error Jobs - sorting of jobs has error jobs and then done jobs so 'remove_done' will retain error jobs. - sort these by completion time and remove all but the last N. You will then have to reorder list by other criteria. (Reported by: Akop Pogosian ) lprng-3.8.B/config.h.in0000644000131400013140000003515211531672271011635 00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* full path to chgrp */ #undef CHGRP /* full path to chown */ #undef CHOWN /* screen clear program */ #undef CLEAR /* number of jobs to retain status of */ #undef DONE_JOBS /* number of seconds to retain job status */ #undef DONE_JOBS_MAX_AGE /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* default LD_LIBRARY_PATH for filters */ #undef FILTER_LD_PATH /* default PATH for filters */ #undef FILTER_PATH /* Force Localhost (force_localhost) */ #undef FORCE_LOCALHOST /* groupid to run LPRng as, default daemon */ #undef GROUPID /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_NAMESER_H /* Define to 1 if you have the header file. */ #undef HAVE_ASSERT_H /* Define to 1 if you have the `cfsetispeed' function. */ #undef HAVE_CFSETISPEED /* Define to 1 if you have the header file. */ #undef HAVE_COMPAT_H /* Define to 1 if you have the header file. */ #undef HAVE_COM_ERR_H /* Define to 1 if you have the header file. */ #undef HAVE_CTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_CTYPE_H /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the header file. */ #undef HAVE_ENDIAN_H /* Define to 1 if you have the header file. */ #undef HAVE_ERRNO_H /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if the system has the type `fd_set'. */ #undef HAVE_FD_SET /* Define to 1 if you have the header file. */ #undef HAVE_FILEHDR_H /* Define to 1 if you have the `flock' function. */ #undef HAVE_FLOCK /* have flock definition */ #undef HAVE_FLOCK_DEF /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK /* Define to 1 if you have the `getdtablesize' function. */ #undef HAVE_GETDTABLESIZE /* Define to 1 if you have the `gethostbyname2' function. */ #undef HAVE_GETHOSTBYNAME2 /* Define to 1 if you have the `gethostname' function. */ #undef HAVE_GETHOSTNAME /* have gethostname definition */ #undef HAVE_GETHOSTNAME_DEF /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT /* Define to 1 if you have the header file. */ #undef HAVE_GRP_H /* Define to 1 if you have the `inet_aton' function. */ #undef HAVE_INET_ATON /* Define to 1 if you have the `inet_ntop' function. */ #undef HAVE_INET_NTOP /* Define to 1 if you have the `inet_pton' function. */ #undef HAVE_INET_PTON /* Define to 1 if you have the `initgroups' function. */ #undef HAVE_INITGROUPS /* Define to 1 if you have the `innetgr' function. */ #undef HAVE_INNETGR /* use innetgr(1) */ #undef HAVE_INNETGR_DEF /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `killpg' function. */ #undef HAVE_KILLPG /* Define to 1 if you have the `krb5_free_data_contents' function. */ #undef HAVE_KRB5_FREE_DATA_CONTENTS /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_H /* have krb5_read_message */ #undef HAVE_KRB5_READ_MESSAGE /* have krb5_xfree */ #undef HAVE_KRB5_XFREE /* have krb_xfree */ #undef HAVE_KRB_XFREE /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* Define to 1 if you have the `lockf' function. */ #undef HAVE_LOCKF /* have lseek definition */ #undef HAVE_LSEEK_PROTO /* Define to 1 if you have the header file. */ #undef HAVE_MACHINE_VMPARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkstemp' function. */ #undef HAVE_MKSTEMP /* Define to 1 if you have the `mktemp' function. */ #undef HAVE_MKTEMP /* Define to 1 if you have the header file. */ #undef HAVE_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the `openlog' function. */ #undef HAVE_OPENLOG /* have openlog definition */ #undef HAVE_OPENLOG_DEF /* Define to 1 if you have the `putenv' function. */ #undef HAVE_PUTENV /* Define to 1 if you have the header file. */ #undef HAVE_PWD_H /* Define to 1 if you have the `rand' function. */ #undef HAVE_RAND /* Define to 1 if you have the `random' function. */ #undef HAVE_RANDOM /* Define to 1 if you have the header file. */ #undef HAVE_RESOLV_H /* Define to 1 if you have the header file. */ #undef HAVE_SELECT_H /* Define to 1 if you have the `setenv' function. */ #undef HAVE_SETENV /* Define to 1 if you have the `seteuid' function. */ #undef HAVE_SETEUID /* Define to 1 if you have the `setgroups' function. */ #undef HAVE_SETGROUPS /* Define to 1 if you have the header file. */ #undef HAVE_SETJMP_H /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE /* Define to 1 if you have the `setpgid' function. */ #undef HAVE_SETPGID /* Define to 1 if you have the `setproctitle' function. */ #undef HAVE_SETPROCTITLE /* setproctitle defined */ #undef HAVE_SETPROCTITLE_DEF /* Define to 1 if you have the `setresuid' function. */ #undef HAVE_SETRESUID /* Define to 1 if you have the `setreuid' function. */ #undef HAVE_SETREUID /* Define to 1 if you have the `setruid' function. */ #undef HAVE_SETRUID /* Define to 1 if you have the `setsid' function. */ #undef HAVE_SETSID /* Define to 1 if you have the header file. */ #undef HAVE_SGTTY_H /* Define to 1 if you have the `sigaction' function. */ #undef HAVE_SIGACTION /* Define to 1 if you have the `siglongjmp' function. */ #undef HAVE_SIGLONGJMP /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H /* Define to 1 if you have the `sigprocmask' function. */ #undef HAVE_SIGPROCMASK /* Define to 1 if you have the `socketpair' function. */ #undef HAVE_SOCKETPAIR /* Define to 1 if the system has the type `socklen_t'. */ #undef HAVE_SOCKLEN_T /* Define to 1 if you have the header file. */ #undef HAVE_STAB_H /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* have strcasecmp definition */ #undef HAVE_STRCASECMP_DEF /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP /* Define to 1 if you have the `strerror' function. */ #undef HAVE_STRERROR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the `sysinfo' function. */ #undef HAVE_SYSINFO /* have syslog definition */ #undef HAVE_SYSLOG_DEF /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_DIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EXEC_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FCNTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MOUNT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_NDIR_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PSTAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H /* have sys_syslist */ #undef HAVE_SYS_SIGLIST /* sys_siglist defined */ #undef HAVE_SYS_SIGLIST_DEF /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SIGNAL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOCKET_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STATVFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSLOG_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SYSTEMINFO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TERMIOX_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TERMIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TTOLD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TTYCOM_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_UTSNAME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_VFS_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* Define to 1 if you have the `tcdrain' function. */ #undef HAVE_TCDRAIN /* Define to 1 if you have the `tcflush' function. */ #undef HAVE_TCFLUSH /* have tcpd */ #undef HAVE_TCPD_H /* Define to 1 if you have the `tcsetattr' function. */ #undef HAVE_TCSETATTR /* Define to 1 if you have the header file. */ #undef HAVE_TERMCAP_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIOS_H /* Define to 1 if you have the header file. */ #undef HAVE_TERMIO_H /* Define to 1 if you have the header file. */ #undef HAVE_TERM_H /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the `uname' function. */ #undef HAVE_UNAME /* have union wait */ #undef HAVE_UNION_WAIT /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `unsetenv' function. */ #undef HAVE_UNSETENV /* Define to 1 if you have the header file. */ #undef HAVE_UTSNAME_H /* Define to 1 if you have the header file. */ #undef HAVE_VARARGS_H /* Define to 1 if you have the `vfork' function. */ #undef HAVE_VFORK /* Define to 1 if you have the header file. */ #undef HAVE_VFORK_H /* Define to 1 if you have the header file. */ #undef HAVE_VMPARAM_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* Define to 1 if you have the `wait3' function. */ #undef HAVE_WAIT3 /* Define to 1 if you have the `waitpid' function. */ #undef HAVE_WAITPID /* Define to 1 if `fork' works. */ #undef HAVE_WORKING_FORK /* Define to 1 if `vfork' works. */ #undef HAVE_WORKING_VFORK /* Define to 1 if you have the `_res' function. */ #undef HAVE__RES /* have _sys_siglist */ #undef HAVE__SYS_SIGLIST /* _sys_siglist defined */ #undef HAVE__SYS_SIGLIST_DEF /* in6_addr defined */ #undef IN6_ADDR /* in_addr6 defined */ #undef IN_ADDR6 /* ipV6 */ #undef IPV6 /* enable Kerberos support */ #undef KERBEROS /* default value for lpd_listen_port (0 means default port ("=515"), "=off" means to not listen at all */ #undef LPD_LISTEN_PORT /* full path to openssl */ #undef OPENSSL /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the version of this package. */ #undef PACKAGE_VERSION /* full path to prutil */ #undef PRUTIL /* require configfiles */ #undef REQUIRE_CONFIGFILES /* Define as the return type of signal handlers (`int' or `void'). */ #undef RETSIGTYPE /* ssl enabled */ #undef SSL_ENABLE /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* struct st_mtimensec present */ #undef ST_MTIMENSEC /* stat st_mtimespec.tv_nsec present */ #undef ST_MTIMESPEC_TV_NSEC /* tcpwrappers */ #undef TCPWRAPPERS /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME /* userid to run LPRng as, default daemon */ #undef USERID /* use sgttyb */ #undef USE_SGTTYB /* statvfs statfs */ #undef USE_STATFS_TYPE /* use termios */ #undef USE_STTY /* use termio */ #undef USE_TERMIO /* use termios */ #undef USE_TERMIOS /* use termiox */ #undef USE_TERMIOX /* Version number of package */ #undef VERSION /* Build dynamic loadable plugins */ #undef WITHPLUGINS /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS /* Define for large files, on AIX-style hosts. */ #undef _LARGE_FILES /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `int' if doesn't define. */ #undef gid_t /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to `int' if does not define. */ #undef mode_t /* Define to `long int' if does not define. */ #undef off_t /* Define to `int' if does not define. */ #undef pid_t /* Define to `unsigned int' if does not define. */ #undef size_t /* Define to `int' if doesn't define. */ #undef uid_t /* Define as `fork' if `vfork' does not work. */ #undef vfork /* Define to empty if the keyword `volatile' does not work. Warning: valid code using `volatile' can become incorrect without. Disable with care. */ #undef volatile lprng-3.8.B/COPYRIGHT0000644000131400013140000001146611531672125011105 00000000000000 COPYRIGHT NOTICES Copyright (c) 1986-2001 Patrick Powell THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Copyright 1986-2000, Patrick Powell, San Diego, CA. All rights reserved. The following notice is included to satisfy the requirements of the BSD 4.4 Software Distribution. Copyright (c) 1988 The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed by the University of California, Berkeley and its contributors. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. July 22, 1999 To All Licensees, Distributors of Any Version of BSD: As you know, certain of the Berkeley Software Distribution ("BSD") source code files require that further distributions of products containing all or portions of the software, acknowledge within their advertising materials that such products contain software developed by UC Berkeley and its contributors. Specifically, the provision reads: " * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors." Effective immediately, licensees and distributors are no longer required to include the acknowledgement within advertising materials. Accordingly, the foregoing paragraph of those BSD Unix files containing it is hereby deleted in its entirety. William Hoskins Director, Office of Technology Licensing University of California, Berkeley THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. src/common/md5.c contains code which states: * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. ----------------------------------------------------------------------- Addendum Fri Jun 21 17:06:33 PDT 2002 Under the terms of the OpenSSL license, the following statement is included: This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/) If you wish to distribute the LPRng source code or binaries of any of the programs in the LPRng packages under terms of the GNU license, then when any package or portion of the LPRng is configured to use any facility or utility of the OpenSSL distribution, the additional following clause will be applied, as recommended in the OpenSSL 0.9.6c release FAQ: "This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed." ----------------------------------------------------------------------- lprng-3.8.B/configure.ac0000644000131400013140000011057311531672221012074 00000000000000AC_INIT(LPRng,3.8.B,lprng-devel@lists.sf.net) AC_CONFIG_SRCDIR(src/common/lpr.c) AM_CONFIG_HEADER(config.h) AM_INIT_AUTOMAKE([foreign]) AM_MAINTAINER_MODE AC_PREFIX_DEFAULT(/usr/local) mysaved_CFLAGSset="${CFLAGS+set}" AC_PROG_CC if test "$ac_cv_prog_gcc" = yes; then if test "$mysaved_CFLAGSset" != set ; then CFLAGS="-g -W -Wall -Wno-unused -Wstrict-prototypes -Wmissing-prototypes" fi fi; AC_SYS_LARGEFILE AC_PROG_AWK AC_SUBST(AWK) AC_PATH_PROG(SED,sed)dnl AC_SUBST(SED)dnl AC_PATH_PROG(PERL,perl)dnl AC_SUBST(PERL)dnl dnl -- TODO: dnl this is used in checkpc, why not just use "chown" there? dnl same with chgrp dnl -- AC_PATH_PROG(CHOWN,chown)dnl AC_DEFINE_UNQUOTED(CHOWN, "$CHOWN",[full path to chown]) AC_PATH_PROG(CHGRP,chgrp)dnl AC_DEFINE_UNQUOTED(CHGRP, "$CHGRP",[full path to chgrp]) AC_PATH_PROG(PRUTIL,pr)dnl AC_DEFINE_UNQUOTED(PRUTIL, "$PRUTIL",[full path to prutil]) AC_PATH_PROG(OPENSSL,openssl)dnl AC_SUBST(OPENSSL)dnl AC_DEFINE_UNQUOTED(OPENSSL, "$OPENSSL",[full path to openssl]) dnl dnl check to see if setuid is suppressed dnl AC_ARG_ENABLE( setuid, dnl AS_HELP_STRING([--disable-setuid],[do not install client executables setuid root]), dnl [ dnl if test "$enableval" = "yes" ; then dnl PERMS=SUID_ROOT_PERMS dnl else dnl PERMS=NORM_PERMS dnl fi dnl ], dnl [ PERMS=SUID_ROOT_PERMS ], dnl ) dnl AC_MSG_NOTICE([installing client with $PERMS]) dnl AC_SUBST(PERMS) dnl check to see if priv ports required ENABLE_BOOLEAN(priv_ports, [--enable-priv_ports],[require connections from privileged ports], "no", [require connections from priviledged ports: $v], [PRIV_PORTS=""],[PRIV_PORTS="#"]) AC_SUBST(PRIV_PORTS) dnl check if only accept from local host ENABLE_BOOLEAN(remote, [--disable-remote],[do not accept remote jobs by default], "yes", [listen for remote connections by default : $v], [NOREMOTE="#" LPD_LISTEN_PORT='"=515"' ],[NOREMOTE="" LPD_LISTEN_PORT='"=off"' ]) AC_SUBST(LPD_LISTEN_PORT) AC_SUBST(NOREMOTE) AC_DEFINE_UNQUOTED(LPD_LISTEN_PORT, $LPD_LISTEN_PORT,[default value for lpd_listen_port (0 means default port ("=515"), "=off" means to not listen at all]) ENABLE_BOOLEAN(lpd.conf.local, [--enable-lpd.conf.local],[include lpd.conf.local in lpd.conf], "no", [include lpd.conf.local in lpd.conf : $v], [INCLUDELPDCONFLOCAL="" ],[INCLUDELPDCONFLOCAL="# " ]) AC_SUBST(INCLUDELPDCONFLOCAL) dnl check to see if force_localhost is suppressed ENABLE_BOOLEAN(force_localhost, [--disable-force_localhost],[disable force_localhost default], "yes", [force_localhost is default : $v], [FORCE_LOCALHOST=1],[FORCE_LOCALHOST=0]) AC_DEFINE_UNQUOTED(FORCE_LOCALHOST,"$FORCE_LOCALHOST",[Force Localhost (force_localhost)]) dnl check to see if clients require lpd.conf and printcap ENABLE_BOOLEAN(require_configfiles, [--disable-require_configfiles],[client programs require lpd.conf, printcap], "yes", [client programs require lpd.conf, printcap: $v], [REQUIRE_CONFIGFILES=1], [REQUIRE_CONFIGFILES=0]) AC_DEFINE_UNQUOTED(REQUIRE_CONFIGFILES, "$REQUIRE_CONFIGFILES",[require configfiles]) dnl check to see if kerberos is disabled AH_TEMPLATE(KERBEROS,[enable Kerberos support]) ENABLE_BOOLEAN(kerberos, [--enable-kerberos],[enable kerberos support], "no", [enable kerberos support : $v], [KERBEROS=1; AC_DEFINE_UNQUOTED(KERBEROS,"1")], [KERBEROS=""]) AM_CONDITIONAL(WITHKERBEROS, test $v = yes) AC_SUBST(KERBEROS) dnl find kerberos libraries ENABLE_BOOLEAN(kerberos_checks, [--disable-kerberos_checks],[disable kerberos library location and checking for support], "yes", [locate Kerberos libraries and check : $v], [KERBEROS_CHECKS=1],[KERBEROS_CHECKS=""]) WITH_DIR(lpddir, [--with-lpddir=DIR],[lpd executable directory (default ${sbindir})], [lpdbindir],['${sbindir}'], [directory to place lpd executable into : $lpdbindir]) AC_ARG_WITH(config_subdir, AS_HELP_STRING([--with-config_subdir=SUBDIR],[configuration subdirectory (default 'lpd')]), CONFIGSUBDIR=$withval,CONFIGSUBDIR=lpd ) configdir=\${sysconfdir}/${CONFIGSUBDIR} AC_MSG_NOTICE([configuration directory configdir= $configdir]) AC_SUBST(configdir) WITH_DIR(lpd_conf_path, [--with-lpd_conf_path=PATH],[path of lpd.conf (default: ${configdir}/lpd.conf)], [LPD_CONF_PATH],['${configdir}/lpd.conf'], [lpd.conf location : $LPD_CONF_PATH]) AC_SUBST(LPD_CONF_PATH) WITH_DIR(lpd_perms_path, [--with-lpd_perms_path=PATH],[path of lpd.perms (default: ${configdir}/lpd.perms)], [LPD_PERMS_PATH],['${configdir}/lpd.perms'], [lpd.perms location : $LPD_PERMS_PATH]) AC_SUBST(LPD_PERMS_PATH) WITH_DIR(printcap_path, [--with-printcap_path=PATH],[path of printcap (default ${sysconfdir}/printcap)], [PRINTCAP_PATH],['${sysconfdir}/printcap'], [printcap location : $PRINTCAP_PATH]) AC_SUBST(PRINTCAP_PATH) WITH_DIR(lpd_printcap_path, [--with-lpd_printcap_path=PATH],[path of lpd_printcap (default ${configdir}/lpd_printcap)], [LPD_PRINTCAP_PATH],['${configdir}/lpd_printcap'], [lpd_printcap location : $LPD_PRINTCAP_PATH]) WITH_DIR(localedir, [--with-localedir=PATH],[specify locale information directory], [localedir],['${datadir}/locale'], [locale information directory is : $localedir]) AC_SUBST(localedir) WITH_DIR(unix_socket_path, [--with-unix_socket_path=DIR],[unix socket path (default /var/run/lprng)], [UNIXSOCKETPATH],[/var/run/lprng], [unix socket path is : $UNIXSOCKETPATH]) WITH_DIR(lockfile, [--with-lockfile=PATH],[lockfile PATH, default /var/run/lpd ], [LOCKFILE],['/var/run/lpd'], [lockfile directory : $LOCKFILE]) WITH_DIR(spooldir, [--with-spooldir=PATH],[default spool directory, default /var/spool/lpd ], [SD_DEFAULT],['/var/spool/lpd'], [default spool directory (:sd=SPOOLDIR/%P) : $SD_DEFAULT]) WITH_DIR(plugindir, [--with-plugindir=DIR],[dynamic loadable plugin directory (default ${libdir}/lprng/plugins)], [plugindir],['${libdir}/lprng/plugins'], [plugin directory plugindir = $plugindir]) WITH_DIR(filterdir, [--with-filterdir=DIR],[filter directory (default ${libexecdir}/filters)], [filterdir],['${libexecdir}/filters'], [filter directory filterdir = $filterdir]) dnl FILTER_LD_PATH (LD_LIBRARY_PATH for filters) value dnl AC_ARG_WITH(ld_library_path, AS_HELP_STRING([--with-ld_library_path=PATH],[FILTER_LD_PATH value, default empty (for Solaris you might need /lib:/usr/lib:/usr/local/lib)]), FILTER_LD_PATH="$withval", FILTER_LD_PATH="" ) AC_MSG_NOTICE([filter LD_LIBRARY_PATH: FILTER_LD_PATH = $FILTER_LD_PATH]) AC_SUBST(FILTER_LD_PATH) AC_DEFINE_UNQUOTED(FILTER_LD_PATH, "$FILTER_LD_PATH",[default LD_LIBRARY_PATH for filters]) dnl filter PATH value dnl AC_ARG_WITH(filter-path, AS_HELP_STRING([--with-filter-path=PATH],[filter PATH value, default /bin:/usr/bin:/usr/local/bin ]), FILTER_PATH="$withval", FILTER_PATH="/bin:/usr/bin:/usr/local/bin" ) AC_MSG_NOTICE([filter PATH: FILTER_PATH = $FILTER_PATH]) AC_SUBST(FILTER_PATH) AC_DEFINE_UNQUOTED(FILTER_PATH, "$FILTER_PATH",[default PATH for filters]) dnl user name dnl AC_ARG_WITH(userid, AS_HELP_STRING([--with-userid=NAME],[run LPRng software as this userid, default daemon ]), USERID="$withval", USERID="daemon", ) AC_MSG_NOTICE([userID to run lpd as : $USERID]) AC_DEFINE_UNQUOTED(USERID, "$USERID",[userid to run LPRng as, default daemon]) dnl group value dnl AC_ARG_WITH(groupid, AS_HELP_STRING([--with-groupid=NAME],[run LPRng software as this groupid, default daemon ]), GROUPID="$withval", GROUPID="daemon", ) AC_MSG_NOTICE([groupID to run lpd as : $GROUPID]) AC_DEFINE_UNQUOTED(GROUPID, "$GROUPID",[groupid to run LPRng as, default daemon]) dnl done_jobs value dnl AC_ARG_WITH(done_jobs, AS_HELP_STRING([--with-done_jobs=N],[retain last N job status, default 1]), DONE_JOBS="$withval", DONE_JOBS="1", ) AC_MSG_NOTICE([number of job status to retain : $DONE_JOBS]) AC_DEFINE_UNQUOTED(DONE_JOBS, "$DONE_JOBS",[number of jobs to retain status of]) dnl done_jobs_max_age value dnl AC_ARG_WITH(done_jobs_max_age, AS_HELP_STRING([--with-done_jobs_max_age=N],[retain job status N seconds, default 0 - no expiry]), DONE_JOBS_MAX_AGE="$withval", DONE_JOBS_MAX_AGE="0", ) AC_MSG_NOTICE([max age to retain job status (0=no expiry): $DONE_JOBS_MAX_AGE]) AC_DEFINE_UNQUOTED(DONE_JOBS_MAX_AGE, "$DONE_JOBS_MAX_AGE",[number of seconds to retain job status]) dnl clear program dnl AC_MSG_CHECKING(terminal screen clear program) if test -z "$CLEAR" ; then AC_PATH_PROG(CLEAR,clear)dnl fi if test -z "$CLEAR" ; then AC_MSG_WARN([Program 'clear' is not found. Set environment CLEAR=no if you do not want to use it]); exit 1 fi if test "$CLEAR" = "no" ; then CLEAR= ; fi if test -n "$CLEAR" ; then AC_DEFINE_UNQUOTED(CLEAR,"$CLEAR",[screen clear program]) fi dnl ---------------------------------------------------------------------------- dnl ----------- C compiler checks ----------------------------------------- AC_C_CONST AC_C_INLINE AC_C_VOLATILE AC_HEADER_STDC AC_HEADER_DIRENT AC_HEADER_SYS_WAIT AC_HEADER_TIME dnl typedefs: AC_TYPE_SIGNAL AC_TYPE_UID_T AC_TYPE_SIZE_T AC_TYPE_MODE_T AC_TYPE_OFF_T AC_TYPE_PID_T AC_CHECK_TYPES( fd_set,,,[ #include #include #include ] ) AC_CHECK_TYPES( socklen_t,,,[ #include #include ] ) checklibs= dnl ---------------------------------------------------------------------------- dnl headers: AC_CHECK_HEADERS(arpa/inet.h arpa/nameser.h assert.h com_err.h compat.h ctype.h ctypes.h dirent.h errno.h fcntl.h filehdr.h grp.h limits.h locale.h machine/vmparam.h malloc.h memory.h ndir.h netdb.h netinet/in.h pwd.h resolv.h select.h setjmp.h sgtty.h signal.h stab.h stdarg.h stdio.h stdlib.h string.h strings.h sys/dir.h sys/exec.h sys/fcntl.h sys/file.h sys/ioctl.h sys/mount.h sys/ndir.h sys/param.h sys/pstat.h sys/resource.h sys/select.h sys/signal.h sys/socket.h sys/stat.h sys/statfs.h sys/statvfs.h sys/syslog.h sys/systeminfo.h sys/termio.h sys/termiox.h sys/time.h sys/ttold.h sys/ttycom.h sys/types.h sys/utsname.h sys/vfs.h sys/wait.h syslog.h term.h termcap.h termio.h termios.h time.h unistd.h utsname.h varargs.h vmparam.h endian.h stdint.h) dnl ---------------------------------------------------------------------------- dnl libraries: dnl it might be nice to put them to some SOCKETLIBS or stuff like that instead, dnl but given it is not needed on Linux, this will both seldom tested and dnl seldom be useful. dnl A/UX uses this... AC_SEARCH_LIBS(getpwent, posix) dnl TODO: error out if not there? AC_SEARCH_LIBS(gethostbyaddr, [nsl_s nsl net_s net]) AC_SEARCH_LIBS(socket, [socket_s socket]) dnl BIND library may be needed, need to force this first if test -z "$no_resolv_lib"; then AC_CHECK_FUNC(inet_ntop,name2=yes) if test -z "$name2" ; then AC_CHECK_LIB(resolv, inet_ntop, [LIBS="$LIBS -lresolv";name2=yes]) fi; fi dnl ---------------------------------------------------------------------------- dnl function checks: dnl BSDs have this: AC_CHECK_LIB(util, setproctitle, [LIBS="-lutil $LIBS"]) AC_CHECK_FUNCS(_res cfsetispeed fcntl flock gethostbyname2 getdtablesize gethostname getrlimit inet_aton inet_ntop inet_pton innetgr initgroups killpg lockf mkstemp mktemp openlog putenv random rand setenv seteuid setgroups setlocale setpgid setproctitle setresuid setreuid setruid setsid sigaction sigprocmask siglongjmp socketpair strcasecmp strchr strdup strerror strncasecmp sysconf sysinfo tcdrain tcflush tcsetattr uname unsetenv wait3 waitpid) if test ! "$ac_cv_func_setreuid" = yes -a ! "$ac_cv_func_seteuid" = yes -a ! "$ac_cv_func_setresuid" = yes; then AC_MSG_WARN([missing setreuid(), seteuid(), and setresuid()]) fi AC_FUNC_VFORK AC_FUNC_VPRINTF dnl ---------------------------------------------------------------------------- dnl special system checks AC_CACHE_CHECK(how to manipulate tty attributes, ac_cv_struct_term, [ if test "$ac_cv_header_termios_h" = yes; then ac_cv_struct_term=termios fi if test "$ac_cv_header_sys_termios_h" = yes; then ac_cv_struct_term=termios fi dnl test to see if we need to compile if test -z "$ac_cv_struct_term" ; then AC_TRY_COMPILE([ #ifdef HAVE_TERMIO_H #include #endif #ifdef HAVE_SYS_TERMIO_H #include #endif],[struct termio t;t.c_iflag = 0], ac_cv_struct_term=termio) fi dnl now you have determined if you have termio if test -z "$ac_cv_struct_term" ; then AC_TRY_COMPILE([#include ],[ struct sgttyb s;s.sg_flags = 0], ac_cv_struct_term=sgttyb) fi if test -z "$ac_cv_struct_term" ; then ac_cv_struct_term=UNDEFINED fi ]) if test "$ac_cv_struct_term" = "sgttyb"; then AC_DEFINE(USE_SGTTYB,1,[use sgttyb]) AC_DEFINE(USE_STTY,SGTTYB,[use sgttyb]) fi if test "$ac_cv_struct_term" = "termio"; then AC_DEFINE(USE_TERMIO,1,[use termio]) AC_DEFINE(USE_STTY,TERMIO,[use termio]) fi if test "$ac_cv_struct_term" = "termios"; then AC_DEFINE(USE_TERMIOS,1,[use termios]) AC_DEFINE(USE_STTY,TERMIOS,[use termios]) if test "$ac_cv_header_sys_termiox_h" = yes; then AC_DEFINE(USE_TERMIOX,1,[use termiox]) fi fi dnl ---------------------------------------------------------------------------- dnl test to see if lseek has a prototype - you make it get an error AC_CACHE_CHECK(checking for lseek prototype, ac_cv_lseek_proto, [ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_UNISTD_H #include #endif ],[off_t x; x = lseek(0,"test",SEEK_SET);], ac_cv_lseek_proto=no, ac_cv_lseek_proto=yes) ]) if test "$ac_cv_lseek_proto" = yes; then AC_DEFINE(HAVE_LSEEK_PROTO,1,[have lseek definition]) fi dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(how to get filesystem free space, ac_cv_struct_fstype, [ fstype= dnl do this check if statvfs is a valid function if test "$ac_cv_func_statvfs" != no ; then #{ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_VFS_H # include #endif],[struct statvfs s; statvfs ("/", &s); return(s.f_bavail+s.f_bsize)], fstype=statvfs) fi #} dnl do these checks if statfs is a valid function if test "$ac_cv_func_statfs" != no ; then #{ if test -z "$fstype" ; then #{ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_VFS_H # include #endif],[struct fs_data s; return(s.fd_bfree+s.fd_bsize)], fstype=Ultrix-statfs) fi #} if test -z "$fstype" ; then #{ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif],[struct statfs s; return(s.f_bavail+s.f_bsize)], fstype=statfs) fi # } if test -z "$fstype" ; then # { AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif],[struct statfs s; return(s.f_bfree+s.f_bsize)], fstype=SVR3-statfs) fi # } fi # } if test -z "$fstype" ; then echo "cannot find a valid statfs-like structure!" fstype=UNKNOWN fi ac_cv_struct_fstype=$fstype ]) if test "$ac_cv_struct_fstype" = SVR3-statfs; then AC_DEFINE(USE_STATFS_TYPE,SVR3_STATFS,[svr3 statfs]) fi if test "$ac_cv_struct_fstype" = Ultrix-statfs; then AC_DEFINE(USE_STATFS_TYPE,ULTRIX_STATFS,[ultix statfs]) fi if test "$ac_cv_struct_fstype" = statfs; then AC_DEFINE(USE_STATFS_TYPE,STATFS,[plain statfs]) fi if test "$ac_cv_struct_fstype" = statvfs; then AC_DEFINE(USE_STATFS_TYPE,STATVFS,[statvfs statfs]) fi dnl ---------------------------------------------------------------------------- dnl AC_CACHE_CHECK(for setproctitle declaration, ac_cv_decl_setproctitle_def, [AC_TRY_COMPILE([ #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif ],[setproctitle(0);], ac_cv_decl_setproctitle_def=no, ac_cv_decl_setproctitle_def=yes) ]) if test "$ac_cv_decl_setproctitle_def" = yes; then AC_DEFINE(HAVE_SETPROCTITLE_DEF,1,[setproctitle defined]) fi dnl ---------------------------------------------------------------------------- dnl sys_siglist array (list of signals) AC_CACHE_CHECK(for sys_siglist array, ac_cv_sys_siglist, [AC_TRY_LINK([ #include ], [extern int sys_siglist; printf("%d",sys_siglist);], ac_cv_sys_siglist=yes, ac_cv_sys_siglist=no) ]) if test "$ac_cv_sys_siglist" = yes; then AC_DEFINE(HAVE_SYS_SIGLIST,1,[have sys_syslist]) AC_CACHE_CHECK(for sys_siglist declaration, ac_cv_decl_sys_siglist_def, [AC_TRY_COMPILE([ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SIGNAL_H #include #endif #include ], [printf("%s",sys_siglist[0]);], ac_cv_decl_sys_siglist_def=yes, ac_cv_decl_sys_siglist_def=no) ]) if test "$ac_cv_decl_sys_siglist_def" = yes; then AC_DEFINE(HAVE_SYS_SIGLIST_DEF,1,[sys_siglist defined]) ac_cv_sys_siglist=yes fi else AC_CACHE_CHECK(for _sys_siglist array, ac_cv__sys_siglist, [AC_TRY_LINK([ #include ], [extern int _sys_siglist; printf("%d",_sys_siglist);], ac_cv__sys_siglist=yes, ac_cv__sys_siglist=no) ]) if test "$ac_cv__sys_siglist" = yes; then AC_DEFINE(HAVE__SYS_SIGLIST,1,[have _sys_siglist]) AC_CACHE_CHECK(for _sys_siglist declaration, ac_cv_decl__sys_siglist_def, [AC_TRY_COMPILE([ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SIGNAL_H #include #endif #include ], [printf("%s",_sys_siglist[0]);], ac_cv_decl__sys_siglist_def=yes, ac_cv_decl__sys_siglist_def=no) ]) if test "$ac_cv_decl__sys_siglist_def" = yes; then AC_DEFINE(HAVE__SYS_SIGLIST_DEF,1,[_sys_siglist defined]) ac_cv__sys_siglist=yes fi fi fi dnl ---------------------------------------------------------------------------- dnl just for (really) backwards compatibility dnl we really try not to use union wait -- it's heinously unportable. dnl nicked this check from Tcl as well. ; dnl dnl The check below checks whether defines the type dnl "union wait" correctly. It's needed because of weirdness in dnl HP-UX where "union wait" is defined in both the BSD and SYS-V dnl environments. Checking the usability of WIFEXITED seems to do dnl the trick. AC_CACHE_CHECK(for obsolete union wait compatibility, ac_cv_unionwait, [ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include ], [union wait x;WIFEXITED(x);], ac_cv_unionwait=yes, ac_cv_unionwait=no) ]) if test "$ac_cv_unionwait" = yes; then AC_DEFINE(HAVE_UNION_WAIT,1,[have union wait]) fi dnl ---------------------------------------------------------------------------- dnl Would you believe the gethostname declarations are broken on some machines dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for gethostname declaration, ac_cv_decl_gethostname_def, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif],[gethostname(1);], ac_cv_decl_gethostname_def=no, ac_cv_decl_gethostname_def=yes) ]) if test "$ac_cv_decl_gethostname_def" = yes; then AC_DEFINE(HAVE_GETHOSTNAME_DEF,1,[have gethostname definition]) fi dnl ---------------------------------------------------------------------------- dnl innetgr() declarations missing dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for innetgr declaration, ac_cv_decl_innetgr_def, [ AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_NETDB_H #include #endif],[printf("%d", innetgr(1));], ac_cv_decl_innetgr_def=no, ac_cv_decl_innetgr_def=yes ) ] ) if test "$ac_cv_decl_innetgr_def" = yes; then AC_DEFINE(HAVE_INNETGR_DEF,1,[use innetgr(1)]) fi dnl ---------------------------------------------------------------------------- dnl openlog() declarations missing dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for openlog declaration, ac_cv_decl_openlog_def, [AC_TRY_COMPILE([ #include #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDARG_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif],[printf("%d",openlog);], ac_cv_decl_openlog_def=yes, ac_cv_decl_openlog_def=no) ]) if test "$ac_cv_decl_openlog_def" = yes; then AC_DEFINE(HAVE_OPENLOG_DEF,1,[have openlog definition]) fi dnl ---------------------------------------------------------------------------- dnl syslog() declarations missing dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for syslog declaration, ac_cv_decl_syslog_def, [AC_TRY_COMPILE([ #include #ifdef HAVE_STDARG_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif],[printf("%d",syslog);], ac_cv_decl_syslog_def=yes, ac_cv_decl_syslog_def=no) ]) if test "$ac_cv_decl_syslog_def" = yes; then AC_DEFINE(HAVE_SYSLOG_DEF,1,[have syslog definition]) fi dnl ---------------------------------------------------------------------------- dnl IPV6 - check for structure declarations dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for struct in6_addr declaration, ac_cv_decl_in6_addr_def, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #include ],[struct in6_addr v;], ac_cv_decl_in6_addr_def=yes, ac_cv_decl_in6_addr_def=no) ]) if test "$ac_cv_decl_in6_addr_def" = yes; then AC_DEFINE(IN6_ADDR,1,[in6_addr defined]) AC_DEFINE(IPV6,1,[ipV6]) fi AC_CACHE_CHECK([for struct in_addr6 declaration (LINUX)], ac_cv_decl_in_addr6_def, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #include #include ],[struct in_addr6 v;], ac_cv_decl_in_addr6_def=yes, ac_cv_decl_in_addr6_def=no) ]) if test "$ac_cv_decl_in_addr6_def" = yes; then AC_DEFINE(IN_ADDR6,1,[in_addr6 defined]) AC_DEFINE(IPV6,1,[ipV6]) fi dnl ---------------------------------------------------------------------------- dnl struct stat can have a st_mtime_nsec field dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for struct stat has st_mtimespec.tv_nsec, ac_cv_decl_st_mtimespec_tv_nsec, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #ifdef HAVE_SYS_TIME_H #include #endif #include ],[struct stat statb; statb.st_mtimespec.tv_nsec;], ac_cv_decl_st_mtimespec_tv_nsec=yes, ac_cv_decl_st_mtimespec_tv_nsec=no) ]) if test "$ac_cv_decl_st_mtimespec_tv_nsec" = yes; then AC_DEFINE_UNQUOTED(ST_MTIMESPEC_TV_NSEC,1,[stat st_mtimespec.tv_nsec present]) fi AC_CACHE_CHECK(for struct stat has st_mtimensec, ac_cv_decl_st_mtimensec, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #include #if defined(HAVE_SYS_TIME_H) #include #endif #include ],[struct stat statb; statb.st_mtimensec;], ac_cv_decl_st_mtimensec=yes, ac_cv_decl_st_mtimensec=no) ]) if test "$ac_cv_decl_st_mtimensec" = yes; then AC_DEFINE_UNQUOTED(ST_MTIMENSEC,1,[struct st_mtimensec present]) fi dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for strcasecmp definition, ac_cv_decl_strcasecmp, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #if defined(HAVE_STDLIB_H) #include #endif #if defined(HAVE_STRING_H) #include #endif #if defined(HAVE_STRINGS_H) #include #endif ],[strcasecmp(1)], ac_cv_decl_strcasecmp=no, ac_cv_decl_strcasecmp=yes) ]) if test "$ac_cv_decl_strcasecmp" = yes; then AC_DEFINE_UNQUOTED(HAVE_STRCASECMP_DEF,1,[have strcasecmp definition]) fi dnl ---------------------------------------------------------------------------- AC_CACHE_CHECK(for flock definition, ac_cv_decl_flock, [AC_TRY_COMPILE([ #ifdef HAVE_CTYPES_H #include #endif #if defined(HAVE_STDLIB_H) #include #endif #if defined(HAVE_SYS_FILE_H) #include #endif #if defined(HAVE_FCNTL_H) #include #endif ],[flock(1)], ac_cv_decl_flock=no, ac_cv_decl_flock=yes) ]) if test "$ac_cv_decl_flock" = yes; then AC_DEFINE_UNQUOTED(HAVE_FLOCK_DEF,1,[have flock definition]) fi dnl ---------------------------------------------------------------------------- AC_PROG_INSTALL AC_CHECK_PROG(INSTALL_MAN,auxman,auxman,[$INSTALL -m 644]) AC_PROG_MAKE_SET dnl ----------------- force this to be Bourne Shell for now --------------- AC_MSG_CHECKING(for shell) SHELL=/bin/sh AC_MSG_RESULT(using $SHELL (FORCED)) MY_GETTEXT dnl ---------------------------------------------------------------------------- dnl ----------------- END OF GENERAL CONFIGURATION --------------------------- dnl check to see if tcp wrappers required AC_MSG_CHECKING(use tcp wrappers) AC_ARG_ENABLE( tcpwrappers, AS_HELP_STRING([--enable-tcpwrappers],[use tcp wrappers (-lwrap)]), [ if test "$enableval" = "yes" ; then v=yes AC_CHECK_HEADERS(tcpd.h, [AC_DEFINE(HAVE_TCPD_H,1,[have tcpd])], [AC_MSG_ERROR(tcpd.h not found); v=no; ] ) AC_CHECK_LIB(wrap, request_init, [LIBS="-lwrap $LIBS"], [AC_MSG_ERROR(request_init not found in -wrap library); v=no; ] ) else v=no; fi ], [ v=no; ] ) if test "$v" = "yes" ; then AC_DEFINE(TCPWRAPPERS,1,[tcpwrappers]) fi AC_MSG_RESULT($v);dnl dnl check to see if ssl is disabled AC_MSG_CHECKING(if ssl authentication is disabled) AC_ARG_ENABLE( ssl, AS_HELP_STRING([--disable-ssl],[disable ssl support]), [ if test "$enableval" = "yes" ; then v=enabled; SSL_ENABLE=1; else v=disabled; SSL_ENABLE=; fi ], [ v=enabled; SSL_ENABLE=1; ], ) AC_MSG_RESULT($v);dnl dnl This does far too much by hand, try to just check for dnl the headers and libs... dnl Now look for OpenSSL ac_openssl_lib_dir= ac_openssl_inc_dir= if test "$SSL_ENABLE" != ""; then dnl See if we can find OpenSSL dnl We can compile without OpenSSL if we have to ac_openssl_lib_dir="/usr/lib /usr/local /usr/local/ssl /usr/local/ssl/lib /usr/pkg" ac_openssl_inc_dir="/usr/include /usr/local /usr/local/ssl /usr/pkg /usr/local/ssl/include" AC_ARG_WITH(openssl, AS_HELP_STRING([--with-openssl=DIR],[root location for OpenSSL]), [ ac_openssl_lib_dir="$withval/lib $withval" ac_openssl_inc_dir="$withval/include $withval" ] ) AC_ARG_WITH(openssl-inc, AS_HELP_STRING([--with-openssl-inc],[OpenSSL include files]), ac_openssl_inc_dir=$withval ) AC_ARG_WITH(openssl-lib, AS_HELP_STRING([--with-openssl-lib],[OpenSSL library files]), ac_openssl_lib_dir=$withval ) ac_found_openssl_inc_dir="no" AC_MSG_CHECKING(for OpenSSL include files) for dir in $ac_openssl_inc_dir; do if test -f $dir/openssl/ssl.h; then ac_found_openssl_inc_dir=$dir break fi done if test "$ac_found_openssl_inc_dir" != "no"; then echo "found in $ac_found_openssl_inc_dir" else echo "not found." SSL_ENABLE="" fi fi SSL_LDADD="" if test "$SSL_ENABLE" != ""; then ac_found_openssl_lib_dir="no" AC_MSG_CHECKING(for OpenSSL libraries) for dir in $ac_openssl_lib_dir; do found_ssl="false" if test -f $dir/libssl.a -a -f $dir/libcrypto.a; then found_ssl="true" fi if test -f $dir/libssl.so -a -f $dir/libcrypto.so; then found_ssl="true" fi if $found_ssl != "false"; then dnl Ok, we think we've found them, but check that they dnl actually ontain the right functions save_LIBS=$LIBS save_LDFLAGS=$LDFLAGS SSL_LDADD="-lssl -lcrypto" if test "X$dir" != "X/usr/lib" ; then SSL_LDADD="-L$dir $SSL_LDADD" fi LDFLAGS="$LDFLAGS $SSL_LDADD" AC_TRY_LINK_FUNC(SSL_load_error_strings,ac_linked_libssl="true", ac_linked_libssl="false"); AC_TRY_LINK_FUNC(RC4_set_key,ac_linked_libcrypto="true", ac_linked_libcrypto="false"); if test "$ac_linked_libssl" != "false" -a \ "$ac_linked_libcrypto" != "false"; then ac_found_openssl_lib_dir=$dir LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS break fi LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS SSL_LDADD="" fi done if test "$ac_found_openssl_lib_dir" != "no"; then echo "found in $ac_found_openssl_lib_dir" if test "X$ac_found_openssl_inc_dir" != "X/usr/include" ; then CPPFLAGS="$CPPFLAGS -I$ac_found_openssl_inc_dir " ; fi else echo "not found." SSL_ENABLE="" fi fi AC_SUBST(SSL_LDADD) AM_CONDITIONAL(WITHSSL, test "$SSL_ENABLE" != "") test "$SSL_ENABLE" != "" && AC_DEFINE(SSL_ENABLE,1,[ssl enabled]) dnl ssl certificate authority CERT file dnl AC_MSG_CHECKING(ssl Certificate Authority CERT file) AC_ARG_WITH(ssl_ca_file, AS_HELP_STRING([--with-ssl_ca_file=FILE],[ssl Certificate Authority CERT file (default ${configdir}/ssl.ca/ca.crt)]), SSL_CA_FILE=$withval, SSL_CA_FILE=\${configdir}/ssl.ca/ca.crt, ) AC_MSG_RESULT($SSL_CA_FILE) AC_SUBST(SSL_CA_FILE) dnl ssl certificate authority private key file dnl AC_MSG_CHECKING(ssl Certificate Authority private key file) AC_ARG_WITH(ssl_ca_key, AS_HELP_STRING([--with-ssl_ca_key=KEY],[ssl Certificate Authority private key file (default ${configdir}/ssl.ca/ca.key)]), SSL_CA_KEY=$withval, SSL_CA_KEY=\${configdir}/ssl.ca/ca.key, ) AC_MSG_RESULT($SSL_CA_KEY) AC_SUBST(SSL_CA_KEY) dnl ssl certificate authority certs working directory dnl AC_MSG_CHECKING(ssl Certificate Authority certs working directory) AC_ARG_WITH(ssl_certs_dir, AS_HELP_STRING([--with-ssl_certs_dir=DIR],[ssl Certificate Authority certs working directory (default ${configdir}/ssl.certs/)]), SSL_CERTS_DIR=$withval, SSL_CERTS_DIR=\${configdir}/ssl.certs, ) AC_MSG_RESULT($SSL_CERTS_DIR) AC_SUBST(SSL_CERTS_DIR) dnl ssl certificate revocation list dnl AC_MSG_CHECKING(ssl Certificate Revocation List (CRL) file) AC_ARG_WITH(ssl_crl_file, AS_HELP_STRING([--with-ssl_crl_file=PATH],[ssl Certificate Revocation List File (default ${configdir}/ssl.crl/ssl.crl)]), SSL_CRL_FILE=$withval, SSL_CRL_FILE=\${configdir}/ssl.crl/ssl.crl, ) AC_MSG_RESULT($SSL_CRL_FILE) AC_SUBST(SSL_CRL_FILE) dnl ssl server certificate file dnl AC_MSG_CHECKING(ssl server certificate file) AC_ARG_WITH(ssl_server_cert, AS_HELP_STRING([--with-ssl_server_cert=FILE],[ssl server certificate file (default ${configdir}/ssl.server/server.crt)]), SSL_SERVER_CERT=$withval, SSL_SERVER_CERT=\${configdir}/ssl.server/server.crt, ) AC_MSG_RESULT($SSL_SERVER_CERT) AC_SUBST(SSL_SERVER_CERT) dnl ssl server password file for private key file dnl AC_MSG_CHECKING(ssl server password file for private key file) AC_ARG_WITH(ssl_server_password_file, AS_HELP_STRING([--with-ssl_server_password_file=FILE],[ssl server private key in password file (default ${configdir}/ssl.server/server.pwd)]), SSL_SERVER_PASSWORD_FILE=$withval, SSL_SERVER_PASSWORD_FILE=\${configdir}/ssl.server/server.pwd, ) AC_MSG_RESULT($SSL_SERVER_PASSWORD_FILE) AC_SUBST(SSL_SERVER_PASSWORD_FILE) dnl ---------------------------------------------------------------------------- dnl ---------------- START OF KERBEROS ----------------------------------------- dnl Kerberos stuff again KRB_LIBS="" SAVELIBS="$LIBS" if test -n "$KERBEROS" ; then echo "Kerberos checks with CFLAGS '$CFLAGS', CPPFLAGS '$CPPFLAGS', LDFLAGS '$LDFLAGS" if test -d /usr/kerberos/include; then CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" fi if test -d /usr/kerberos/lib; then LDFLAGS="-L/usr/kerberos/lib $LDFLAGS" fi dnl Kerberos 5 - release 1.1.1 found= AC_CHECK_HEADERS(krb5.h,found=yes) if test "$found" != "yes" ; then AC_MSG_ERROR([ Kerberos 5 support wanted and cannot find krb5.h include file use configure --disable-kerberos-checks or check your Kerberos 5 installation If you have installed kerberos in /usr/local/{lib,include} then use configure --enable-kerberos CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ]) fi if test "$KERBEROS_CHECKS" = 1 ; then dnl we have the Kerberos 5 package, lets try for the rest AC_TRY_COMPILE([ #include #include ], [printf("%d",sizeof(HostAddress));], heimdal=yes, heimdal=no) if test $heimdal = yes; then AC_MSG_WARN(compiling with CFLAGS $CFLAGS, CPPFLAGS $CPPFLAGS) AC_MSG_ERROR(You appear to be using the Heimdal Kerberos krb5.h file. You must use MIT Kerberos with LPRng) fi dnl we check for the library we need to use dnl courtesy of mandrake linux and friends. dnl Christian Zoffoli found=no if test "$found" "!=" "yes" ; then found=yes KRB_LIBS="-lkrb5 -lk5crypto -lcom_err" LIBS=" $KRB_LIBS $SAVELIBS" AC_CHECKING(for krb5_init_context in $LIBS ) AC_TRY_LINK_FUNC(krb5_init_context,,found="no") AC_CHECKING(for krb5_encrypt_size in $LIBS ) AC_TRY_LINK_FUNC(krb5_encrypt_size,,found="no") fi; if test "$found" "!=" "yes" ; then found=yes KRB_LIBS="-lkrb5 -lcrypto -lcom_err" LIBS=" $KRB_LIBS $SAVELIBS" AC_CHECKING(for krb5_init_context in $LIBS ) AC_TRY_LINK_FUNC(krb5_init_context,,found="no") AC_CHECKING(for krb5_encrypt_size in $LIBS ) AC_TRY_LINK_FUNC(krb5_encrypt_size,,found="no") fi; if test "$found" "!=" "yes" ; then AC_PATH_PROG(KRB5CONFIG, krb5-config) found=yes KRB_LIBS="$($KRB5CONFIG --libs krb5)" LIBS=" $KRB_LIBS $SAVELIBS" AC_CHECKING(for krb5_init_context in $LIBS ) AC_TRY_LINK_FUNC(krb5_init_context,,found="no") AC_CHECKING(for krb5_encrypt_size in $LIBS ) AC_TRY_LINK_FUNC(krb5_encrypt_size,,found="no") fi; if test "$found" "!=" "yes" ; then AC_MSG_WARN(Kerberos 5 library does not have krb5_init_context and krb5_encrypt_size or ) AC_MSG_WARN(use configure --disable-kerberos or check your Kerberos 5 installation) exit 1 fi AC_MSG_RESULT(found in $LIBS) AC_CHECK_FUNC(krb5_read_message,AC_DEFINE_UNQUOTED(HAVE_KRB5_READ_MESSAGE,1,[have krb5_read_message]),[AC_MSG_WARN(Kerberos 5 library does not have krb5_read_message)]) fi AC_CHECK_FUNCS(krb5_free_data_contents) AC_CACHE_CHECK(for krb5_xfree, ac_cv_krb5_xfree, [AC_TRY_LINK([ # define KRB5_DEPRECATED 1 #if defined(HAVE_KRB5_H) #include #endif ],[krb5_xfree((void *)0);], ac_cv_krb5_xfree=yes, ac_cv_krb5_xfree=no) ]) if test "$ac_cv_krb5_xfree" = yes; then AC_DEFINE_UNQUOTED(HAVE_KRB5_XFREE,1,[have krb5_xfree]) fi AC_CACHE_CHECK(for krb_xfree, ac_cv_krb_xfree, [AC_TRY_LINK([ # define KRB5_DEPRECATED 1 #if defined(HAVE_KRB5_H) #include #endif ],[krb_xfree((void *)0);], ac_cv_krb_xfree=yes, ac_cv_krb_xfree=no) ]) if test "$ac_cv_krb_xfree" = yes; then AC_DEFINE_UNQUOTED(HAVE_KRB_XFREE,1,[have krb_xfree]) fi LIBS="$SAVELIBS" fi; AC_SUBST(KRB_LIBS) dnl ---------------------------------------------------------------------------- dnl ---------------- END OF KERBEROS ----------------------------------------- CHECK_PLUGINS dnl ---------------------------------------------------------------------------- dnl ----------------- START OF OUTPUT ------------------------------------------ AC_OUTPUT( [ Makefile UTILS/LPRng.pm UTILS/Makefile UTILS/accounting.pl UTILS/decode_args_with_perl UTILS/decode_args_with_sh UTILS/fixid UTILS/fixupdate UTILS/lpq_in_perl UTILS/lpr_in_perl UTILS/lprm_in_perl UTILS/make_lpd_conf UTILS/make_printcap_use UTILS/makeinc UTILS/read_conf UTILS/remote_active UTILS/test_read UTILS/update_z.pl man/Makefile src/Makefile src/pclbanner src/psbanner po/Makefile conf/Makefile conf/lpd.perms ], [ for i in \ UTILS/LPRng.pm \ UTILS/accounting.pl \ UTILS/decode_args_with_perl \ UTILS/decode_args_with_sh \ UTILS/fixid \ UTILS/fixupdate \ UTILS/lpq_in_perl \ UTILS/lpr_in_perl \ UTILS/lprm_in_perl \ UTILS/make_lpd_conf \ UTILS/make_printcap_use \ UTILS/makeinc \ UTILS/read_conf \ UTILS/remote_active \ UTILS/test_read \ UTILS/update_z.pl \ ; do chmod +x $i ; done ] ) dnl ---------------------------------------------------------------------------- dnl ----------------- END OF OUTPUT -------------------------------------------- lprng-3.8.B/configure0000755000131400013140000130234711531672270011524 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for LPRng 3.8.B. # # Report bugs to . # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='LPRng' PACKAGE_TARNAME='lprng' PACKAGE_VERSION='3.8.B' PACKAGE_STRING='LPRng 3.8.B' PACKAGE_BUGREPORT='lprng-devel@lists.sf.net' ac_unique_file="src/common/lpr.c" ac_default_prefix=/usr/local # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA am__isrc CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE SED PERL CHOWN CHGRP PRUTIL OPENSSL PRIV_PORTS LPD_LISTEN_PORT NOREMOTE INCLUDELPDCONFLOCAL WITHKERBEROS_TRUE WITHKERBEROS_FALSE KERBEROS lpdbindir configdir LPD_CONF_PATH LPD_PERMS_PATH PRINTCAP_PATH LPD_PRINTCAP_PATH UNIXSOCKETPATH LOCKFILE SD_DEFAULT plugindir filterdir FILTER_LD_PATH FILTER_PATH CLEAR CPP GREP EGREP INSTALL_MAN USE_NLS MSGFMT GMSGFMT XGETTEXT MSGMERGE SSL_LDADD WITHSSL_TRUE WITHSSL_FALSE SSL_CA_FILE SSL_CA_KEY SSL_CERTS_DIR SSL_CRL_FILE SSL_SERVER_CERT SSL_SERVER_PASSWORD_FILE KRB5CONFIG KRB_LIBS PLUGIN_LDFLAGS PLUGIN_CFLAGS PLUGINUSER_LDFLAGS WITHPLUGINS_TRUE WITHPLUGINS_FALSE DL_LIBS LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP PLUGIN_LDFLAGS PLUGIN_CFLAGS PLUGINUSER_LDFLAGS' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures LPRng 3.8.B to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/lprng] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of LPRng 3.8.B:";; esac cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --disable-largefile omit support for large files --enable-priv_ports require connections from privileged ports --disable-remote do not accept remote jobs by default --enable-lpd.conf.local include lpd.conf.local in lpd.conf --disable-force_localhost disable force_localhost default --disable-require_configfiles client programs require lpd.conf, printcap --enable-kerberos enable kerberos support --disable-kerberos_checks disable kerberos library location and checking for support --enable-nls use Native Language Support --enable-tcpwrappers use tcp wrappers (-lwrap) --disable-ssl disable ssl support --enable-plugins build authentication modules as plugins Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-lpddir=DIR lpd executable directory (default ${sbindir}) --with-config_subdir=SUBDIR configuration subdirectory (default 'lpd') --with-lpd_conf_path=PATH path of lpd.conf (default: ${configdir}/lpd.conf) --with-lpd_perms_path=PATH path of lpd.perms (default: ${configdir}/lpd.perms) --with-printcap_path=PATH path of printcap (default ${sysconfdir}/printcap) --with-lpd_printcap_path=PATH path of lpd_printcap (default ${configdir}/lpd_printcap) --with-localedir=PATH specify locale information directory --with-unix_socket_path=DIR unix socket path (default /var/run/lprng) --with-lockfile=PATH lockfile PATH, default /var/run/lpd --with-spooldir=PATH default spool directory, default /var/spool/lpd --with-plugindir=DIR dynamic loadable plugin directory (default ${libdir}/lprng/plugins) --with-filterdir=DIR filter directory (default ${libexecdir}/filters) --with-ld_library_path=PATH FILTER_LD_PATH value, default empty (for Solaris you might need /lib:/usr/lib:/usr/local/lib) --with-filter-path=PATH filter PATH value, default /bin:/usr/bin:/usr/local/bin --with-userid=NAME run LPRng software as this userid, default daemon --with-groupid=NAME run LPRng software as this groupid, default daemon --with-done_jobs=N retain last N job status, default 1 --with-done_jobs_max_age=N retain job status N seconds, default 0 - no expiry --with-openssl=DIR root location for OpenSSL --with-openssl-inc OpenSSL include files --with-openssl-lib OpenSSL library files --with-ssl_ca_file=FILE ssl Certificate Authority CERT file (default ${configdir}/ssl.ca/ca.crt) --with-ssl_ca_key=KEY ssl Certificate Authority private key file (default ${configdir}/ssl.ca/ca.key) --with-ssl_certs_dir=DIR ssl Certificate Authority certs working directory (default ${configdir}/ssl.certs/) --with-ssl_crl_file=PATH ssl Certificate Revocation List File (default ${configdir}/ssl.crl/ssl.crl) --with-ssl_server_cert=FILE ssl server certificate file (default ${configdir}/ssl.server/server.crt) --with-ssl_server_password_file=FILE ssl server private key in password file (default ${configdir}/ssl.server/server.pwd) Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor PLUGIN_LDFLAGS Additional LDFLAGS for plugins (default --shared) PLUGIN_CFLAGS Additional CFLAGS for plugins (default -fPIC) PLUGINUSER_LDFLAGS Additional LDFLAGS for a program loading plugins (default -export-dynamic) Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF LPRng configure 3.8.B generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by LPRng $as_me 3.8.B, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers config.h" am__api_version='1.10' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { echo "$as_me:$LINENO: checking whether build environment is sane" >&5 echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&5 echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken alias in your environment" >&2;} { (exit 1); exit 1; }; } fi test "$2" = conftest.file ) then # Ok. : else { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! Check your system clock" >&5 echo "$as_me: error: newly created file is older than distributed files! Check your system clock" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. echo might interpret backslashes. # By default was `s,x,x', remove it if useless. cat <<\_ACEOF >conftest.sed s/[\\$]/&&/g;s/;s,x,x,$// _ACEOF program_transform_name=`echo $program_transform_name | sed -f conftest.sed` rm -f conftest.sed # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi { echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 echo $ECHO_N "checking for a thread-safe mkdir -p... $ECHO_C" >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. test -d ./--version && rmdir ./--version MKDIR_P="$ac_install_sh -d" fi fi { echo "$as_me:$LINENO: result: $MKDIR_P" >&5 echo "${ECHO_T}$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} { (exit 1); exit 1; }; } fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='lprng' VERSION='3.8.B' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { echo "$as_me:$LINENO: result: $STRIP" >&5 echo "${ECHO_T}$STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 echo "${ECHO_T}$ac_ct_STRIP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' { echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; } # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval else USE_MAINTAINER_MODE=no fi { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; } if test $USE_MAINTAINER_MODE = yes; then MAINTAINER_MODE_TRUE= MAINTAINER_MODE_FALSE='#' else MAINTAINER_MODE_TRUE='#' MAINTAINER_MODE_FALSE= fi MAINT=$MAINTAINER_MODE_TRUE mysaved_CFLAGSset="${CFLAGS+set}" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi { echo "$as_me:$LINENO: result: $_am_result" >&5 echo "${ECHO_T}$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi if test "$ac_cv_c_compiler_gnu" = yes; then if test "$mysaved_CFLAGSset" != set ; then CFLAGS="-g -W -Wall -Wno-unused -Wstrict-prototypes -Wmissing-prototypes" fi fi; # Check whether --enable-largefile was given. if test "${enable_largefile+set}" = set; then enableval=$enable_largefile; fi if test "$enable_largefile" != no; then { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_largefile_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then ac_save_CC=$CC while :; do # IRIX 6.2 and later do not support large files by default, # so use the C compiler's -n32 option if that helps. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext CC="$CC -n32" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_largefile_CC=' -n32'; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext break done CC=$ac_save_CC rm -f conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_file_offset_bits+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=no; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _FILE_OFFSET_BITS 64 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=64; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_file_offset_bits=unknown break done fi { echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits _ACEOF ;; esac rm -f conftest* if test $ac_cv_sys_file_offset_bits = unknown; then { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } if test "${ac_cv_sys_large_files+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=no; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #define _LARGE_FILES 1 #include /* Check that off_t can represent 2**63 - 1 correctly. We can't simply define LARGE_OFF_T to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=1; break else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_sys_large_files=unknown break done fi { echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) cat >>confdefs.h <<_ACEOF #define _LARGE_FILES $ac_cv_sys_large_files _ACEOF ;; esac rm -f conftest* fi fi for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_AWK+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { echo "$as_me:$LINENO: result: $AWK" >&5 echo "${ECHO_T}$AWK" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$AWK" && break done # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_SED+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PERL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { echo "$as_me:$LINENO: result: $PERL" >&5 echo "${ECHO_T}$PERL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "chown", so it can be a program name with args. set dummy chown; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_CHOWN+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $CHOWN in [\\/]* | ?:[\\/]*) ac_cv_path_CHOWN="$CHOWN" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CHOWN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CHOWN=$ac_cv_path_CHOWN if test -n "$CHOWN"; then { echo "$as_me:$LINENO: result: $CHOWN" >&5 echo "${ECHO_T}$CHOWN" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi cat >>confdefs.h <<_ACEOF #define CHOWN "$CHOWN" _ACEOF # Extract the first word of "chgrp", so it can be a program name with args. set dummy chgrp; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_CHGRP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $CHGRP in [\\/]* | ?:[\\/]*) ac_cv_path_CHGRP="$CHGRP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CHGRP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CHGRP=$ac_cv_path_CHGRP if test -n "$CHGRP"; then { echo "$as_me:$LINENO: result: $CHGRP" >&5 echo "${ECHO_T}$CHGRP" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi cat >>confdefs.h <<_ACEOF #define CHGRP "$CHGRP" _ACEOF # Extract the first word of "pr", so it can be a program name with args. set dummy pr; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PRUTIL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PRUTIL in [\\/]* | ?:[\\/]*) ac_cv_path_PRUTIL="$PRUTIL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PRUTIL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PRUTIL=$ac_cv_path_PRUTIL if test -n "$PRUTIL"; then { echo "$as_me:$LINENO: result: $PRUTIL" >&5 echo "${ECHO_T}$PRUTIL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi cat >>confdefs.h <<_ACEOF #define PRUTIL "$PRUTIL" _ACEOF # Extract the first word of "openssl", so it can be a program name with args. set dummy openssl; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_OPENSSL+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $OPENSSL in [\\/]* | ?:[\\/]*) ac_cv_path_OPENSSL="$OPENSSL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi OPENSSL=$ac_cv_path_OPENSSL if test -n "$OPENSSL"; then { echo "$as_me:$LINENO: result: $OPENSSL" >&5 echo "${ECHO_T}$OPENSSL" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi cat >>confdefs.h <<_ACEOF #define OPENSSL "$OPENSSL" _ACEOF # Check whether --enable-priv_ports was given. if test "${enable_priv_ports+set}" = set; then enableval=$enable_priv_ports; v="$enableval" else v="no" fi { echo "$as_me:$LINENO: require connections from priviledged ports: $v" >&5 echo "$as_me: require connections from priviledged ports: $v" >&6;} if test "x$v" = "xyes"; then PRIV_PORTS="" else PRIV_PORTS="#" fi # Check whether --enable-remote was given. if test "${enable_remote+set}" = set; then enableval=$enable_remote; v="$enableval" else v="yes" fi { echo "$as_me:$LINENO: listen for remote connections by default : $v" >&5 echo "$as_me: listen for remote connections by default : $v" >&6;} if test "x$v" = "xyes"; then NOREMOTE="#" LPD_LISTEN_PORT='"=515"' else NOREMOTE="" LPD_LISTEN_PORT='"=off"' fi cat >>confdefs.h <<_ACEOF #define LPD_LISTEN_PORT $LPD_LISTEN_PORT _ACEOF # Check whether --enable-lpd.conf.local was given. if test "${enable_lpd_conf_local+set}" = set; then enableval=$enable_lpd_conf_local; v="$enableval" else v="no" fi { echo "$as_me:$LINENO: include lpd.conf.local in lpd.conf : $v" >&5 echo "$as_me: include lpd.conf.local in lpd.conf : $v" >&6;} if test "x$v" = "xyes"; then INCLUDELPDCONFLOCAL="" else INCLUDELPDCONFLOCAL="# " fi # Check whether --enable-force_localhost was given. if test "${enable_force_localhost+set}" = set; then enableval=$enable_force_localhost; v="$enableval" else v="yes" fi { echo "$as_me:$LINENO: force_localhost is default : $v" >&5 echo "$as_me: force_localhost is default : $v" >&6;} if test "x$v" = "xyes"; then FORCE_LOCALHOST=1 else FORCE_LOCALHOST=0 fi cat >>confdefs.h <<_ACEOF #define FORCE_LOCALHOST "$FORCE_LOCALHOST" _ACEOF # Check whether --enable-require_configfiles was given. if test "${enable_require_configfiles+set}" = set; then enableval=$enable_require_configfiles; v="$enableval" else v="yes" fi { echo "$as_me:$LINENO: client programs require lpd.conf, printcap: $v" >&5 echo "$as_me: client programs require lpd.conf, printcap: $v" >&6;} if test "x$v" = "xyes"; then REQUIRE_CONFIGFILES=1 else REQUIRE_CONFIGFILES=0 fi cat >>confdefs.h <<_ACEOF #define REQUIRE_CONFIGFILES "$REQUIRE_CONFIGFILES" _ACEOF # Check whether --enable-kerberos was given. if test "${enable_kerberos+set}" = set; then enableval=$enable_kerberos; v="$enableval" else v="no" fi { echo "$as_me:$LINENO: enable kerberos support : $v" >&5 echo "$as_me: enable kerberos support : $v" >&6;} if test "x$v" = "xyes"; then KERBEROS=1; cat >>confdefs.h <<_ACEOF #define KERBEROS "1" _ACEOF else KERBEROS="" fi if test $v = yes; then WITHKERBEROS_TRUE= WITHKERBEROS_FALSE='#' else WITHKERBEROS_TRUE='#' WITHKERBEROS_FALSE= fi # Check whether --enable-kerberos_checks was given. if test "${enable_kerberos_checks+set}" = set; then enableval=$enable_kerberos_checks; v="$enableval" else v="yes" fi { echo "$as_me:$LINENO: locate Kerberos libraries and check : $v" >&5 echo "$as_me: locate Kerberos libraries and check : $v" >&6;} if test "x$v" = "xyes"; then KERBEROS_CHECKS=1 else KERBEROS_CHECKS="" fi # Check whether --with-lpddir was given. if test "${with_lpddir+set}" = set; then withval=$with_lpddir; lpdbindir="$withval" else lpdbindir='${sbindir}' fi { echo "$as_me:$LINENO: directory to place lpd executable into : $lpdbindir" >&5 echo "$as_me: directory to place lpd executable into : $lpdbindir" >&6;} # Check whether --with-config_subdir was given. if test "${with_config_subdir+set}" = set; then withval=$with_config_subdir; CONFIGSUBDIR=$withval else CONFIGSUBDIR=lpd fi configdir=\${sysconfdir}/${CONFIGSUBDIR} { echo "$as_me:$LINENO: configuration directory configdir= $configdir" >&5 echo "$as_me: configuration directory configdir= $configdir" >&6;} # Check whether --with-lpd_conf_path was given. if test "${with_lpd_conf_path+set}" = set; then withval=$with_lpd_conf_path; LPD_CONF_PATH="$withval" else LPD_CONF_PATH='${configdir}/lpd.conf' fi { echo "$as_me:$LINENO: lpd.conf location : $LPD_CONF_PATH" >&5 echo "$as_me: lpd.conf location : $LPD_CONF_PATH" >&6;} # Check whether --with-lpd_perms_path was given. if test "${with_lpd_perms_path+set}" = set; then withval=$with_lpd_perms_path; LPD_PERMS_PATH="$withval" else LPD_PERMS_PATH='${configdir}/lpd.perms' fi { echo "$as_me:$LINENO: lpd.perms location : $LPD_PERMS_PATH" >&5 echo "$as_me: lpd.perms location : $LPD_PERMS_PATH" >&6;} # Check whether --with-printcap_path was given. if test "${with_printcap_path+set}" = set; then withval=$with_printcap_path; PRINTCAP_PATH="$withval" else PRINTCAP_PATH='${sysconfdir}/printcap' fi { echo "$as_me:$LINENO: printcap location : $PRINTCAP_PATH" >&5 echo "$as_me: printcap location : $PRINTCAP_PATH" >&6;} # Check whether --with-lpd_printcap_path was given. if test "${with_lpd_printcap_path+set}" = set; then withval=$with_lpd_printcap_path; LPD_PRINTCAP_PATH="$withval" else LPD_PRINTCAP_PATH='${configdir}/lpd_printcap' fi { echo "$as_me:$LINENO: lpd_printcap location : $LPD_PRINTCAP_PATH" >&5 echo "$as_me: lpd_printcap location : $LPD_PRINTCAP_PATH" >&6;} # Check whether --with-localedir was given. if test "${with_localedir+set}" = set; then withval=$with_localedir; localedir="$withval" else localedir='${datadir}/locale' fi { echo "$as_me:$LINENO: locale information directory is : $localedir" >&5 echo "$as_me: locale information directory is : $localedir" >&6;} # Check whether --with-unix_socket_path was given. if test "${with_unix_socket_path+set}" = set; then withval=$with_unix_socket_path; UNIXSOCKETPATH="$withval" else UNIXSOCKETPATH=/var/run/lprng fi { echo "$as_me:$LINENO: unix socket path is : $UNIXSOCKETPATH" >&5 echo "$as_me: unix socket path is : $UNIXSOCKETPATH" >&6;} # Check whether --with-lockfile was given. if test "${with_lockfile+set}" = set; then withval=$with_lockfile; LOCKFILE="$withval" else LOCKFILE='/var/run/lpd' fi { echo "$as_me:$LINENO: lockfile directory : $LOCKFILE" >&5 echo "$as_me: lockfile directory : $LOCKFILE" >&6;} # Check whether --with-spooldir was given. if test "${with_spooldir+set}" = set; then withval=$with_spooldir; SD_DEFAULT="$withval" else SD_DEFAULT='/var/spool/lpd' fi { echo "$as_me:$LINENO: default spool directory (:sd=SPOOLDIR/%P) : $SD_DEFAULT" >&5 echo "$as_me: default spool directory (:sd=SPOOLDIR/%P) : $SD_DEFAULT" >&6;} # Check whether --with-plugindir was given. if test "${with_plugindir+set}" = set; then withval=$with_plugindir; plugindir="$withval" else plugindir='${libdir}/lprng/plugins' fi { echo "$as_me:$LINENO: plugin directory plugindir = $plugindir" >&5 echo "$as_me: plugin directory plugindir = $plugindir" >&6;} # Check whether --with-filterdir was given. if test "${with_filterdir+set}" = set; then withval=$with_filterdir; filterdir="$withval" else filterdir='${libexecdir}/filters' fi { echo "$as_me:$LINENO: filter directory filterdir = $filterdir" >&5 echo "$as_me: filter directory filterdir = $filterdir" >&6;} # Check whether --with-ld_library_path was given. if test "${with_ld_library_path+set}" = set; then withval=$with_ld_library_path; FILTER_LD_PATH="$withval" else FILTER_LD_PATH="" fi { echo "$as_me:$LINENO: filter LD_LIBRARY_PATH: FILTER_LD_PATH = $FILTER_LD_PATH" >&5 echo "$as_me: filter LD_LIBRARY_PATH: FILTER_LD_PATH = $FILTER_LD_PATH" >&6;} cat >>confdefs.h <<_ACEOF #define FILTER_LD_PATH "$FILTER_LD_PATH" _ACEOF # Check whether --with-filter-path was given. if test "${with_filter_path+set}" = set; then withval=$with_filter_path; FILTER_PATH="$withval" else FILTER_PATH="/bin:/usr/bin:/usr/local/bin" fi { echo "$as_me:$LINENO: filter PATH: FILTER_PATH = $FILTER_PATH" >&5 echo "$as_me: filter PATH: FILTER_PATH = $FILTER_PATH" >&6;} cat >>confdefs.h <<_ACEOF #define FILTER_PATH "$FILTER_PATH" _ACEOF # Check whether --with-userid was given. if test "${with_userid+set}" = set; then withval=$with_userid; USERID="$withval" else USERID="daemon" fi { echo "$as_me:$LINENO: userID to run lpd as : $USERID" >&5 echo "$as_me: userID to run lpd as : $USERID" >&6;} cat >>confdefs.h <<_ACEOF #define USERID "$USERID" _ACEOF # Check whether --with-groupid was given. if test "${with_groupid+set}" = set; then withval=$with_groupid; GROUPID="$withval" else GROUPID="daemon" fi { echo "$as_me:$LINENO: groupID to run lpd as : $GROUPID" >&5 echo "$as_me: groupID to run lpd as : $GROUPID" >&6;} cat >>confdefs.h <<_ACEOF #define GROUPID "$GROUPID" _ACEOF # Check whether --with-done_jobs was given. if test "${with_done_jobs+set}" = set; then withval=$with_done_jobs; DONE_JOBS="$withval" else DONE_JOBS="1" fi { echo "$as_me:$LINENO: number of job status to retain : $DONE_JOBS" >&5 echo "$as_me: number of job status to retain : $DONE_JOBS" >&6;} cat >>confdefs.h <<_ACEOF #define DONE_JOBS "$DONE_JOBS" _ACEOF # Check whether --with-done_jobs_max_age was given. if test "${with_done_jobs_max_age+set}" = set; then withval=$with_done_jobs_max_age; DONE_JOBS_MAX_AGE="$withval" else DONE_JOBS_MAX_AGE="0" fi { echo "$as_me:$LINENO: max age to retain job status (0=no expiry): $DONE_JOBS_MAX_AGE" >&5 echo "$as_me: max age to retain job status (0=no expiry): $DONE_JOBS_MAX_AGE" >&6;} cat >>confdefs.h <<_ACEOF #define DONE_JOBS_MAX_AGE "$DONE_JOBS_MAX_AGE" _ACEOF { echo "$as_me:$LINENO: checking terminal screen clear program" >&5 echo $ECHO_N "checking terminal screen clear program... $ECHO_C" >&6; } if test -z "$CLEAR" ; then # Extract the first word of "clear", so it can be a program name with args. set dummy clear; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_CLEAR+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $CLEAR in [\\/]* | ?:[\\/]*) ac_cv_path_CLEAR="$CLEAR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CLEAR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi CLEAR=$ac_cv_path_CLEAR if test -n "$CLEAR"; then { echo "$as_me:$LINENO: result: $CLEAR" >&5 echo "${ECHO_T}$CLEAR" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CLEAR" ; then { echo "$as_me:$LINENO: WARNING: Program 'clear' is not found. Set environment CLEAR=no if you do not want to use it" >&5 echo "$as_me: WARNING: Program 'clear' is not found. Set environment CLEAR=no if you do not want to use it" >&2;}; exit 1 fi if test "$CLEAR" = "no" ; then CLEAR= ; fi if test -n "$CLEAR" ; then cat >>confdefs.h <<_ACEOF #define CLEAR "$CLEAR" _ACEOF fi { echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } if test "${ac_cv_c_const+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { /* FIXME: Include the comments suggested by Paul. */ #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; const charset cs; /* SunOS 4.1.1 cc rejects this. */ char const *const *pcpcc; char **ppc; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; /* AIX XL C 1.02.0.0 rejects this. It does not let you subtract one const X* pointer from another in an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; pcpcc = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ ++pcpcc; ppc = (char**) pcpcc; pcpcc = (char const *const *) ppc; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; *t++ = 0; if (s) return 0; } { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ int x[] = {25, 17}; const int *foo = &x[0]; ++foo; } { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ typedef const int *iptr; iptr p = 0; ++p; } { /* AIX XL C 1.02.0.0 rejects this saying "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ struct s { int j; const int *ap[3]; }; struct s *b; b->j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; if (!foo) return 0; } return !cs[0] && !zero.x; #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 echo "${ECHO_T}$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF #define const _ACEOF fi { echo "$as_me:$LINENO: checking for inline" >&5 echo $ECHO_N "checking for inline... $ECHO_C" >&6; } if test "${ac_cv_c_inline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifndef __cplusplus typedef int foo_t; static $ac_kw foo_t static_foo () {return 0; } $ac_kw foo_t foo () {return 0; } #endif _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_inline=$ac_kw else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext test "$ac_cv_c_inline" != no && break done fi { echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 echo "${ECHO_T}$ac_cv_c_inline" >&6; } case $ac_cv_c_inline in inline | yes) ;; *) case $ac_cv_c_inline in no) ac_val=;; *) ac_val=$ac_cv_c_inline;; esac cat >>confdefs.h <<_ACEOF #ifndef __cplusplus #define inline $ac_val #endif _ACEOF ;; esac { echo "$as_me:$LINENO: checking for working volatile" >&5 echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; } if test "${ac_cv_c_volatile+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { volatile int x; int * volatile y = (int *) 0; return !x && !y; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_volatile=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_volatile=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 echo "${ECHO_T}$ac_cv_c_volatile" >&6; } if test $ac_cv_c_volatile = no; then cat >>confdefs.h <<\_ACEOF #define volatile _ACEOF fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi ac_header_dirent=no for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5 echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include <$ac_hdr> int main () { if ((DIR *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 _ACEOF ac_header_dirent=$ac_hdr; break fi done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then { echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' dir; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi else { echo "$as_me:$LINENO: checking for library containing opendir" >&5 echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6; } if test "${ac_cv_search_opendir+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char opendir (); int main () { return opendir (); ; return 0; } _ACEOF for ac_lib in '' x; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break fi done if test "${ac_cv_search_opendir+set}" = set; then : else ac_cv_search_opendir=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5 echo "${ECHO_T}$ac_cv_search_opendir" >&6; } ac_res=$ac_cv_search_opendir if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi fi { echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6; } if test "${ac_cv_header_sys_wait_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifndef WEXITSTATUS # define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8) #endif #ifndef WIFEXITED # define WIFEXITED(stat_val) (((stat_val) & 255) == 0) #endif int main () { int s; wait (&s); s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_sys_wait_h=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6; } if test $ac_cv_header_sys_wait_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_WAIT_H 1 _ACEOF fi { echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } if test "${ac_cv_header_time+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include int main () { if ((struct tm *) 0) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 echo "${ECHO_T}$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF #define TIME_WITH_SYS_TIME 1 _ACEOF fi { echo "$as_me:$LINENO: checking return type of signal handlers" >&5 echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } if test "${ac_cv_type_signal+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { return *(signal (0, 0)) (0) == 1; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_signal=int else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_signal=void fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 echo "${ECHO_T}$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal _ACEOF { echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5 echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6; } if test "${ac_cv_type_uid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "uid_t" >/dev/null 2>&1; then ac_cv_type_uid_t=yes else ac_cv_type_uid_t=no fi rm -f conftest* fi { echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5 echo "${ECHO_T}$ac_cv_type_uid_t" >&6; } if test $ac_cv_type_uid_t = no; then cat >>confdefs.h <<\_ACEOF #define uid_t int _ACEOF cat >>confdefs.h <<\_ACEOF #define gid_t int _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for size_t" >&5 echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } if test "${ac_cv_type_size_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef size_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_size_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 echo "${ECHO_T}$ac_cv_type_size_t" >&6; } if test $ac_cv_type_size_t = yes; then : else cat >>confdefs.h <<_ACEOF #define size_t unsigned int _ACEOF fi { echo "$as_me:$LINENO: checking for mode_t" >&5 echo $ECHO_N "checking for mode_t... $ECHO_C" >&6; } if test "${ac_cv_type_mode_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef mode_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_mode_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_mode_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5 echo "${ECHO_T}$ac_cv_type_mode_t" >&6; } if test $ac_cv_type_mode_t = yes; then : else cat >>confdefs.h <<_ACEOF #define mode_t int _ACEOF fi { echo "$as_me:$LINENO: checking for off_t" >&5 echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } if test "${ac_cv_type_off_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef off_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_off_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_off_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 echo "${ECHO_T}$ac_cv_type_off_t" >&6; } if test $ac_cv_type_off_t = yes; then : else cat >>confdefs.h <<_ACEOF #define off_t long int _ACEOF fi { echo "$as_me:$LINENO: checking for pid_t" >&5 echo $ECHO_N "checking for pid_t... $ECHO_C" >&6; } if test "${ac_cv_type_pid_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default typedef pid_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_pid_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 echo "${ECHO_T}$ac_cv_type_pid_t" >&6; } if test $ac_cv_type_pid_t = yes; then : else cat >>confdefs.h <<_ACEOF #define pid_t int _ACEOF fi { echo "$as_me:$LINENO: checking for fd_set" >&5 echo $ECHO_N "checking for fd_set... $ECHO_C" >&6; } if test "${ac_cv_type_fd_set+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include typedef fd_set ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_fd_set=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_fd_set=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_fd_set" >&5 echo "${ECHO_T}$ac_cv_type_fd_set" >&6; } if test $ac_cv_type_fd_set = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_FD_SET 1 _ACEOF fi { echo "$as_me:$LINENO: checking for socklen_t" >&5 echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6; } if test "${ac_cv_type_socklen_t+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include typedef socklen_t ac__type_new_; int main () { if ((ac__type_new_ *) 0) return 0; if (sizeof (ac__type_new_)) return 0; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_socklen_t=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_socklen_t=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_type_socklen_t" >&5 echo "${ECHO_T}$ac_cv_type_socklen_t" >&6; } if test $ac_cv_type_socklen_t = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SOCKLEN_T 1 _ACEOF fi checklibs= for ac_header in arpa/inet.h arpa/nameser.h assert.h com_err.h compat.h ctype.h ctypes.h dirent.h errno.h fcntl.h filehdr.h grp.h limits.h locale.h machine/vmparam.h malloc.h memory.h ndir.h netdb.h netinet/in.h pwd.h resolv.h select.h setjmp.h sgtty.h signal.h stab.h stdarg.h stdio.h stdlib.h string.h strings.h sys/dir.h sys/exec.h sys/fcntl.h sys/file.h sys/ioctl.h sys/mount.h sys/ndir.h sys/param.h sys/pstat.h sys/resource.h sys/select.h sys/signal.h sys/socket.h sys/stat.h sys/statfs.h sys/statvfs.h sys/syslog.h sys/systeminfo.h sys/termio.h sys/termiox.h sys/time.h sys/ttold.h sys/ttycom.h sys/types.h sys/utsname.h sys/vfs.h sys/wait.h syslog.h term.h termcap.h termio.h termios.h time.h unistd.h utsname.h varargs.h vmparam.h endian.h stdint.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------- ## ## Report this to lprng-devel@lists.sf.net ## ## --------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for library containing getpwent" >&5 echo $ECHO_N "checking for library containing getpwent... $ECHO_C" >&6; } if test "${ac_cv_search_getpwent+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char getpwent (); int main () { return getpwent (); ; return 0; } _ACEOF for ac_lib in '' posix; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_getpwent=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_getpwent+set}" = set; then break fi done if test "${ac_cv_search_getpwent+set}" = set; then : else ac_cv_search_getpwent=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_getpwent" >&5 echo "${ECHO_T}$ac_cv_search_getpwent" >&6; } ac_res=$ac_cv_search_getpwent if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing gethostbyaddr" >&5 echo $ECHO_N "checking for library containing gethostbyaddr... $ECHO_C" >&6; } if test "${ac_cv_search_gethostbyaddr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gethostbyaddr (); int main () { return gethostbyaddr (); ; return 0; } _ACEOF for ac_lib in '' nsl_s nsl net_s net; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_gethostbyaddr=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_gethostbyaddr+set}" = set; then break fi done if test "${ac_cv_search_gethostbyaddr+set}" = set; then : else ac_cv_search_gethostbyaddr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_gethostbyaddr" >&5 echo "${ECHO_T}$ac_cv_search_gethostbyaddr" >&6; } ac_res=$ac_cv_search_gethostbyaddr if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi { echo "$as_me:$LINENO: checking for library containing socket" >&5 echo $ECHO_N "checking for library containing socket... $ECHO_C" >&6; } if test "${ac_cv_search_socket+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char socket (); int main () { return socket (); ; return 0; } _ACEOF for ac_lib in '' socket_s socket; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_socket=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_socket+set}" = set; then break fi done if test "${ac_cv_search_socket+set}" = set; then : else ac_cv_search_socket=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_socket" >&5 echo "${ECHO_T}$ac_cv_search_socket" >&6; } ac_res=$ac_cv_search_socket if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi if test -z "$no_resolv_lib"; then { echo "$as_me:$LINENO: checking for inet_ntop" >&5 echo $ECHO_N "checking for inet_ntop... $ECHO_C" >&6; } if test "${ac_cv_func_inet_ntop+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define inet_ntop to an innocuous variant, in case declares inet_ntop. For example, HP-UX 11i declares gettimeofday. */ #define inet_ntop innocuous_inet_ntop /* System header to define __stub macros and hopefully few prototypes, which can conflict with char inet_ntop (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef inet_ntop /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntop (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_inet_ntop || defined __stub___inet_ntop choke me #endif int main () { return inet_ntop (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_inet_ntop=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_inet_ntop=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_inet_ntop" >&5 echo "${ECHO_T}$ac_cv_func_inet_ntop" >&6; } if test $ac_cv_func_inet_ntop = yes; then name2=yes fi if test -z "$name2" ; then { echo "$as_me:$LINENO: checking for inet_ntop in -lresolv" >&5 echo $ECHO_N "checking for inet_ntop in -lresolv... $ECHO_C" >&6; } if test "${ac_cv_lib_resolv_inet_ntop+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char inet_ntop (); int main () { return inet_ntop (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_resolv_inet_ntop=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_inet_ntop=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_ntop" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_inet_ntop" >&6; } if test $ac_cv_lib_resolv_inet_ntop = yes; then LIBS="$LIBS -lresolv";name2=yes fi fi; fi { echo "$as_me:$LINENO: checking for setproctitle in -lutil" >&5 echo $ECHO_N "checking for setproctitle in -lutil... $ECHO_C" >&6; } if test "${ac_cv_lib_util_setproctitle+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lutil $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setproctitle (); int main () { return setproctitle (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_util_setproctitle=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_util_setproctitle=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_util_setproctitle" >&5 echo "${ECHO_T}$ac_cv_lib_util_setproctitle" >&6; } if test $ac_cv_lib_util_setproctitle = yes; then LIBS="-lutil $LIBS" fi for ac_func in _res cfsetispeed fcntl flock gethostbyname2 getdtablesize gethostname getrlimit inet_aton inet_ntop inet_pton innetgr initgroups killpg lockf mkstemp mktemp openlog putenv random rand setenv seteuid setgroups setlocale setpgid setproctitle setresuid setreuid setruid setsid sigaction sigprocmask siglongjmp socketpair strcasecmp strchr strdup strerror strncasecmp sysconf sysinfo tcdrain tcflush tcsetattr uname unsetenv wait3 waitpid do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test ! "$ac_cv_func_setreuid" = yes -a ! "$ac_cv_func_seteuid" = yes -a ! "$ac_cv_func_setresuid" = yes; then { echo "$as_me:$LINENO: WARNING: missing setreuid(), seteuid(), and setresuid()" >&5 echo "$as_me: WARNING: missing setreuid(), seteuid(), and setresuid()" >&2;} fi for ac_header in vfork.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------- ## ## Report this to lprng-devel@lists.sf.net ## ## --------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in fork vfork do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done if test "x$ac_cv_func_fork" = xyes; then { echo "$as_me:$LINENO: checking for working fork" >&5 echo $ECHO_N "checking for working fork... $ECHO_C" >&6; } if test "${ac_cv_func_fork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_fork_works=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default int main () { /* By Ruediger Kuhlmann. */ return fork () < 0; ; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_fork_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_fork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_func_fork_works" >&5 echo "${ECHO_T}$ac_cv_func_fork_works" >&6; } else ac_cv_func_fork_works=$ac_cv_func_fork fi if test "x$ac_cv_func_fork_works" = xcross; then case $host in *-*-amigaos* | *-*-msdosdjgpp*) # Override, as these systems have only a dummy fork() stub ac_cv_func_fork_works=no ;; *) ac_cv_func_fork_works=yes ;; esac { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} fi ac_cv_func_vfork_works=$ac_cv_func_vfork if test "x$ac_cv_func_vfork" = xyes; then { echo "$as_me:$LINENO: checking for working vfork" >&5 echo $ECHO_N "checking for working vfork... $ECHO_C" >&6; } if test "${ac_cv_func_vfork_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$cross_compiling" = yes; then ac_cv_func_vfork_works=cross else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Thanks to Paul Eggert for this test. */ $ac_includes_default #include #ifdef HAVE_VFORK_H # include #endif /* On some sparc systems, changes by the child to local and incoming argument registers are propagated back to the parent. The compiler is told about this with #include , but some compilers (e.g. gcc -O) don't grok . Test for this by using a static variable whose address is put into a register that is clobbered by the vfork. */ static void #ifdef __cplusplus sparc_address_test (int arg) # else sparc_address_test (arg) int arg; #endif { static pid_t child; if (!child) { child = vfork (); if (child < 0) { perror ("vfork"); _exit(2); } if (!child) { arg = getpid(); write(-1, "", 0); _exit (arg); } } } int main () { pid_t parent = getpid (); pid_t child; sparc_address_test (0); child = vfork (); if (child == 0) { /* Here is another test for sparc vfork register problems. This test uses lots of local variables, at least as many local variables as main has allocated so far including compiler temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should reuse the register of parent for one of the local variables, since it will think that parent can't possibly be used any more in this routine. Assigning to the local variable will thus munge parent in the parent process. */ pid_t p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); /* Convince the compiler that p..p7 are live; otherwise, it might use the same hardware register for all 8 local variables. */ if (p != p1 || p != p2 || p != p3 || p != p4 || p != p5 || p != p6 || p != p7) _exit(1); /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent from child file descriptors. If the child closes a descriptor before it execs or exits, this munges the parent's descriptor as well. Test for this by closing stdout in the child. */ _exit(close(fileno(stdout)) != 0); } else { int status; struct stat st; while (wait(&status) != child) ; return ( /* Was there some problem with vforking? */ child < 0 /* Did the child fail? (This shouldn't happen.) */ || status /* Did the vfork/compiler bug occur? */ || parent != getpid() /* Did the file descriptor bug occur? */ || fstat(fileno(stdout), &st) != 0 ); } } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_func_vfork_works=yes else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_func_vfork_works=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi { echo "$as_me:$LINENO: result: $ac_cv_func_vfork_works" >&5 echo "${ECHO_T}$ac_cv_func_vfork_works" >&6; } fi; if test "x$ac_cv_func_fork_works" = xcross; then ac_cv_func_vfork_works=$ac_cv_func_vfork { echo "$as_me:$LINENO: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} fi if test "x$ac_cv_func_vfork_works" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_WORKING_VFORK 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define vfork fork _ACEOF fi if test "x$ac_cv_func_fork_works" = xyes; then cat >>confdefs.h <<\_ACEOF #define HAVE_WORKING_FORK 1 _ACEOF fi for ac_func in vprintf do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF { echo "$as_me:$LINENO: checking for _doprnt" >&5 echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6; } if test "${ac_cv_func__doprnt+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define _doprnt to an innocuous variant, in case declares _doprnt. For example, HP-UX 11i declares gettimeofday. */ #define _doprnt innocuous__doprnt /* System header to define __stub macros and hopefully few prototypes, which can conflict with char _doprnt (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef _doprnt /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char _doprnt (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub__doprnt || defined __stub____doprnt choke me #endif int main () { return _doprnt (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func__doprnt=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__doprnt=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 echo "${ECHO_T}$ac_cv_func__doprnt" >&6; } if test $ac_cv_func__doprnt = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_DOPRNT 1 _ACEOF fi fi done { echo "$as_me:$LINENO: checking how to manipulate tty attributes" >&5 echo $ECHO_N "checking how to manipulate tty attributes... $ECHO_C" >&6; } if test "${ac_cv_struct_term+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test "$ac_cv_header_termios_h" = yes; then ac_cv_struct_term=termios fi if test "$ac_cv_header_sys_termios_h" = yes; then ac_cv_struct_term=termios fi if test -z "$ac_cv_struct_term" ; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_TERMIO_H #include #endif #ifdef HAVE_SYS_TERMIO_H #include #endif int main () { struct termio t;t.c_iflag = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_struct_term=termio else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$ac_cv_struct_term" ; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { struct sgttyb s;s.sg_flags = 0 ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_struct_term=sgttyb else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi if test -z "$ac_cv_struct_term" ; then ac_cv_struct_term=UNDEFINED fi fi { echo "$as_me:$LINENO: result: $ac_cv_struct_term" >&5 echo "${ECHO_T}$ac_cv_struct_term" >&6; } if test "$ac_cv_struct_term" = "sgttyb"; then cat >>confdefs.h <<\_ACEOF #define USE_SGTTYB 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_STTY SGTTYB _ACEOF fi if test "$ac_cv_struct_term" = "termio"; then cat >>confdefs.h <<\_ACEOF #define USE_TERMIO 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_STTY TERMIO _ACEOF fi if test "$ac_cv_struct_term" = "termios"; then cat >>confdefs.h <<\_ACEOF #define USE_TERMIOS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define USE_STTY TERMIOS _ACEOF if test "$ac_cv_header_sys_termiox_h" = yes; then cat >>confdefs.h <<\_ACEOF #define USE_TERMIOX 1 _ACEOF fi fi { echo "$as_me:$LINENO: checking checking for lseek prototype" >&5 echo $ECHO_N "checking checking for lseek prototype... $ECHO_C" >&6; } if test "${ac_cv_lseek_proto+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_UNISTD_H #include #endif int main () { off_t x; x = lseek(0,"test",SEEK_SET); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_lseek_proto=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lseek_proto=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_lseek_proto" >&5 echo "${ECHO_T}$ac_cv_lseek_proto" >&6; } if test "$ac_cv_lseek_proto" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_LSEEK_PROTO 1 _ACEOF fi { echo "$as_me:$LINENO: checking how to get filesystem free space" >&5 echo $ECHO_N "checking how to get filesystem free space... $ECHO_C" >&6; } if test "${ac_cv_struct_fstype+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else fstype= if test "$ac_cv_func_statvfs" != no ; then #{ cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_VFS_H # include #endif int main () { struct statvfs s; statvfs ("/", &s); return(s.f_bavail+s.f_bsize) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then fstype=statvfs else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi #} if test "$ac_cv_func_statfs" != no ; then #{ if test -z "$fstype" ; then #{ cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H # include #endif #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_VFS_H # include #endif int main () { struct fs_data s; return(s.fd_bfree+s.fd_bsize) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then fstype=Ultrix-statfs else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi #} if test -z "$fstype" ; then #{ cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif int main () { struct statfs s; return(s.f_bavail+s.f_bsize) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then fstype=statfs else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi # } if test -z "$fstype" ; then # { cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #ifdef HAVE_SYS_STATFS_H #include #endif #ifdef HAVE_SYS_MOUNT_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif int main () { struct statfs s; return(s.f_bfree+s.f_bsize) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then fstype=SVR3-statfs else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi # } fi # } if test -z "$fstype" ; then echo "cannot find a valid statfs-like structure!" fstype=UNKNOWN fi ac_cv_struct_fstype=$fstype fi { echo "$as_me:$LINENO: result: $ac_cv_struct_fstype" >&5 echo "${ECHO_T}$ac_cv_struct_fstype" >&6; } if test "$ac_cv_struct_fstype" = SVR3-statfs; then cat >>confdefs.h <<\_ACEOF #define USE_STATFS_TYPE SVR3_STATFS _ACEOF fi if test "$ac_cv_struct_fstype" = Ultrix-statfs; then cat >>confdefs.h <<\_ACEOF #define USE_STATFS_TYPE ULTRIX_STATFS _ACEOF fi if test "$ac_cv_struct_fstype" = statfs; then cat >>confdefs.h <<\_ACEOF #define USE_STATFS_TYPE STATFS _ACEOF fi if test "$ac_cv_struct_fstype" = statvfs; then cat >>confdefs.h <<\_ACEOF #define USE_STATFS_TYPE STATVFS _ACEOF fi { echo "$as_me:$LINENO: checking for setproctitle declaration" >&5 echo $ECHO_N "checking for setproctitle declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_setproctitle_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include #endif int main () { setproctitle(0); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_setproctitle_def=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_setproctitle_def=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_setproctitle_def" >&5 echo "${ECHO_T}$ac_cv_decl_setproctitle_def" >&6; } if test "$ac_cv_decl_setproctitle_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SETPROCTITLE_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for sys_siglist array" >&5 echo $ECHO_N "checking for sys_siglist array... $ECHO_C" >&6; } if test "${ac_cv_sys_siglist+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { extern int sys_siglist; printf("%d",sys_siglist); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_sys_siglist=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_sys_siglist=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_sys_siglist" >&5 echo "${ECHO_T}$ac_cv_sys_siglist" >&6; } if test "$ac_cv_sys_siglist" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_SIGLIST 1 _ACEOF { echo "$as_me:$LINENO: checking for sys_siglist declaration" >&5 echo $ECHO_N "checking for sys_siglist declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_sys_siglist_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SIGNAL_H #include #endif #include int main () { printf("%s",sys_siglist[0]); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_sys_siglist_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_sys_siglist_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_sys_siglist_def" >&5 echo "${ECHO_T}$ac_cv_decl_sys_siglist_def" >&6; } if test "$ac_cv_decl_sys_siglist_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_SIGLIST_DEF 1 _ACEOF ac_cv_sys_siglist=yes fi else { echo "$as_me:$LINENO: checking for _sys_siglist array" >&5 echo $ECHO_N "checking for _sys_siglist array... $ECHO_C" >&6; } if test "${ac_cv__sys_siglist+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include int main () { extern int _sys_siglist; printf("%d",_sys_siglist); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv__sys_siglist=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv__sys_siglist=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv__sys_siglist" >&5 echo "${ECHO_T}$ac_cv__sys_siglist" >&6; } if test "$ac_cv__sys_siglist" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE__SYS_SIGLIST 1 _ACEOF { echo "$as_me:$LINENO: checking for _sys_siglist declaration" >&5 echo $ECHO_N "checking for _sys_siglist declaration... $ECHO_C" >&6; } if test "${ac_cv_decl__sys_siglist_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_SIGNAL_H #include #endif #include int main () { printf("%s",_sys_siglist[0]); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl__sys_siglist_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl__sys_siglist_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl__sys_siglist_def" >&5 echo "${ECHO_T}$ac_cv_decl__sys_siglist_def" >&6; } if test "$ac_cv_decl__sys_siglist_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE__SYS_SIGLIST_DEF 1 _ACEOF ac_cv__sys_siglist=yes fi fi fi { echo "$as_me:$LINENO: checking for obsolete union wait compatibility" >&5 echo $ECHO_N "checking for obsolete union wait compatibility... $ECHO_C" >&6; } if test "${ac_cv_unionwait+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include int main () { union wait x;WIFEXITED(x); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_unionwait=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_unionwait=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_unionwait" >&5 echo "${ECHO_T}$ac_cv_unionwait" >&6; } if test "$ac_cv_unionwait" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_UNION_WAIT 1 _ACEOF fi { echo "$as_me:$LINENO: checking for gethostname declaration" >&5 echo $ECHO_N "checking for gethostname declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_gethostname_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif int main () { gethostname(1); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_gethostname_def=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_gethostname_def=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_gethostname_def" >&5 echo "${ECHO_T}$ac_cv_decl_gethostname_def" >&6; } if test "$ac_cv_decl_gethostname_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_GETHOSTNAME_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for innetgr declaration" >&5 echo $ECHO_N "checking for innetgr declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_innetgr_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDIO_H #include #endif #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_NETDB_H #include #endif int main () { printf("%d", innetgr(1)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_innetgr_def=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_innetgr_def=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_innetgr_def" >&5 echo "${ECHO_T}$ac_cv_decl_innetgr_def" >&6; } if test "$ac_cv_decl_innetgr_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_INNETGR_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for openlog declaration" >&5 echo $ECHO_N "checking for openlog declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_openlog_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_CTYPES_H #include #endif #ifdef HAVE_STDARG_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif int main () { printf("%d",openlog); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_openlog_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_openlog_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_openlog_def" >&5 echo "${ECHO_T}$ac_cv_decl_openlog_def" >&6; } if test "$ac_cv_decl_openlog_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_OPENLOG_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for syslog declaration" >&5 echo $ECHO_N "checking for syslog declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_syslog_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #ifdef HAVE_STDARG_H #include #endif #ifdef HAVE_SYSLOG_H #include #endif int main () { printf("%d",syslog); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_syslog_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_syslog_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_syslog_def" >&5 echo "${ECHO_T}$ac_cv_decl_syslog_def" >&6; } if test "$ac_cv_decl_syslog_def" = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SYSLOG_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct in6_addr declaration" >&5 echo $ECHO_N "checking for struct in6_addr declaration... $ECHO_C" >&6; } if test "${ac_cv_decl_in6_addr_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #include int main () { struct in6_addr v; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_in6_addr_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_in6_addr_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_in6_addr_def" >&5 echo "${ECHO_T}$ac_cv_decl_in6_addr_def" >&6; } if test "$ac_cv_decl_in6_addr_def" = yes; then cat >>confdefs.h <<\_ACEOF #define IN6_ADDR 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define IPV6 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct in_addr6 declaration (LINUX)" >&5 echo $ECHO_N "checking for struct in_addr6 declaration (LINUX)... $ECHO_C" >&6; } if test "${ac_cv_decl_in_addr6_def+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #include #include int main () { struct in_addr6 v; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_in_addr6_def=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_in_addr6_def=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_in_addr6_def" >&5 echo "${ECHO_T}$ac_cv_decl_in_addr6_def" >&6; } if test "$ac_cv_decl_in_addr6_def" = yes; then cat >>confdefs.h <<\_ACEOF #define IN_ADDR6 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define IPV6 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct stat has st_mtimespec.tv_nsec" >&5 echo $ECHO_N "checking for struct stat has st_mtimespec.tv_nsec... $ECHO_C" >&6; } if test "${ac_cv_decl_st_mtimespec_tv_nsec+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #ifdef HAVE_SYS_TIME_H #include #endif #include int main () { struct stat statb; statb.st_mtimespec.tv_nsec; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_st_mtimespec_tv_nsec=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_st_mtimespec_tv_nsec=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_st_mtimespec_tv_nsec" >&5 echo "${ECHO_T}$ac_cv_decl_st_mtimespec_tv_nsec" >&6; } if test "$ac_cv_decl_st_mtimespec_tv_nsec" = yes; then cat >>confdefs.h <<_ACEOF #define ST_MTIMESPEC_TV_NSEC 1 _ACEOF fi { echo "$as_me:$LINENO: checking for struct stat has st_mtimensec" >&5 echo $ECHO_N "checking for struct stat has st_mtimensec... $ECHO_C" >&6; } if test "${ac_cv_decl_st_mtimensec+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #include #if defined(HAVE_SYS_TIME_H) #include #endif #include int main () { struct stat statb; statb.st_mtimensec; ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_st_mtimensec=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_st_mtimensec=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_st_mtimensec" >&5 echo "${ECHO_T}$ac_cv_decl_st_mtimensec" >&6; } if test "$ac_cv_decl_st_mtimensec" = yes; then cat >>confdefs.h <<_ACEOF #define ST_MTIMENSEC 1 _ACEOF fi { echo "$as_me:$LINENO: checking for strcasecmp definition" >&5 echo $ECHO_N "checking for strcasecmp definition... $ECHO_C" >&6; } if test "${ac_cv_decl_strcasecmp+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #if defined(HAVE_STDLIB_H) #include #endif #if defined(HAVE_STRING_H) #include #endif #if defined(HAVE_STRINGS_H) #include #endif int main () { strcasecmp(1) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_strcasecmp=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_strcasecmp=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_strcasecmp" >&5 echo "${ECHO_T}$ac_cv_decl_strcasecmp" >&6; } if test "$ac_cv_decl_strcasecmp" = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_STRCASECMP_DEF 1 _ACEOF fi { echo "$as_me:$LINENO: checking for flock definition" >&5 echo $ECHO_N "checking for flock definition... $ECHO_C" >&6; } if test "${ac_cv_decl_flock+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef HAVE_CTYPES_H #include #endif #if defined(HAVE_STDLIB_H) #include #endif #if defined(HAVE_SYS_FILE_H) #include #endif #if defined(HAVE_FCNTL_H) #include #endif int main () { flock(1) ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_decl_flock=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_decl_flock=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_decl_flock" >&5 echo "${ECHO_T}$ac_cv_decl_flock" >&6; } if test "$ac_cv_decl_flock" = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_FLOCK_DEF 1 _ACEOF fi # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # Extract the first word of "auxman", so it can be a program name with args. set dummy auxman; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_INSTALL_MAN+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$INSTALL_MAN"; then ac_cv_prog_INSTALL_MAN="$INSTALL_MAN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_INSTALL_MAN="auxman" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_INSTALL_MAN" && ac_cv_prog_INSTALL_MAN="$INSTALL -m 644" fi fi INSTALL_MAN=$ac_cv_prog_INSTALL_MAN if test -n "$INSTALL_MAN"; then { echo "$as_me:$LINENO: result: $INSTALL_MAN" >&5 echo "${ECHO_T}$INSTALL_MAN" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi { echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6; } set x ${MAKE-make}; ac_make=`echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } SET_MAKE= else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi { echo "$as_me:$LINENO: checking for shell" >&5 echo $ECHO_N "checking for shell... $ECHO_C" >&6; } SHELL=/bin/sh { echo "$as_me:$LINENO: result: using $SHELL (FORCED)" >&5 echo "${ECHO_T}using $SHELL (FORCED)" >&6; } { echo "$as_me:$LINENO: checking whether NLS is requested" >&5 echo $ECHO_N "checking whether NLS is requested... $ECHO_C" >&6; } # Check whether --enable-nls was given. if test "${enable_nls+set}" = set; then enableval=$enable_nls; USE_NLS=$enableval else USE_NLS=no fi { echo "$as_me:$LINENO: result: $USE_NLS" >&5 echo "${ECHO_T}$USE_NLS" >&6; } if test "$USE_NLS" = "yes"; then { echo "$as_me:$LINENO: checking for GNU gettext in libc" >&5 echo $ECHO_N "checking for GNU gettext in libc... $ECHO_C" >&6; } if test "${gt_cv_func_gnugettext1_libc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; int main () { bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then gt_cv_func_gnugettext1_libc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 gt_cv_func_gnugettext1_libc=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $gt_cv_func_gnugettext1_libc" >&5 echo "${ECHO_T}$gt_cv_func_gnugettext1_libc" >&6; } if test "$gt_cv_func_gnugettext1_libc" = "yes" ; then { echo "$as_me:$LINENO: checking for ngettext" >&5 echo $ECHO_N "checking for ngettext... $ECHO_C" >&6; } if test "${ac_cv_func_ngettext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define ngettext to an innocuous variant, in case declares ngettext. For example, HP-UX 11i declares gettimeofday. */ #define ngettext innocuous_ngettext /* System header to define __stub macros and hopefully few prototypes, which can conflict with char ngettext (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef ngettext /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ngettext (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_ngettext || defined __stub___ngettext choke me #endif int main () { return ngettext (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_ngettext=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_ngettext=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_ngettext" >&5 echo "${ECHO_T}$ac_cv_func_ngettext" >&6; } if test $ac_cv_func_ngettext = yes; then cat >>confdefs.h <<\_ACEOF #define ENABLE_NLS 1 _ACEOF else USE_NLS=no fi else USE_NLS=no fi fi { echo "$as_me:$LINENO: checking whether to use NLS" >&5 echo $ECHO_N "checking whether to use NLS... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $USE_NLS" >&5 echo "${ECHO_T}$USE_NLS" >&6; } # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgfmt", so it can be a program name with args. set dummy msgfmt; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_MSGFMT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$MSGFMT" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" ;; esac fi MSGFMT="$ac_cv_path_MSGFMT" if test "$MSGFMT" != ":"; then { echo "$as_me:$LINENO: result: $MSGFMT" >&5 echo "${ECHO_T}$MSGFMT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Extract the first word of "gmsgfmt", so it can be a program name with args. set dummy gmsgfmt; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_GMSGFMT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $GMSGFMT in [\\/]* | ?:[\\/]*) ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" ;; esac fi GMSGFMT=$ac_cv_path_GMSGFMT if test -n "$GMSGFMT"; then { echo "$as_me:$LINENO: result: $GMSGFMT" >&5 echo "${ECHO_T}$GMSGFMT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "xgettext", so it can be a program name with args. set dummy xgettext; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_XGETTEXT+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$XGETTEXT" in [\\/]* | ?:[\\/]*) ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" ;; esac fi XGETTEXT="$ac_cv_path_XGETTEXT" if test "$XGETTEXT" != ":"; then { echo "$as_me:$LINENO: result: $XGETTEXT" >&5 echo "${ECHO_T}$XGETTEXT" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi rm -f messages.po # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "msgmerge", so it can be a program name with args. set dummy msgmerge; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_MSGMERGE+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case "$MSGMERGE" in [\\/]* | ?:[\\/]*) ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&5 if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" ;; esac fi MSGMERGE="$ac_cv_path_MSGMERGE" if test "$MSGMERGE" != ":"; then { echo "$as_me:$LINENO: result: $MSGMERGE" >&5 echo "${ECHO_T}$MSGMERGE" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi { echo "$as_me:$LINENO: checking use tcp wrappers" >&5 echo $ECHO_N "checking use tcp wrappers... $ECHO_C" >&6; } # Check whether --enable-tcpwrappers was given. if test "${enable_tcpwrappers+set}" = set; then enableval=$enable_tcpwrappers; if test "$enableval" = "yes" ; then v=yes for ac_header in tcpd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------- ## ## Report this to lprng-devel@lists.sf.net ## ## --------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define HAVE_TCPD_H 1 _ACEOF else { { echo "$as_me:$LINENO: error: tcpd.h not found" >&5 echo "$as_me: error: tcpd.h not found" >&2;} { (exit 1); exit 1; }; }; v=no; fi done { echo "$as_me:$LINENO: checking for request_init in -lwrap" >&5 echo $ECHO_N "checking for request_init in -lwrap... $ECHO_C" >&6; } if test "${ac_cv_lib_wrap_request_init+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lwrap $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char request_init (); int main () { return request_init (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_wrap_request_init=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_wrap_request_init=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_wrap_request_init" >&5 echo "${ECHO_T}$ac_cv_lib_wrap_request_init" >&6; } if test $ac_cv_lib_wrap_request_init = yes; then LIBS="-lwrap $LIBS" else { { echo "$as_me:$LINENO: error: request_init not found in -wrap library" >&5 echo "$as_me: error: request_init not found in -wrap library" >&2;} { (exit 1); exit 1; }; }; v=no; fi else v=no; fi else v=no; fi if test "$v" = "yes" ; then cat >>confdefs.h <<\_ACEOF #define TCPWRAPPERS 1 _ACEOF fi { echo "$as_me:$LINENO: result: $v" >&5 echo "${ECHO_T}$v" >&6; }; { echo "$as_me:$LINENO: checking if ssl authentication is disabled" >&5 echo $ECHO_N "checking if ssl authentication is disabled... $ECHO_C" >&6; } # Check whether --enable-ssl was given. if test "${enable_ssl+set}" = set; then enableval=$enable_ssl; if test "$enableval" = "yes" ; then v=enabled; SSL_ENABLE=1; else v=disabled; SSL_ENABLE=; fi else v=enabled; SSL_ENABLE=1; fi { echo "$as_me:$LINENO: result: $v" >&5 echo "${ECHO_T}$v" >&6; }; ac_openssl_lib_dir= ac_openssl_inc_dir= if test "$SSL_ENABLE" != ""; then ac_openssl_lib_dir="/usr/lib /usr/local /usr/local/ssl /usr/local/ssl/lib /usr/pkg" ac_openssl_inc_dir="/usr/include /usr/local /usr/local/ssl /usr/pkg /usr/local/ssl/include" # Check whether --with-openssl was given. if test "${with_openssl+set}" = set; then withval=$with_openssl; ac_openssl_lib_dir="$withval/lib $withval" ac_openssl_inc_dir="$withval/include $withval" fi # Check whether --with-openssl-inc was given. if test "${with_openssl_inc+set}" = set; then withval=$with_openssl_inc; ac_openssl_inc_dir=$withval fi # Check whether --with-openssl-lib was given. if test "${with_openssl_lib+set}" = set; then withval=$with_openssl_lib; ac_openssl_lib_dir=$withval fi ac_found_openssl_inc_dir="no" { echo "$as_me:$LINENO: checking for OpenSSL include files" >&5 echo $ECHO_N "checking for OpenSSL include files... $ECHO_C" >&6; } for dir in $ac_openssl_inc_dir; do if test -f $dir/openssl/ssl.h; then ac_found_openssl_inc_dir=$dir break fi done if test "$ac_found_openssl_inc_dir" != "no"; then echo "found in $ac_found_openssl_inc_dir" else echo "not found." SSL_ENABLE="" fi fi SSL_LDADD="" if test "$SSL_ENABLE" != ""; then ac_found_openssl_lib_dir="no" { echo "$as_me:$LINENO: checking for OpenSSL libraries" >&5 echo $ECHO_N "checking for OpenSSL libraries... $ECHO_C" >&6; } for dir in $ac_openssl_lib_dir; do found_ssl="false" if test -f $dir/libssl.a -a -f $dir/libcrypto.a; then found_ssl="true" fi if test -f $dir/libssl.so -a -f $dir/libcrypto.so; then found_ssl="true" fi if $found_ssl != "false"; then save_LIBS=$LIBS save_LDFLAGS=$LDFLAGS SSL_LDADD="-lssl -lcrypto" if test "X$dir" != "X/usr/lib" ; then SSL_LDADD="-L$dir $SSL_LDADD" fi LDFLAGS="$LDFLAGS $SSL_LDADD" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char SSL_load_error_strings (); int main () { return SSL_load_error_strings (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_linked_libssl="true" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_linked_libssl="false" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext; cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char RC4_set_key (); int main () { return RC4_set_key (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_linked_libcrypto="true" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_linked_libcrypto="false" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext; if test "$ac_linked_libssl" != "false" -a \ "$ac_linked_libcrypto" != "false"; then ac_found_openssl_lib_dir=$dir LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS break fi LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS SSL_LDADD="" fi done if test "$ac_found_openssl_lib_dir" != "no"; then echo "found in $ac_found_openssl_lib_dir" if test "X$ac_found_openssl_inc_dir" != "X/usr/include" ; then CPPFLAGS="$CPPFLAGS -I$ac_found_openssl_inc_dir " ; fi else echo "not found." SSL_ENABLE="" fi fi if test "$SSL_ENABLE" != ""; then WITHSSL_TRUE= WITHSSL_FALSE='#' else WITHSSL_TRUE='#' WITHSSL_FALSE= fi test "$SSL_ENABLE" != "" && cat >>confdefs.h <<\_ACEOF #define SSL_ENABLE 1 _ACEOF { echo "$as_me:$LINENO: checking ssl Certificate Authority CERT file" >&5 echo $ECHO_N "checking ssl Certificate Authority CERT file... $ECHO_C" >&6; } # Check whether --with-ssl_ca_file was given. if test "${with_ssl_ca_file+set}" = set; then withval=$with_ssl_ca_file; SSL_CA_FILE=$withval else SSL_CA_FILE=\${configdir}/ssl.ca/ca.crt fi { echo "$as_me:$LINENO: result: $SSL_CA_FILE" >&5 echo "${ECHO_T}$SSL_CA_FILE" >&6; } { echo "$as_me:$LINENO: checking ssl Certificate Authority private key file" >&5 echo $ECHO_N "checking ssl Certificate Authority private key file... $ECHO_C" >&6; } # Check whether --with-ssl_ca_key was given. if test "${with_ssl_ca_key+set}" = set; then withval=$with_ssl_ca_key; SSL_CA_KEY=$withval else SSL_CA_KEY=\${configdir}/ssl.ca/ca.key fi { echo "$as_me:$LINENO: result: $SSL_CA_KEY" >&5 echo "${ECHO_T}$SSL_CA_KEY" >&6; } { echo "$as_me:$LINENO: checking ssl Certificate Authority certs working directory" >&5 echo $ECHO_N "checking ssl Certificate Authority certs working directory... $ECHO_C" >&6; } # Check whether --with-ssl_certs_dir was given. if test "${with_ssl_certs_dir+set}" = set; then withval=$with_ssl_certs_dir; SSL_CERTS_DIR=$withval else SSL_CERTS_DIR=\${configdir}/ssl.certs fi { echo "$as_me:$LINENO: result: $SSL_CERTS_DIR" >&5 echo "${ECHO_T}$SSL_CERTS_DIR" >&6; } { echo "$as_me:$LINENO: checking ssl Certificate Revocation List (CRL) file" >&5 echo $ECHO_N "checking ssl Certificate Revocation List (CRL) file... $ECHO_C" >&6; } # Check whether --with-ssl_crl_file was given. if test "${with_ssl_crl_file+set}" = set; then withval=$with_ssl_crl_file; SSL_CRL_FILE=$withval else SSL_CRL_FILE=\${configdir}/ssl.crl/ssl.crl fi { echo "$as_me:$LINENO: result: $SSL_CRL_FILE" >&5 echo "${ECHO_T}$SSL_CRL_FILE" >&6; } { echo "$as_me:$LINENO: checking ssl server certificate file" >&5 echo $ECHO_N "checking ssl server certificate file... $ECHO_C" >&6; } # Check whether --with-ssl_server_cert was given. if test "${with_ssl_server_cert+set}" = set; then withval=$with_ssl_server_cert; SSL_SERVER_CERT=$withval else SSL_SERVER_CERT=\${configdir}/ssl.server/server.crt fi { echo "$as_me:$LINENO: result: $SSL_SERVER_CERT" >&5 echo "${ECHO_T}$SSL_SERVER_CERT" >&6; } { echo "$as_me:$LINENO: checking ssl server password file for private key file" >&5 echo $ECHO_N "checking ssl server password file for private key file... $ECHO_C" >&6; } # Check whether --with-ssl_server_password_file was given. if test "${with_ssl_server_password_file+set}" = set; then withval=$with_ssl_server_password_file; SSL_SERVER_PASSWORD_FILE=$withval else SSL_SERVER_PASSWORD_FILE=\${configdir}/ssl.server/server.pwd fi { echo "$as_me:$LINENO: result: $SSL_SERVER_PASSWORD_FILE" >&5 echo "${ECHO_T}$SSL_SERVER_PASSWORD_FILE" >&6; } KRB_LIBS="" SAVELIBS="$LIBS" if test -n "$KERBEROS" ; then echo "Kerberos checks with CFLAGS '$CFLAGS', CPPFLAGS '$CPPFLAGS', LDFLAGS '$LDFLAGS" if test -d /usr/kerberos/include; then CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include" fi if test -d /usr/kerberos/lib; then LDFLAGS="-L/usr/kerberos/lib $LDFLAGS" fi found= for ac_header in krb5.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking $ac_header usability" >&5 echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking $ac_header presence" >&5 echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <$ac_header> _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ( cat <<\_ASBOX ## --------------------------------------- ## ## Report this to lprng-devel@lists.sf.net ## ## --------------------------------------- ## _ASBOX ) | sed "s/^/$as_me: WARNING: /" >&2 ;; esac { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF found=yes fi done if test "$found" != "yes" ; then { { echo "$as_me:$LINENO: error: Kerberos 5 support wanted and cannot find krb5.h include file use configure --disable-kerberos-checks or check your Kerberos 5 installation If you have installed kerberos in /usr/local/{lib,include} then use configure --enable-kerberos CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib " >&5 echo "$as_me: error: Kerberos 5 support wanted and cannot find krb5.h include file use configure --disable-kerberos-checks or check your Kerberos 5 installation If you have installed kerberos in /usr/local/{lib,include} then use configure --enable-kerberos CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib " >&2;} { (exit 1); exit 1; }; } fi if test "$KERBEROS_CHECKS" = 1 ; then cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include int main () { printf("%d",sizeof(HostAddress)); ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then heimdal=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 heimdal=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $heimdal = yes; then { echo "$as_me:$LINENO: WARNING: compiling with CFLAGS $CFLAGS" >&5 echo "$as_me: WARNING: compiling with CFLAGS $CFLAGS" >&2;} { { echo "$as_me:$LINENO: error: You appear to be using the Heimdal Kerberos krb5.h file. You must use MIT Kerberos with LPRng" >&5 echo "$as_me: error: You appear to be using the Heimdal Kerberos krb5.h file. You must use MIT Kerberos with LPRng" >&2;} { (exit 1); exit 1; }; } fi found=no if test "$found" "!=" "yes" ; then found=yes KRB_LIBS="-lkrb5 -lk5crypto -lcom_err" LIBS=" $KRB_LIBS $SAVELIBS" { echo "$as_me:$LINENO: checking for krb5_init_context in $LIBS ..." >&5 echo "$as_me: checking for krb5_init_context in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_init_context (); int main () { return krb5_init_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking for krb5_encrypt_size in $LIBS ..." >&5 echo "$as_me: checking for krb5_encrypt_size in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_encrypt_size (); int main () { return krb5_encrypt_size (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi; if test "$found" "!=" "yes" ; then found=yes KRB_LIBS="-lkrb5 -lcrypto -lcom_err" LIBS=" $KRB_LIBS $SAVELIBS" { echo "$as_me:$LINENO: checking for krb5_init_context in $LIBS ..." >&5 echo "$as_me: checking for krb5_init_context in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_init_context (); int main () { return krb5_init_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking for krb5_encrypt_size in $LIBS ..." >&5 echo "$as_me: checking for krb5_encrypt_size in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_encrypt_size (); int main () { return krb5_encrypt_size (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi; if test "$found" "!=" "yes" ; then # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_KRB5CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $KRB5CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5CONFIG="$KRB5CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_KRB5CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi KRB5CONFIG=$ac_cv_path_KRB5CONFIG if test -n "$KRB5CONFIG"; then { echo "$as_me:$LINENO: result: $KRB5CONFIG" >&5 echo "${ECHO_T}$KRB5CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi found=yes KRB_LIBS="$($KRB5CONFIG --libs krb5)" LIBS=" $KRB_LIBS $SAVELIBS" { echo "$as_me:$LINENO: checking for krb5_init_context in $LIBS ..." >&5 echo "$as_me: checking for krb5_init_context in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_init_context (); int main () { return krb5_init_context (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext { echo "$as_me:$LINENO: checking for krb5_encrypt_size in $LIBS ..." >&5 echo "$as_me: checking for krb5_encrypt_size in $LIBS ..." >&6;} cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_encrypt_size (); int main () { return krb5_encrypt_size (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 found="no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi; if test "$found" "!=" "yes" ; then { echo "$as_me:$LINENO: WARNING: Kerberos 5 library does not have krb5_init_context and krb5_encrypt_size or " >&5 echo "$as_me: WARNING: Kerberos 5 library does not have krb5_init_context and krb5_encrypt_size or " >&2;} { echo "$as_me:$LINENO: WARNING: use configure --disable-kerberos or check your Kerberos 5 installation" >&5 echo "$as_me: WARNING: use configure --disable-kerberos or check your Kerberos 5 installation" >&2;} exit 1 fi { echo "$as_me:$LINENO: result: found in $LIBS" >&5 echo "${ECHO_T}found in $LIBS" >&6; } { echo "$as_me:$LINENO: checking for krb5_read_message" >&5 echo $ECHO_N "checking for krb5_read_message... $ECHO_C" >&6; } if test "${ac_cv_func_krb5_read_message+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define krb5_read_message to an innocuous variant, in case declares krb5_read_message. For example, HP-UX 11i declares gettimeofday. */ #define krb5_read_message innocuous_krb5_read_message /* System header to define __stub macros and hopefully few prototypes, which can conflict with char krb5_read_message (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef krb5_read_message /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char krb5_read_message (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_krb5_read_message || defined __stub___krb5_read_message choke me #endif int main () { return krb5_read_message (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_func_krb5_read_message=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_krb5_read_message=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_krb5_read_message" >&5 echo "${ECHO_T}$ac_cv_func_krb5_read_message" >&6; } if test $ac_cv_func_krb5_read_message = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_READ_MESSAGE 1 _ACEOF else { echo "$as_me:$LINENO: WARNING: Kerberos 5 library does not have krb5_read_message" >&5 echo "$as_me: WARNING: Kerberos 5 library does not have krb5_read_message" >&2;} fi fi for ac_func in krb5_free_data_contents do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for krb5_xfree" >&5 echo $ECHO_N "checking for krb5_xfree... $ECHO_C" >&6; } if test "${ac_cv_krb5_xfree+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ # define KRB5_DEPRECATED 1 #if defined(HAVE_KRB5_H) #include #endif int main () { krb5_xfree((void *)0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_krb5_xfree=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_krb5_xfree=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_krb5_xfree" >&5 echo "${ECHO_T}$ac_cv_krb5_xfree" >&6; } if test "$ac_cv_krb5_xfree" = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_KRB5_XFREE 1 _ACEOF fi { echo "$as_me:$LINENO: checking for krb_xfree" >&5 echo $ECHO_N "checking for krb_xfree... $ECHO_C" >&6; } if test "${ac_cv_krb_xfree+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ # define KRB5_DEPRECATED 1 #if defined(HAVE_KRB5_H) #include #endif int main () { krb_xfree((void *)0); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_krb_xfree=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_krb_xfree=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_krb_xfree" >&5 echo "${ECHO_T}$ac_cv_krb_xfree" >&6; } if test "$ac_cv_krb_xfree" = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_KRB_XFREE 1 _ACEOF fi LIBS="$SAVELIBS" fi; # Check whether --enable-plugins was given. if test "${enable_plugins+set}" = set; then enableval=$enable_plugins; enable_plugins=$enableval else enable_plugins=no fi DL_LIBS="" if test $enable_plugins != no ; then mysaved_LIBS="$LIBS" { echo "$as_me:$LINENO: checking for library containing dlopen" >&5 echo $ECHO_N "checking for library containing dlopen... $ECHO_C" >&6; } if test "${ac_cv_search_dlopen+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break fi done if test "${ac_cv_search_dlopen+set}" = set; then : else ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_dlopen" >&5 echo "${ECHO_T}$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" if test "x$LIBS" != "x$mysaved_LIBS" ; then DL_LIBS="-ldl" fi else if test $enable_plugins = default ; then enable_plugins=no else { { echo "$as_me:$LINENO: error: Plugins requested with --enable-plugins but did not find dlopen" >&5 echo "$as_me: error: Plugins requested with --enable-plugins but did not find dlopen" >&2;} { (exit 1); exit 1; }; } enable_plugins=no fi fi LIBS="$mysaved_LIBS" fi if test $enable_plugins != no ; then if test "${PLUGIN_CFLAGS+set}" != set ; then PLUGIN_CFLAGS="-fPIE" fi if test "${PLUGIN_LDFLAGS+set}" != set ; then PLUGIN_LDFLAGS="--shared" fi if test "${PLUGINUSER_LDFLAGS+set}" != set ; then PLUGINUSER_LDFLAGS="-export-dynamic" fi { echo "$as_me:$LINENO: checking whether dynamic plugins can be generated and work" >&5 echo $ECHO_N "checking whether dynamic plugins can be generated and work... $ECHO_C" >&6; } if test "${my_cv_sys_shared_with_callback_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else mysaved_LDFLAGS="$LDFLAGS" mysaved_CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS $PLUGIN_LDFLAGS" CFLAGS="$CFLAGS $PLUGIN_CFLAGS" cat >conftest.$ac_ext <<_ACEOF int test(void);int test(void) {return callback();} _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then cp conftest$ac_exeext libmyXYZtest.so || { { echo "$as_me:$LINENO: error: Internal error, perhaps autoconf changed soem internals" >&5 echo "$as_me: error: Internal error, perhaps autoconf changed soem internals" >&2;} { (exit 1); exit 1; }; } my_cv_sys_shared_with_callback_works=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 my_cv_sys_shared_with_callback_works=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test $my_cv_sys_shared_with_callback_works = yes ; then LDFLAGS="$mysaved_LDFLAGS $PLUGINUSER_LDFLAGS -L. -lmyXYZtest" CFLAGS="$mysaved_CFLAGS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int callback(void) { return 17; } return test(); int main () { my_cv_sys_shared_with_callback_works=yes ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then my_cv_sys_shared_works=no else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi LDFLAGS="$mysaved_LDFLAGS" CFLAGS="$mysaved_CFLAGS" rm -f libmyXYZtest.so fi { echo "$as_me:$LINENO: result: $my_cv_sys_shared_with_callback_works" >&5 echo "${ECHO_T}$my_cv_sys_shared_with_callback_works" >&6; } if test $my_cv_sys_shared_with_callback_works = no ; then if test $enable_plugins = default ; then enable_plugins=no else { { echo "$as_me:$LINENO: error: Plugins requested with --enable-plugins but shared libraries cannot be created (might only work with gcc on linux yet, also make sure you have no -Wl,-z,defs or similar set)" >&5 echo "$as_me: error: Plugins requested with --enable-plugins but shared libraries cannot be created (might only work with gcc on linux yet, also make sure you have no -Wl,-z,defs or similar set)" >&2;} { (exit 1); exit 1; }; } enable_plugins=no fi fi fi if test $enable_plugins != no; then WITHPLUGINS_TRUE= WITHPLUGINS_FALSE='#' else WITHPLUGINS_TRUE='#' WITHPLUGINS_FALSE= fi if test $enable_plugins != no ; then cat >>confdefs.h <<\_ACEOF #define WITHPLUGINS 1 _ACEOF fi ac_config_files="$ac_config_files Makefile UTILS/LPRng.pm UTILS/Makefile UTILS/accounting.pl UTILS/decode_args_with_perl UTILS/decode_args_with_sh UTILS/fixid UTILS/fixupdate UTILS/lpq_in_perl UTILS/lpr_in_perl UTILS/lprm_in_perl UTILS/make_lpd_conf UTILS/make_printcap_use UTILS/makeinc UTILS/read_conf UTILS/remote_active UTILS/test_read UTILS/update_z.pl man/Makefile src/Makefile src/pclbanner src/psbanner po/Makefile conf/Makefile conf/lpd.perms" ac_config_commands="$ac_config_commands default" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${WITHKERBEROS_TRUE}" && test -z "${WITHKERBEROS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"WITHKERBEROS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"WITHKERBEROS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${WITHSSL_TRUE}" && test -z "${WITHSSL_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"WITHSSL\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"WITHSSL\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi if test -z "${WITHPLUGINS_TRUE}" && test -z "${WITHPLUGINS_FALSE}"; then { { echo "$as_me:$LINENO: error: conditional \"WITHPLUGINS\" was never defined. Usually this means the macro was only invoked conditionally." >&5 echo "$as_me: error: conditional \"WITHPLUGINS\" was never defined. Usually this means the macro was only invoked conditionally." >&2;} { (exit 1); exit 1; }; } fi : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by LPRng $as_me 3.8.B, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ LPRng config.status 3.8.B configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "UTILS/LPRng.pm") CONFIG_FILES="$CONFIG_FILES UTILS/LPRng.pm" ;; "UTILS/Makefile") CONFIG_FILES="$CONFIG_FILES UTILS/Makefile" ;; "UTILS/accounting.pl") CONFIG_FILES="$CONFIG_FILES UTILS/accounting.pl" ;; "UTILS/decode_args_with_perl") CONFIG_FILES="$CONFIG_FILES UTILS/decode_args_with_perl" ;; "UTILS/decode_args_with_sh") CONFIG_FILES="$CONFIG_FILES UTILS/decode_args_with_sh" ;; "UTILS/fixid") CONFIG_FILES="$CONFIG_FILES UTILS/fixid" ;; "UTILS/fixupdate") CONFIG_FILES="$CONFIG_FILES UTILS/fixupdate" ;; "UTILS/lpq_in_perl") CONFIG_FILES="$CONFIG_FILES UTILS/lpq_in_perl" ;; "UTILS/lpr_in_perl") CONFIG_FILES="$CONFIG_FILES UTILS/lpr_in_perl" ;; "UTILS/lprm_in_perl") CONFIG_FILES="$CONFIG_FILES UTILS/lprm_in_perl" ;; "UTILS/make_lpd_conf") CONFIG_FILES="$CONFIG_FILES UTILS/make_lpd_conf" ;; "UTILS/make_printcap_use") CONFIG_FILES="$CONFIG_FILES UTILS/make_printcap_use" ;; "UTILS/makeinc") CONFIG_FILES="$CONFIG_FILES UTILS/makeinc" ;; "UTILS/read_conf") CONFIG_FILES="$CONFIG_FILES UTILS/read_conf" ;; "UTILS/remote_active") CONFIG_FILES="$CONFIG_FILES UTILS/remote_active" ;; "UTILS/test_read") CONFIG_FILES="$CONFIG_FILES UTILS/test_read" ;; "UTILS/update_z.pl") CONFIG_FILES="$CONFIG_FILES UTILS/update_z.pl" ;; "man/Makefile") CONFIG_FILES="$CONFIG_FILES man/Makefile" ;; "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; "src/pclbanner") CONFIG_FILES="$CONFIG_FILES src/pclbanner" ;; "src/psbanner") CONFIG_FILES="$CONFIG_FILES src/psbanner" ;; "po/Makefile") CONFIG_FILES="$CONFIG_FILES po/Makefile" ;; "conf/Makefile") CONFIG_FILES="$CONFIG_FILES conf/Makefile" ;; "conf/lpd.perms") CONFIG_FILES="$CONFIG_FILES conf/lpd.perms" ;; "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim am__isrc!$am__isrc$ac_delim CYGPATH_W!$CYGPATH_W$ac_delim PACKAGE!$PACKAGE$ac_delim VERSION!$VERSION$ac_delim ACLOCAL!$ACLOCAL$ac_delim AUTOCONF!$AUTOCONF$ac_delim AUTOMAKE!$AUTOMAKE$ac_delim AUTOHEADER!$AUTOHEADER$ac_delim MAKEINFO!$MAKEINFO$ac_delim install_sh!$install_sh$ac_delim STRIP!$STRIP$ac_delim INSTALL_STRIP_PROGRAM!$INSTALL_STRIP_PROGRAM$ac_delim mkdir_p!$mkdir_p$ac_delim AWK!$AWK$ac_delim SET_MAKE!$SET_MAKE$ac_delim am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim MAINT!$MAINT$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim DEPDIR!$DEPDIR$ac_delim am__include!$am__include$ac_delim am__quote!$am__quote$ac_delim AMDEP_TRUE!$AMDEP_TRUE$ac_delim AMDEP_FALSE!$AMDEP_FALSE$ac_delim AMDEPBACKSLASH!$AMDEPBACKSLASH$ac_delim CCDEPMODE!$CCDEPMODE$ac_delim am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim SED!$SED$ac_delim PERL!$PERL$ac_delim CHOWN!$CHOWN$ac_delim CHGRP!$CHGRP$ac_delim PRUTIL!$PRUTIL$ac_delim OPENSSL!$OPENSSL$ac_delim PRIV_PORTS!$PRIV_PORTS$ac_delim LPD_LISTEN_PORT!$LPD_LISTEN_PORT$ac_delim NOREMOTE!$NOREMOTE$ac_delim INCLUDELPDCONFLOCAL!$INCLUDELPDCONFLOCAL$ac_delim WITHKERBEROS_TRUE!$WITHKERBEROS_TRUE$ac_delim WITHKERBEROS_FALSE!$WITHKERBEROS_FALSE$ac_delim KERBEROS!$KERBEROS$ac_delim lpdbindir!$lpdbindir$ac_delim configdir!$configdir$ac_delim LPD_CONF_PATH!$LPD_CONF_PATH$ac_delim LPD_PERMS_PATH!$LPD_PERMS_PATH$ac_delim PRINTCAP_PATH!$PRINTCAP_PATH$ac_delim LPD_PRINTCAP_PATH!$LPD_PRINTCAP_PATH$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF CEOF$ac_eof _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF UNIXSOCKETPATH!$UNIXSOCKETPATH$ac_delim LOCKFILE!$LOCKFILE$ac_delim SD_DEFAULT!$SD_DEFAULT$ac_delim plugindir!$plugindir$ac_delim filterdir!$filterdir$ac_delim FILTER_LD_PATH!$FILTER_LD_PATH$ac_delim FILTER_PATH!$FILTER_PATH$ac_delim CLEAR!$CLEAR$ac_delim CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim INSTALL_MAN!$INSTALL_MAN$ac_delim USE_NLS!$USE_NLS$ac_delim MSGFMT!$MSGFMT$ac_delim GMSGFMT!$GMSGFMT$ac_delim XGETTEXT!$XGETTEXT$ac_delim MSGMERGE!$MSGMERGE$ac_delim SSL_LDADD!$SSL_LDADD$ac_delim WITHSSL_TRUE!$WITHSSL_TRUE$ac_delim WITHSSL_FALSE!$WITHSSL_FALSE$ac_delim SSL_CA_FILE!$SSL_CA_FILE$ac_delim SSL_CA_KEY!$SSL_CA_KEY$ac_delim SSL_CERTS_DIR!$SSL_CERTS_DIR$ac_delim SSL_CRL_FILE!$SSL_CRL_FILE$ac_delim SSL_SERVER_CERT!$SSL_SERVER_CERT$ac_delim SSL_SERVER_PASSWORD_FILE!$SSL_SERVER_PASSWORD_FILE$ac_delim KRB5CONFIG!$KRB5CONFIG$ac_delim KRB_LIBS!$KRB_LIBS$ac_delim PLUGIN_LDFLAGS!$PLUGIN_LDFLAGS$ac_delim PLUGIN_CFLAGS!$PLUGIN_CFLAGS$ac_delim PLUGINUSER_LDFLAGS!$PLUGINUSER_LDFLAGS$ac_delim WITHPLUGINS_TRUE!$WITHPLUGINS_TRUE$ac_delim WITHPLUGINS_FALSE!$WITHPLUGINS_FALSE$ac_delim DL_LIBS!$DL_LIBS$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 36; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" # Compute $ac_file's index in $config_headers. _am_arg=$ac_file _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { echo "$as_me:$LINENO: executing $ac_file commands" >&5 echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir=$dirpart/$fdir case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ;; "default":C) for i in \ UTILS/LPRng.pm \ UTILS/accounting.pl \ UTILS/decode_args_with_perl \ UTILS/decode_args_with_sh \ UTILS/fixid \ UTILS/fixupdate \ UTILS/lpq_in_perl \ UTILS/lpr_in_perl \ UTILS/lprm_in_perl \ UTILS/make_lpd_conf \ UTILS/make_printcap_use \ UTILS/makeinc \ UTILS/read_conf \ UTILS/remote_active \ UTILS/test_read \ UTILS/update_z.pl \ ; do chmod +x $i ; done ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi lprng-3.8.B/ABOUT-NLS.LPRng0000644000131400013140000000217611531672125012020 00000000000000 Internationalization and gettext Patrick Powell Fri Sep 5 13:01:06 PDT 2003 Internationalization is done using the gettext packages. There are three possibilities to use this functionality: a) no internationalization (default) ./configure b) nationalization if system supports it and gettext installed on your system: ./configure --enable-nls You may discover that system support for NLS has been put into /usr/local/{include,lib}. Sometimes the C compiler does not search these directories by default and you will need to use: configure 'CPPFLAGS=-I/usr/local/include' \ 'LDFLAGS=-L/usr/local/lib' --enable-nls How to Install the gettext software: 1. Get the gettext distribution and install it on your local system ftp://prep.ai.mit.edu/pub/gnu/gettext- Unpack it by using: tar zxvf gettext-.tgz cd gettext- Read the documentation. It is pretty straight forward with respect to installation. 2. Create and/or update the configuration information using the CREATE_CONFIGURE script in the source directory: sh CREATE_CONFIGURE lprng-3.8.B/KERBEROS_configuration0000755000131400013140000000075611531672125013703 00000000000000#!/bin/sh set -x if [ -d /usr/share/man ] ; then mandir="--mandir=/usr/share/man" fi for i in /usr/kerberos /usr/local/kerberos /usr/local ; do if [ -d $i/include ] ; then CPPFLAGS="$CPPFLAGS -I$i/include"; fi if [ -d $i/lib ] ; then LDFLAGS="$LDFLAGS -L$i/lib"; fi done export LDFLAGS CPPFLAGS sh ./configure --prefix=/usr --sysconfdir=/etc $mandir \ --enable-ssl --enable-force_localhost \ --enable-kerberos --enable-mit_kerberos4 \ LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS" exit 0 lprng-3.8.B/missing0000755000131400013140000002557711531672272011224 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2006-05-10.23 # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program 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, or (at your option) # any later version. # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). case $1 in lex|yacc) # Not GNU programs, they don't have --version. ;; tar) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $1 in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison|yacc) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex|flex) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit 1 fi ;; makeinfo) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: lprng-3.8.B/NEWS0000644000131400013140000000463011531672126010305 00000000000000--------------------------------------------------------------------- Version LPRng-3.8.B --------------------------------------------------------------------- - new --enable-plugins to build authentication modules as dynamic loadable modules - --enable-nls now needs ngettext availabe and uses it - drop support for kerberos4 and pgp authentication - some small bugfixes / cleanups / improvements --------------------------------------------------------------------- Version LPRng-3.8.A --------------------------------------------------------------------- This is the first release not done by Patrick Powell but by the new team to maintain LPRng. The project is hosted on sourceforge, take a look at http://sourceforge.net/projects/lprng/ and join us on the new mailing-list at http://lists.sourceforge.net/mailman/listinfo/lprng-devel The biggest change is the switch to using automake to generate the Makefile.im and cleaning the autoconf rules a bit. Most things should work just as before, with the following exceptions: - make install no longer tries to remove previous installed printing systems and to modify your system to run LPRng, you will have to do this yourself. Example files with descriptions can be found in the conf/ subdirectory of the source. - binaries are currently not made suid even if requested, that might be reimplemented in the future. - when configuring with --enable-nls less time is invested in finding a gettext implementation. You might need to give it some more flags when using a gettext not in your libc. There is a new configure option --disable-remote to change the default to not listen via tcp and not accepting requests from remote hosts. (Also without --disable-remote, lpd_listen_port defaults to 515 and not lpd_port). Otherwise a lot of cleanup has happened. Many compiler warnings quieted, prototypes added, format strings synced with format of arguments, some code and manpages with strange license situation replaced, ip mask parsing more robus, local functions declared static, deleting some unreachable code, moving some code around to not have to link all lpd code in all other binaries... --------------------------------------------------------------------- Changes in versions until LPRng-3.8.28 can be found in the file CHANGES. If that file did not come with your LPRng, you should be able to download it from: http://lprng.cvs.sourceforge.net/*checkout*/lprng/lprng/CHANGES lprng-3.8.B/CONTRIBUTORS0000644000131400013140000001537011531672125011470 00000000000000Thanks to the following folks who made the LPRng software possible: Developer: Patrick Powell LPRng - 1996 - 1999 These folks have greatly contributed by sending patches, requests, warnings, and pleas for changes or improvements, and are really the driving force behind LPRng. Also, thanks to the many others who did not make it to the list, but whose contributions were, none the less, greatly appreciated. In (semi) alphatical order: Heinz-Ado Arnolds Damon W Atkins Jos Backus Jeff Bacon Don Badrak Jan Barte Marc Baudoin Oved Ben-Aroya Carsten Benecke Ole Benner Thierry Besancon Zygo Blaxell Uri Blumenthal Sherwood Botsford Paul Burry John Callaghan Gary Cender David Coelho Garrett D'Amore Bertrand Decouty Panos Dimakopoulos Jarrod Douglas James P. Dugal Avery Earle Niklas Edmundsson Paul Eggert Jussi Eloranta Jon E. Ferguson Horst Fickensche Markus Fleck Albert Fluegel Per Foreby Carson Gaspar Guy Geens Dave Goldhammer Dwaine C. Gonyier Tony Graham Brad Greer Patrick Hildenbrand Carl Hilton Ken Hornstein Lee Muh Hwa Philip J. Nesser II Edan Idzerda Christian Illinger Park Jae-hyon Helmut Jarausch Christophe Kalt Charles Karney Petri Kaukasoina Jost Krieger Christian Kuehnke John R Lane Andrew Leahy Elliot Lee Marty Leisner George Lindholm David Livingstone Qing Long Alan F Lundin Desmond Macauley Al Marquardt Norman R. McBride Duncan McEwan K.D. Meyer Todd C. Miller Walter Misar Stefan Monnier Tim Mooney Chad Mynhier Scott Nelson Nathan Neulinger Dirk Nitschke Chris O'Regan Jesse Off Martin Pahl John Perkins Giray Pultar Todd Rannow Andrew Richards Keith Richardson Michel Robitaille Florian La Roche Brad Rogers Bernhard Rosenkraenzer Ron Roskens Sven Rudolph Cortney Sampson Ed Santiago Wolfgang Scherer Gerhard Schneider Rainer Schoepf Yuji Shinozaki Chen Shiyuan Alan Shutko Lennart Sorth Klaus Steinberger David Stenglein Harlan Stenn Jim Stosick Scott Sutherland Paul Szabo Frank Terhaar-Yonkers Sergio Tessaris Jens Thiel Jens Thiel Anthony Thyssen Cecil R. Whitaker Doug White Simon Wilkinson Dirk Wrocklage Chao-Wen Young Paul Zablosky Reinhard Zierke LPRng - The Alpha Version 1994-1996 The lprng@lprng.com mailing list, and many folks on it who made comments and requests for features, changes, etc. Alpha Minus Portablility Testers: Michael Joosten Ken Lalonde Marty Leisner 1996 psfilter (psrev, banner) derived from: LPRPS Version 2.6 PLP James Clark PLP4.0 - The baseline distribution Justin Mason - PLP4.0 - archvist and maintainer PLP4.0 Contributors: Corey Minyard Stuart Kemp Angus Duggan Julian Turnbull Paul Haldane Michael Joosten Bjarne Steinsbo Todd C. Miller Eric C Hagberg maf@math.chalmers.se (Martin Forssen) Stefano Ianigro Greg Wohletz Michael Haardt Julian Anderson George Harrach but@unibw-hamburg.de (Lothar Butsch) dmc900@durras.anu.edu.au (David M Clarke) Harlan Stenn Ed Santiago Panos Dimakopoulos dorab@twinsun.com (Dorab Patel) Rick Martin Baba Z Buehler Bertrand Wallrich jarausch@igpm.igpm.rwth-aachen.de (Helmut Jarausch) Dave Alden Jan Barte Hendrik.Klompmaker@Beheer.zod.wau.nl (hendrik klompmaker) LPRng - Thousands and Thousands lprng-3.8.B/README.SSL.SECURITY0000644000131400013140000007560011531672126012401 00000000000000 Using and Abusing SSL Securty OR It must be secure, its so bloody hard to use (With apologies to Eric A. Young and the OpenSSL developers) Patrick Powell Thu Jul 18 10:20:58 PDT 2002 Executive Summary SSL Encryption and authentication is supported using the OpenSSL library. The following changes have been made to LPRng: lprng_certs - a certificate creation/management tool lpd.perms - AUTHFROM set to the 'subject' value of sender CERT AUTHCA set to the 'issuer' value of sender CERT and the hierarchy of 'issuer' values of CERT signers. ${HOME}/.lpr/client.crt, ${HOME}/.lpr/client.pwd - user or client certificate locations /etc/lpd/ssl.ca, /etc/lpd/ssl.server - locations of certificates and server certificates Introduction Why add SSL security to LPRng? a) It's there. b) Everybody and their dog is using it. c) It is needed to support IPP So I got hold of the SSL and TLS book by Eric Rescorla (he may regret this shameless plug, but be it on his head), and started reading it. After two weeks and a VERY large bottle of 'Super Strong No Doze Wakeup Pills' I figured out what needed to be done: a) Set up some certs (i.e. - X509 Authentication Certificates). b) Get some code from some other places and the examples. c) Read the code, figure out what it was doing, and then reverse engineer the SSL stuff. d) File off serial numbers, recode, etc., where necessary to 1) avoid the GNU license curse 2) make it LPRng specific My references were: Mod_ssl from the Apache project. http://www.apache.org Follow links to Mod_SSL OR get apache2 which has mod_ssl in it. Stole the organization for certs, as well as looking at how the Makefile created and installed the various certificates. fetchmail ftp://ftp.ccil.org/pub/esr/fetchmail http://www.tuxedo.org/~esr/fetchmail Ummm... this was happenstance, I use fetchmail and it has the SSL authentication in it. curl http://download.sourceforge.net/curl/ Again, I use curl and it has SSL. The articles by Eric Rescola: An Introduction to OpenSSL Programming http://www.rtfm.com/openssl-examples/ wserver, wclient, sclient And the book: SSL and TLS - Desiging and Building Secure Systems And, of course, the OpenSSL code, the examples in the code, the utilities, etc. etc. etc. About 260,000 lines of etc. Sigh... WHAT I DID a) Started with the Eric Rescola articles, and the examples for wserver, wclient. b) Added various things to handle getting authentication. - printing the Subject and Issuer information - adding directory information for Certificate locations c) Created new certificates using what I thought would work... d) Read 260,000 lines of OpenSSL code and heartily cursed the OpenSSL developers, the OpenSSL coders, and just about anybody who is associated with the project for NOT putting in some trace statements OR better error message reporting. But that is over new, and I have recalled the guys with the baseball bats. e) Documented this so that other people can figure out what I did. HERE IS WHAT YOU NEED TO KNOW The idea behind SSL is that you create some files (Certificates) that have various private/public key information in them. A checksum is calculated over the information, and then the checksum is 'encrypted' using a private key of some 'signer'. This is attached to the certficate file... and the whole thing is encoded in the most obnoxious manner... ANS1 to be exact. This is then EXPANDED into a text format called PEM, and forms the 'certificate file'. Now lets see what we do to validate that a certificate is correct or from the 'Subject' who is identified in the Certificate. We get the X509 certificate for the 'signer' (or 'Issuer' in X509 jargon). Since the public key of the signer is including in the 'signer' certificate, we can use this to check that the information in the suspect certificate is valid by using it to decrypt the checksum information encoded with the private key. If this matches, we have validated the certificate. (Well, not quite. There are a couple more gotchas.) Now we must validate the 'signers' cerificate, which was in turn signed by another signer, and so we go up the food chain, I mean 'authentication chain', until we reach Nirvana: a certificate which is signed by itself (i.e. - root certificate) or more exactly, a certificate where the 'subject' or the person identified by the CERT and the 'issuer' or the person who signed the CERT are the same. Now lets see how we use this for printing. Each user and/or print spooler is given a certificate with a corresponding set of private and secret keys. When a client sends a request to the lpd server, he signs it using his private key; the lpd spooler gets the request, and then decodes/checks it using the public key in the users certificate. The SSL protocol provides a way to: a) set up an encrypted connection (not our problem) b) exchange certificate information (Hmm... need to tell OpenSSL what certs to exchange) c) validate the certificates (strictly speaking, this X509 stuff, but what the hey...) and hence, authenticate the end users. (Need to tell OpenSSL where the certs are). d) set up and perform encrypted data exchange. (not our problem). So all we really need to do is set up the CERTIFICATES, tell the OpenSSL library where they are, and it should do the work for us. (Ho ho ho... it sounds so simple...) There are two components to a certificate: a) the certificate file (name.crt file) itself b) the private key corresponding to the public key in the certificate file (name.key file). Now clearly if the private key was obtained by somebody then they could impersonate a user. So there are two possibilities: a) make the private key file readable only by the people that need it (more on this later). b) encrypt the private key and then when you need to use it to sign something, provide a decryption password/key. So, we have 3 components: the certificate (name.crt), the encrypted private key (name.key, but encrypted) and a password that we use to decrypt the private key. But since we do not need to keep the private key hidden away, we can put the private key and certificate in the same file: -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,3EAD3ED0FA436761 Vi5K0olpFfe2ltDpY/7gPM4iW74gYqtO1yEFm1DOhp7Kd8hB5Is6TVuVX78zkTaP ... j6Z5TX61x4YCHKleFa9nXFC5god/MCYzIHKKep0f4TKWCZcJLR5AyQ== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDGzCCAoSgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBkzELMAkGA1UEBhMCVVMx ... 3VapletoUPtYPvUAAgAg4w28pKWvlVW3tU/CsoHDEw== -----END CERTIFICATE----- Which is the convention we adopted for LPRng. Now lets deal with the problem of certificates. There are FOUR types of certificates that we need: CERTS/files root (/etc/lpd/ssl.ca/ca.crt) - signer1 (/etc/lpd/ssl.ca/signer1.crt - signed by ca) - print spoolers (/etc/lpd/ssl.server/h121.crt - signed by signer1 ) - users (${HOME}/.lpd/user1.crt - signed by signer1 ) - signer2 (/etc/lpd/ssl.ca/signer2.crt - signed by ca) - print spoolers (/etc/lpd/ssl.server/h121.crt - signed by signer2) - users (${HOME}/.lpd/user2.crt - signed by signer2) The ROOT cert signs the signer certs, which in turn can sign print spooler certs and user certs. If you feel lucky, you can also use the root cert to sign print spoolers or user certs. Now, what happens if and when somebody gets hold of the private key for the root cert or a signing cert? If it is for the root cert, you are doomed. Reissue all the CERTS. Start from square 0. If it is a signing cert, then you can REVOKE it. How do you do this? You put it into a 'revocation' directory, and then tell OpenSSL to do its magic and update the CERT information so that it is revoked. (More on this later). Finally, how does the certificate information get transferred? This is a little complicated, and there are a zillion ways to do this. I have opted to implement and use a very simple method based on the Apached mod_perl SSL setup. a) A directory (/etc/lpd/ssl.ca/) containing all of the signing certificates, including the root certificate (ca.crt). These will be used by both servers and clients. Note: due to the OpenSSL implementation, it may be necessary to copy files to this directory. OpenSSL also supports putting all of the certificates in a single file. The certificates should be put in root to leaf order, i.e. - a breadth first walk of the certificate tree. For individual signing/certificate files: printcap/configure option: ssl_ca_path=DIR default=/etc/lpd/ssl.ca/ssl.ca For single signing/certificate files: printcap/configure option: ssl_ca_file=FILE default= NONE configure: --with-ssl_ca_path=DIR default ${sysconfdir}/lpd/ssl.crt/ --with-ssl_ca_file=FILE default - none Note: See the SSL_CTX_load_verify_locations( SSL_CTX *ctx, const char *CAfile, const char *CApath); documentation for the details. b) The LPRng lpd server certifcate file and the password for using the certificate: A file (/etc/lpd/server.crt/server.crt) containing the cert that is used by the server. It should also contain the private key for the server. printcap/configure option: ssl_server_cert=FILE default ${sysconfdir}/lpd/server.crt/server.crt configure: --with-ssl_server_cert=PATH default ${sysconfdir}/lpd/server.crt/server.crt Note: See SSL_CTX_use_certificate_chain_file( SSL_CTX *ctx, const char *file); SSL_use_PrivateKey_file(SSL *ssl, char *file, int type); documentation for details. Note that this file can contain multiple certs, but these must be sorted in top (root CA) to bottom (server) order. i.e. - private_key, server cert (additional certs specified by ssl_ca_path or ssl_ca_file) OR root CA cert, signer1 cert, ..., server cert Note: the private key can be in any position. The password file file contains the password for the private key in the server cert file. This file should to be 600, owned by the LPD server user. printcap/configure option: ssl_server_passwd=FILE default ${sysconfdir}/lpd/server.crt/server.crt configure: --with-ssl_server_passwd=PATH Note: See the SSL_CTX_set_default_passwd_cb for details. The password is read from the file. d) For user authentication to the server, users will need to specify a certificate and password. This can be by using values in default files or ${HOME}/.lpr/ssl.ca/ - signing/root certificates (if not present, then ${sysconfdir}/lpd/ssl.ca/ is used) Environment variable: LPR_CA_PATH ${HOME}/.lpr/client.crt - client cert and key Environment variable: LPR_SSL_CERT ${HOME}/.lpr/client.pwd - file containing client password Environment variable: LPR_SSL_PASSWORD CERTIFICATE FIELDS: There are several fields that need to be set in a certificate/ C = country [US] ST = state [California] L = city [San Diego] OU = Organization Unit [OU=Certificate Authority for root cert] [OU=Server for server cert] [OU=User for user cert] CN = Common Name [CN=Orgname for root cert] [CN=ServerID (h110.astart) for server cert] [CN=papowell for user cert] Email = email address [Email=hostmaster@astart.com for root cert] [Email=hostmaster@h110.astart for server cert] [Email=papowell@astart.com for user cert] You can set default values for these fields. SETTING UP CERTIFICATE AUTHORITY There are several types of certificate files: - CA root (self signed) - signing certs (signed by CA or by signing cert) - server certs (used by lpd server AND by lpd server when forwarding to a remote queue) - user certs (used to identify users programs) The certificates are arranged as follows: 1. signing certs are in a directory (or a single file) default: /etc/lpd/ssl.ca/* 2. server certs are in a directory default: /etc/lpd/ssl.server/* 3. user certificates are kept in a subdirectory of the user home directory, say: ${HOME}/.lpr/client.crt - cert ${HOME}/.lpr/client.pwd - password to use cert private key for authentication 4. certificates are created in a working directory and are then copied (if necessary) to the correct directory. default: /etc/lpd/ssl.certs PRINTCAP INFORMATION: the following entries are added to the printcap or lpd.conf file: lp: :auth=ssl # ssl authentication :ssl_id=lp # id value :ssl_ca_file=/etc/lpd/ssl.ca/ca.crt # certs for signing :ssl_crl_file=/etc/lpd/ssl.crl/ssl.crl # revocation certs :ssl_server_cert=/etc/lpd/ssl.server/server.crt # server cert :ssl_server_password_file=/etc/lpd/ssl.server/server.pwd # password CREATING CERTS The lprng_certs script provides a way to create ROOT certs, signer certs, server (lpd) certs, and user certs. You may need to copy the certificate files to the appropriate locations. usage: lprng_certs option init - make directory structure newca - make new root CA and defaults defaults - set new default values encrypt keyfile - set or change password on private key file gen - generate user, server, or signing cert verify cert* - verify certs certs can be path or user-XX.csr values STEP 1: CREATE DIRECTORY STRUCTURE Use: lprng_certs [--TEMP=/dir] init - creates directories for lpd server TEMP=/dir sets the directory; byt default, TEMP=/etc/lpd ${TEMP}/ssl.ca/ - ca root and/or signer certs default location for creation ${TEMP}/ssl.server/ - server cert (usually server.crt and server.pwd files) ${TEMP}/ssl.certs/ - server and/or user certs default location for creation You use this to set up the directories for certificates on a non-master system. STEP 2: CREATE CA ROOT CERT AND SET CERTIFICATE DEFAULTS Use: lprng [--TEMP=/dir] newca You use this when you want to set up a totally new CA on a master system. Example of use: #> lprng_certs newca lprng_certs -- LPRng SSL Certificate Management Copyright (c) 2002 Patrick Powell Based on CCA by Ralf S. Engelschall (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.) WARNING: /etc/lpd/ssl.ca/ca.crt already exists! Do you want to overwrite it? [N/y] Y INITIALIZATION - SET DEFAULTS There are several fields that need to be set in a certificate/ C = country [US] ST = state [California] L = city [San Diego] OU = Organization Unit [OU=Certificate Authority for root cert] [OU=Server for server cert] [OU=User for user cert] CN = Common Name [CN=Orgname for root cert] [CN=ServerID (h110.astart) for server cert] [CN=papowell for user cert] Email = email address [Email=hostmaster@astart.com for root cert] [Email=hostmaster@h110.astart for server cert] [Email=papowell@astart.com for user cert] You can set default values for these fields. 110: {90} % lprng_certs --TEMP=/tmp newca lprng_certs -- LPRng SSL Certificate Management Copyright (c) 2002 Patrick Powell Based on CCA by Ralf S. Engelschall (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.) INITIALIZATION - SET DEFAULTS in /tmp/ssl.ca/ca.defaults *** you can change the defaults as shown *** 1. Country Name (2 letter code, C) [default 'XY'] US 2. State or Province Name (full name, ST) [default 'Snake Desert'] California 3. Locality Name (eg, city, L) [default 'Snake Town'] San Diego 4. Organization Name (eg, company, O) [default 'Snake Oil, Ltd'] Astart Technologies 5. Organizational Unit Name for CA (eg, section, OU) [default 'CA'] 6. Organizational Unit Name for Signer (eg, section, OU) [default 'Signer'] 7. Organizational Unit Name for Server (eg, section, OU) [default 'Server'] 8. Organizational Unit Name for User (eg, section, OU) [default 'User'] 9. Common Name for CA (eg, CA name, CN) [default 'Snake Oil CA'] Astart CA 10. Common Name for Signer (eg, signer name, CN) [default 'Signer Name'] 11. Common Name for Server (eg, server name, CN) [default 'PrintServer Name'] 12. Common Name for User (eg, user name, CN) [default 'John Q. User'] 13. Email Address (eg, name@FQDN, Email) [default 'name@snakeoil.dom'] name@astart.com 14. CA Certificate Validity in days [default '365'] 15. Signer Certificate Validity in days [default '365'] 16. Server Certificate Validity in days [default '365'] 17. User Certificate Validity in days [default '365'] 18. Signer Certificate Path (blank indicates CA signs) [default ''] 19. Signer Private Key File (blank indicates key in cert file) [default ''] 20. Created Certificates Directory (blank indicates default /tmp/ssl.certs) [default ''] 21. Revoked Certificates File (blank indicates default /tmp/certs.crl) [default ''] **** this shows what the new default value will be ***** C_val US ST_val California L_val San Diego O_val Astart Technologies OU_ca_val CA OU_signer_val Signer OU_server_val Server OU_user_val User CN_ca_val Astart CA CN_signer_val Signer Name CN_server_val PrintServer Name CN_user_val John Q. User Email_val name@astart.com Validity_ca_val 365 Validity_signer_val 365 Validity_server_val 365 Validity_user_val 365 Signer_cert_path Signer_key_path Cert_dir Revoke_file ... ______________________________________________________________________ STEP 1: Generating RSA private key for CA (1024 bit) 49279 semi-random bytes loaded Generating RSA private key, 1024 bit long modulus .........................................++++++ .................++++++ e is 65537 (0x10001) ______________________________________________________________________ STEP 2: Generating X.509 certificate signing request for CA You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. *** change any of the field names *** ----- 1. Country Name (2 letter code, C) [US]: 2. State or Province Name (full name, ST) [California]: 3. Locality Name (eg, city, L) [San Diego]: 4. Organization Name (eg, company, 0) [Astart Technologies]: 5. Organizational Unit Name (eg, section, OU) [CA]: 6. Common Name (eg, ca name, CN) [Astart CA]: 7. Email Address (eg, name@FQDN, Email) [name@astart.com]:root@astart.com ______________________________________________________________________ STEP 3: Generating X.509 certificate for CA signed by itself Signature ok subject=/C=US/ST=California/L=San Diego/O=Astart Technologies/OU=CA/CN=Astart CA/emailAddress=root@astart.com Getting Private key ______________________________________________________________________ RESULT: /tmp/ssl.ca/ca.crt: /C=US/ST=California/L=San Diego/O=Astart Technologies/OU=CA/CN=Astart CA/emailAddress=root@astart.com error 18 at 0 depth lookup:self signed certificate OK ______________________________________________________________________ STEP 4. Enrypting RSA private key /tmp/ssl.ca/ca.key with a pass phrase for security The contents of the certificate key file (the generated private key) should be echo kept secret, especially so if it is used to sign Certificates or for User authentication. SSL experts strongly recommend you to encrypt the key file with a Triple-DES cipher and a Pass Phrase. When using LPRng, you provide the password via a file specified by the LPR_SSL_PASSWORD environent variable, or in the /home/papowell/.lpr/client.pwd file. The LPD server uses the ssl_server_password_file option to specify the location of a file containing the password. Encrypt the private key now? [Y/n]: writing RSA key Enter PEM pass phrase: Verifying - Enter PEM pass phrase: Fine, you're using an encrypted private key to sign CERTS. ______________________________________________________________________ STEP 5: Combine CERT and KEY file Generate single CERT and KEY file? [N/y] Indexing /tmp/ssl.ca ca.crt ... cbd552ae.0 Use the following commands to examine the CERT and KEY files: openssl x509 -text -in /tmp/ssl.ca/ca.crt openssl rsa -text -in /tmp/ssl.ca/ca.key STEP 3: CREATE SERVER CERTS AND INSTALL ON SERVERS Creates a certificate with the appropriate entries for use as a server (lpd) certificate. Example: #> lprng_certs gen lprng_certs -- LPRng SSL Certificate Management Copyright (c) 2002 Patrick Powell Based on CCA by Ralf S. Engelschall (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.) CERTIFICATE GENERATION What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] s Create in '/etc/lpd/ssl.certs' [return for yes, or specify directory] y CERT name 'server-01'? [return for yes, or specify name] h110 CERT name 'h110'? [return for yes, or specify name] Creating h110 in /etc/lpd/ssl.certs Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' [return for yes, or specify cert file] Private key in /etc/lpd/ssl.ca/ca.crt Generating user Certificate [h110] ______________________________________________________________________ STEP 1: Generating RSA private key for user (1024 bit) ______________________________________________________________________ STEP 2: Generating X.509 certificate signing request for user User Certificate Validity in days [default 365] ______________________________________________________________________ STEP 3: Generating X.509 certificate signed by own CA ______________________________________________________________________ RESULT: /etc/lpd/ssl.certs/h110.crt: OK ______________________________________________________________________ STEP 4. Enrypting RSA private key with a pass phrase for security The contents of the certificate key file (the generated private key) should be echo kept secret, especially so if it is used to sign Certificates or for User authentication. SSL experts strongly recommend you to encrypt the key file with a Triple-DES cipher and a Pass Phrase. When using LPRng, you provide the password via a file or file descriptor specified by an environent variable, i.e. - SSL_PASSWORD_FILE or SSL_PASSWORD_FD, or in the ${HOME}/.ssl_password file. The LPD server uses the ssl_server_password_file option to specify the location of a file containing the password. See the LPRng Refernce Manual for details, or the printcap(5) man page. key file is /etc/lpd/ssl.certs/h110.key Encrypt the private key now? [Y/n]: y Fine, you're using an encrypted private key to sign CERTS. ______________________________________________________________________ STEP 5: Combine CERT and KEY file Generate single CERT and KEY file? [Y/n] y Use the following commands to examine the CERT and KEY files: openssl x509 -text -in /etc/lpd/ssl.certs/h110.crt openssl rsa -text -in /etc/lpd/ssl.certs/h110.crt ---------- You must now copy the h110.crt certificate to the lpd server certificate file location: cp /etc/lpd/ssl.certs/h110.crt /etc/lpd/server.cert/server.crt echo 'password' >/etc/lpd/server.crt/server.pwd chown lpd /etc/lpd/server.crt/server.pwd chmod 700 /etc/lpd/server.crt/server.pwd (Note: lpd is the user that the LPD server will run as. This value is set by the configuration in the lpd.conf file.) STEP 5: CREATE AND INSTALL USER CERTS Creates a certificate with the appropriate entries for use as a server (lpd) certificate. Example: #> lprng_certs gen lprng_certs -- LPRng SSL Certificate Management Copyright (c) 2002 Patrick Powell Based on CCA by Ralf S. Engelschall (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.) CERTIFICATE GENERATION What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] u Create in '/etc/lpd/ssl.certs' [return for yes, or specify directory] y CERT name 'user-01'? [return for yes, or specify name] papowell CERT name 'papowell'? [return for yes, or specify name] Creating h110 in /etc/lpd/ssl.certs Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' [return for yes, or specify cert file] Private key in /etc/lpd/ssl.ca/ca.crt ... Use the following commands to examine the CERT and KEY files: openssl x509 -text -in /etc/lpd/ssl.certs/papowell.crt openssl rsa -text -in /etc/lpd/ssl.certs/papowell.crt ---------- You must now copy the papowell.crt certificate to the user .lpd directory and then set the password. cp /etc/lpd/ssl.certs/papowell.crt ~papowell/.lpd/client.crt echo 'password' >~papowell/.lpd/client.pwd chown papowell ~papowell/.lpd/client.pwd chmod 700 ~papowell/.lpd/client.pwd CREATE A SIGNING CERT You will need to do this if you want to create a certificate that you can use to sign other certificates - i.e. - delegate signing authority. This is done by creating a signing certificate. The private key file for this certificate should be treated in the same was as for the root certificate - it should not be stored in the same file as the certificate, or if it is, the password for the key should be very long and resistant to a dictionary attack. I do not recommend storing the private key and certificate in the same file. lprng_certs -- LPRng SSL Certificate Management Copyright (c) 2002 Patrick Powell Based on CCA by Ralf S. Engelschall (Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved.) CERTIFICATE GENERATION What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] a Create in '/etc/lpd/ssl.ca' [return for yes, or specify directory] CERT name 'signer-02'? [return for yes, or specify name] Creating signer-02 in /etc/lpd/ssl.ca Sign with Certificate '/etc/lpd/ssl.ca/ca.crt' [return for yes, or specify cert file] Private key in /etc/lpd/ssl.ca/ca.crt Generating signer Certificate [signer-02] ______________________________________________________________________ STEP 1: Generating RSA private key for signer (1024 bit) ______________________________________________________________________ STEP 2: Generating X.509 certificate signing request for signer User Certificate Validity in days [default 365] ______________________________________________________________________ STEP 3: Generating X.509 certificate signed by own CA ______________________________________________________________________ RESULT: /etc/lpd/ssl.ca/signer-02.crt: OK ______________________________________________________________________ STEP 4. Enrypting RSA private key with a pass phrase for security The contents of the certificate key file (the generated private key) should be echo kept secret, especially so if it is used to sign Certificates or for User authentication. SSL experts strongly recommend you to encrypt the key file with a Triple-DES cipher and a Pass Phrase. When using LPRng, you provide the password via a file or file descriptor specified by an environent variable, i.e. - SSL_PASSWORD_FILE or SSL_PASSWORD_FD, or in the ${HOME}/.ssl_password file. The LPD server uses the ssl_server_password_file option to specify the location of a file containing the password. See the LPRng Refernce Manual for details, or the printcap(5) man page. key file is /etc/lpd/ssl.ca/signer-02.key Encrypt the private key now? [Y/n]: Fine, you're using an encrypted private key to sign CERTS. ______________________________________________________________________ STEP 5: Combine CERT and KEY file Generate single CERT and KEY file? [Y/n] Use the following commands to examine the CERT and KEY files: openssl x509 -text -in /etc/lpd/ssl.ca/signer-02.crt openssl rsa -text -in /etc/lpd/ssl.ca/signer-02.crt - creates a certificate with the appropriate entries for use as a signing, server (lpd), or client (user) certificate. TESTING SSL AUTHENTICATION Set up a printcap entry: ssl: :auth=ssl :ssl_id=lp :ssl_ca_file=/etc/lpd/ssl.ca/ca.crt :ssl_crl_file=/etc/lpd/ssl.crl/ssl.crl :ssl_server_cert=/etc/lpd/ssl.server/server.crt :ssl_server_password_file=/etc/lpd/ssl.server/server.pwd :sd=/var/spool/lpd/%P :lp=/dev/null # for debugging only! :db=2 Create the spool queue by using: checkpc -f Use the lprng_ssl script described above to create the ssl certs and install them as required. Now restart LPD in debug mode, so you can kill it: lpd -F -D1 Use the 'lpq' command to connect to the server: lpq -Pssl -D1 |&tee /tmp/log If this fails, examine the /var/spool/lpd/ssl/log file for reasons that the server failed. Examine the /tmp/log file for reasons that the client failed. CERTIFICATE REVOCATION AND PERMSSIONS CHECKING The current implementation does not support or provide support for the X509 Certificate Revocation List or files. Instead, we use the lpd.perms facilities and reject user and/or signers based on the information in their 'subject' or 'issuer' information. The AUTHFROM and AUTHCA contain the subject and issuer information for the user certificate received by the LPD server. Actually, the AUTHCA information contains the hierarchy of certificate signers, so you can reject a request based on the presence or abscence of a certificate signer. For example: h110: {230} % openssl x509 -issuer -subject -noout -in ${HOME}/.lpr/client.crt issuer= /C=US/ST=California/L=San Diego/O=Astart/\ OU=CertificateAuthority/CN=AstartCA/Email=ca@astart.com subject= /C=US/ST=California/L=San Diego/O=Astart/\ OU=Server/CN=papowell/Email=papowell@astart.com You can now use: # /etc/lpd.perms REJECT NOT AUTHTYPE=ssl REJECT NOT AUTHCA=*/CN=AstartCA/* REJECT AUTHFROM=*/CN=papowell/* You can also put this in a file, say /etc/lpd/signers.auth */CN=AstartCA/* and, say /etc/lpd/reject.users */CN=papowell/* Now you can use: REJECT NOT AUTHCA= #: src/common/lpc.c:270 src/common/lpc.c:435 src/common/lpq.c:547 msgid "" msgstr "" "Project-Id-Version: LPRng 3.8.28\n" "Report-Msgid-Bugs-To: lprng-devel@lists.sf.net\n" "POT-Creation-Date: 2011-02-03 19:40+0100\n" "PO-Revision-Date: 2000-08-21 18:06-0700\n" "Last-Translator: Patrick Powell \n" "Language-Team: fr \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" #: src/common/accounting.c:134 #, c-format msgid "connection to accounting server '%s' failed '%s'" msgstr "la connexion au serveur de comtabilité '%s' a échoué '%s'" # la table controlword n'est pas traduite volontairement #: src/common/controlword.c:16 msgid "ABORT" msgstr "ABORT" #: src/common/controlword.c:17 msgid "ACTIVE" msgstr "ACTIVE" #: src/common/controlword.c:18 msgid "CLASS" msgstr "CLASS" #: src/common/controlword.c:19 msgid "CLIENT" msgstr "CLIENT" #: src/common/controlword.c:20 msgid "DEBUG" msgstr "DEBUG" #: src/common/controlword.c:21 msgid "DEFAULTQ" msgstr "DEFAULTQ" #: src/common/controlword.c:22 msgid "DISABLE" msgstr "DISABLE" #: src/common/controlword.c:23 msgid "DOWN" msgstr "DOWN" #: src/common/controlword.c:24 msgid "ENABLE" msgstr "ENABLE" #: src/common/controlword.c:25 msgid "HOLD" msgstr "HOLD" #: src/common/controlword.c:26 msgid "HOLDALL" msgstr "HOLDALL" #: src/common/controlword.c:27 msgid "KILL" msgstr "KILL" #: src/common/controlword.c:28 msgid "LPD" msgstr "LPD" #: src/common/controlword.c:29 msgid "LPQ" msgstr "LPQ" #: src/common/controlword.c:30 msgid "LPRM" msgstr "LPRM" #: src/common/controlword.c:31 msgid "MOVE" msgstr "MOVE" #: src/common/controlword.c:32 msgid "MSG" msgstr "MSG" #: src/common/controlword.c:33 msgid "NOHOLDALL" msgstr "NOHOLDALL" #: src/common/controlword.c:34 msgid "PRINTCAP" msgstr "PRINTCAP" #: src/common/controlword.c:35 msgid "REDIRECT" msgstr "REDIRECT" #: src/common/controlword.c:36 msgid "REDO" msgstr "REDO" #: src/common/controlword.c:37 msgid "RELEASE" msgstr "RELEASE" #: src/common/controlword.c:38 msgid "REREAD" msgstr "REREAD" #: src/common/controlword.c:39 msgid "START" msgstr "START" #: src/common/controlword.c:40 msgid "STATUS" msgstr "STATUS" #: src/common/controlword.c:41 msgid "STOP" msgstr "STOP" #: src/common/controlword.c:42 msgid "TOPQ" msgstr "TOPQ" #: src/common/controlword.c:43 msgid "UP" msgstr "UP" #: src/common/controlword.c:44 msgid "SERVER" msgstr "SERVER" #: src/common/controlword.c:45 msgid "DEFAULTS" msgstr "DEFAULTS" #: src/common/controlword.c:46 msgid "FLUSH" msgstr "FLUSH" #: src/common/controlword.c:47 msgid "LANG" msgstr "LANG" #: src/common/controlword.c:48 #, fuzzy msgid "PPD" msgstr "LPD" #: src/common/lpc.c:129 src/common/lpq.c:181 src/common/lpstat.c:147 #: src/common/lpr.c:91 src/common/lprm.c:146 msgid "" "authentication requested (-A option) and AUTH environment variable not set" msgstr "" "authentification demandée (option -A) et variable d'environnement AUTH non " "positionnée" #: src/common/lpc.c:198 msgid "exit" msgstr "exit" #: src/common/lpc.c:242 src/common/lpq.c:237 #, c-format msgid "Printer: %s - cannot get status from device '%s'\n" msgstr "" #: src/common/lpc.c:249 src/common/lpq.c:259 src/common/lprm.c:253 #, c-format msgid "Printer: %s - direct connection to device '%s'\n" msgstr "" #: src/common/lpc.c:267 #, c-format msgid "Locale information directory '%s'\n" msgstr "Répertoire information de localisation '%s'\n" #: src/common/lpc.c:269 src/common/lpc.c:434 src/common/lpq.c:546 #, c-format msgid "LANG environment variable '%s'\n" msgstr "variable d'environnement LANG '%s'\n" #: src/common/lpc.c:272 src/common/lpc.c:437 src/common/lpq.c:549 #, c-format msgid "gettext translation information '%s'\n" msgstr "information de traduction pour gettext '%s'\n" #: src/common/lpc.c:274 src/common/lpc.c:439 src/common/lpq.c:551 msgid "No translation available\n" msgstr "Pas de traduction disponible\n" #: src/common/lpc.c:276 msgid "TRANSLATION TEST" msgstr "FR TRANSLATION TEST" #: src/common/lpc.c:306 src/common/lpc.c:317 src/common/lpc.c:335 msgid "all" msgstr "all" #: src/common/lpc.c:312 src/common/lpc.c:321 msgid "# Printcap Information\n" msgstr "# Information pour Printcap\n" #: src/common/lpc.c:350 #, c-format msgid "execvp failed - '%s'" msgstr "execvp a échoué - '%s'" #: src/common/lpc.c:353 #, c-format msgid "fork failed - '%s'" msgstr "fork a échoué - '%s'" #: src/common/lpc.c:361 #, c-format msgid "doaction: waitpid(%ld) failed" msgstr "doaction: waitpid(%ld) a échoué" #: src/common/lpc.c:452 #, c-format msgid "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke " "LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect " "jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint " "jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release " "jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder " "jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) " "support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n" msgstr "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " sans commande, lecture depuis STDIN\n" " -a - alias pour -Pall\n" " -Ddebuglevel - niveau de debug\n" " -Pprinter - specifie l'imprimante\n" " -P printer[@host] - imprimante sur le hôte\n" " -Shost - connexion au serveur lpd sur l'hôte\n" " -Uuser - identifie la commande comme venant de l'utilisateur\n" " -V - accroissement du nombre de messages explicatifs\n" " commandes:\n" " active (printer[@host]) - test pour un serveur actif\n" " abort (printer[@host] | all) - arrêt du serveur\n" " class printer[@host] (class | off) - montrer/positionner la\n" " classe d'impression\n" " disable (printer[@host] | all) - interdire la mise en file d'attente\n" " debug (printer[@host] | all) debugparms - positionner le niveau de\n" " debug pour l'imprimante\n" " down (printer[@host] | all) - interdire l'impression et la mise en " "file d'attente\n" "enable (printer[@host] | all) - autoriser la mise en file d'attente\n" " flush (printer[@host] | all) - vider les status du cache\n" " hold (printer[@host] | all) (name[@host] | job | all)* - retenir le " "travail\n" " holdall (printer[@host] | all) - retenir tous les travaux\n" " kill (printer[@host] | all) - arreter et redémarrer le serveur\n" " lpd (printer[@host]) - obtenir le PID de LPD \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoquer LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoquer " "LPRM\n" " msg printer message text - positionner le message de status\n" " move printer (user|jobid)* target - déplacer les travaux vers une nouvelle " "file d'attente\n" " noholdall (printer[@host] | all) - ne plus retenir les travaux\n" " printcap (printer[@host] | all) - rapporter les valeur de printcap\n" " quit - sortie de LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - rediriger " "les travaux\n" " redo (printer[@host] | all) (name[@host] | job | all)* - refaire le " "travail\n" " release (printer[@host] | all) (name[@host] | job | all)* - relacher le " "travail\n" " reread (printer[@host]) - LPD relire la base de données " "d'information\n" " start (printer[@host] | all) - démarrer l'impression\n" " status (printer[@host] | all) - état des imprimantes\n" " stop (printer[@host] | all) - arrêt de l'impression\n" " topq (printer[@host] | all) (name[@host] | job | all)* - relancer le " "travail\n" " up (printer[@host] | all) - autoriser l'impression et la mise en " "file d'attente\n" " defaultq - montrer la file d'attente par défaut du " "serveur LPD\n" " defaults - montrer les valeurs par défaut de la " "configuration\n" " lang - montrer le support courant de i18n " "(iNTERNATIONALISATIONn)\n" " client (printer | all) - information sur la configuration client et " "printcap\n" " server (printer | all) - information sur la configuration du serveur " "et printcap\n" #: src/common/lpd.c:178 msgid "No LPD lockfile specified!" msgstr "Pas de fichier de blocage LPD spécifié!" #: src/common/lpd.c:189 src/common/lpd.c:202 #, fuzzy, c-format msgid "Another print spooler active, possibly lpd process '%ld'" msgstr "" "Un autre spouleur d'impression utilise le port TCP imprimante, peut-être le " "process lpd '%ld'" #: src/common/lpd.c:194 #, fuzzy, c-format msgid "cannot open or lock lockfile - %s" msgstr "ne peut mettre à jour le fichier retenu '%s'" #: src/common/lpd.c:267 msgid "lpd: main() dofork failed" msgstr "lpd: main() dofork a échoué" #: src/common/lpd.c:312 src/common/lpd.c:323 msgid "lpd: pipe call failed" msgstr "lpd: pipe call a échoué" #: src/common/lpd.c:330 msgid "lpd: cannot start initial logger process" msgstr "" #: src/common/lpd.c:683 msgid "lpd: select error!" msgstr "lpd: select erreur!" #: src/common/lpd.c:710 msgid "lpd: Lpd_request pipe EOF! cannot happen" msgstr "lpd: Lpd_request pipe EOF! ne doit pas arriver" #: src/common/lpd.c:735 src/common/lpd.c:738 msgid "Setup_log: open /dev/null failed" msgstr "Setup_log: open /dev/null a échoué" #: src/common/lpd.c:745 src/common/lpd.c:749 #, c-format msgid "Setup_log: dup2(%d,%d) failed" msgstr "Setup_log: dup2(%d,%d) a échoué" #: src/common/lpd.c:754 #, c-format msgid "Setup_log: open %s failed" msgstr "Setup_log: open %s a échoué" #: src/common/lpd.c:792 msgid "lpd: Cannot truncate lock file" msgstr "" #: src/common/lpd.c:810 #, fuzzy, c-format msgid "lpd: Cannot open lock file '%s'" msgstr "lpd: ne peut ouvrir '%s'" #: src/common/lpd.c:912 #, fuzzy, c-format msgid "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" msgstr "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "Options\n" " -D dbg - positionner le niveau de debug et les drapeaux\n" " -F - exécution en avant-plan, enregistrement sur STDERR\n" " -L logfile - ajouter l'enregistrement d'information dans logfile\n" " -V - montrer les informations de version\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" #: src/common/lpd.c:1001 msgid "lpd: fork() failed" msgstr "lpd: fork() a échoué" #: src/common/lpd.c:1012 #, fuzzy msgid "lpd: accept on listening socket failed" msgstr "Service_connection: accept sur un connecteur en écoute a échoué" #: src/common/lpd.c:1031 msgid "Start_all: pipe failed!" msgstr "Start_all: pipe a échoué!" #: src/common/lpd_control.c:87 #, c-format msgid "bad control command '%s'" msgstr "mauvaise commande de contrôle '%s'" #: src/common/lpd_control.c:102 #, c-format msgid "printer '%s' has illegal char at '%s' in name" msgstr "l'imprimante '%s' a un caractère illégal '%s' dans le nom" #: src/common/lpd_control.c:114 #, c-format msgid "%s: unknown control request '%s'" msgstr "%s: demande de contrôle inconnue '%s'" #: src/common/lpd_control.c:195 #, fuzzy msgid "Use: move printer (user|jobid)* target" msgstr "Use: OP_MOVE printer (user|jobid)* target" #: src/common/lpd_control.c:206 msgid "no permission to control server" msgstr "pas d'autorisation pour contrôler le serveur" #: src/common/lpd_control.c:460 msgid "not implemented yet" msgstr "pas encore implémenté" #: src/common/lpd_control.c:486 #, fuzzy, c-format msgid "server process PID %ld exited\n" msgstr "tuer le serveur de PID %ld avec %s\n" #: src/common/lpd_control.c:489 #, fuzzy, c-format msgid "kill server process PID %ld with %s\n" msgstr "tuer le serveur de PID %ld avec %s\n" #: src/common/lpd_control.c:497 msgid "enabled and started" msgstr "armé et démarré" #: src/common/lpd_control.c:498 msgid "disabled and stopped" msgstr "désarmé et arrété" #: src/common/lpd_control.c:499 msgid "stopped" msgstr "arrété" #: src/common/lpd_control.c:501 msgid "started" msgstr "démarré" #: src/common/lpd_control.c:502 msgid "disabled" msgstr "désarmé" #: src/common/lpd_control.c:503 msgid "enabled" msgstr "armé" #: src/common/lpd_control.c:504 msgid "redirected" msgstr "redirigé" #: src/common/lpd_control.c:505 msgid "holdall on" msgstr "retenir tous oui" #: src/common/lpd_control.c:506 msgid "holdall off" msgstr "retenir tous non" #: src/common/lpd_control.c:507 msgid "move done" msgstr "déplacé fait" #: src/common/lpd_control.c:508 msgid "class updated" msgstr "classe mise à jour" #: src/common/lpd_control.c:509 msgid "killed job" msgstr "travail tué" #: src/common/lpd_control.c:510 msgid "aborted job" msgstr "travail avorté" #: src/common/lpd_control.c:511 msgid "flushed status" msgstr "état vidé" #: src/common/lpd_control.c:531 #, c-format msgid "" "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n" msgstr "" #: src/common/lpd_control.c:565 #, c-format msgid "Do_queue_control: write to fd '%d' failed" msgstr "Do_queue_control: écriture sur '%d' a échoué" #: src/common/lpd_control.c:654 #, c-format msgid "%s: no permission '%s'\n" msgstr "%s: pas l'autorisation '%s'\n" #: src/common/lpd_control.c:738 #, c-format msgid "%s: selected '%s'\n" msgstr "%s: selectionné '%s'\n" #: src/common/lpd_control.c:748 #, c-format msgid "%s: cannot set hold file '%s'\n" msgstr "%s: ne peut positionner le fichier retenu '%s'\n" #: src/common/lpd_control.c:855 msgid " holdall" msgstr " retenir tous" #: src/common/lpd_control.c:859 #, c-format msgid " class=%s" msgstr " classe=%s" #: src/common/lpd_control.c:863 msgid " autohold" msgstr " retenue automatique" #: src/common/lpd_control.c:935 src/common/lpd_control.c:990 #: src/common/lpd_control.c:1045 #, c-format msgid "wrong number arguments, %d" msgstr "mauvais nombre d'arguments, %d" #: src/common/lpd_control.c:941 #, c-format msgid "forwarding to '%s'\n" msgstr "renvoyé à '%s'\n" #: src/common/lpd_control.c:943 msgid "forwarding off\n" msgstr "renvoi non\n" #: src/common/lpd_control.c:997 #, c-format msgid "classes printed '%s'\n" msgstr "classes imprimées '%s'\n" #: src/common/lpd_control.c:1000 msgid "all classes printed\n" msgstr "toutes les classes imprimées\n" #: src/common/lpd_control.c:1051 #, c-format msgid "debugging override set to '%s'" msgstr "niveau de debug surchargé positonné à '%s'" #: src/common/lpd_control.c:1053 msgid "debugging override off" msgstr "niveau de debug surchargé non" #: src/common/lpd_jobs.c:435 #, c-format msgid "Do_queue_jobs: cannot open lockfile '%s'" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%s'" #: src/common/lpd_jobs.c:767 src/common/lpd_jobs.c:787 #: src/common/lpd_jobs.c:2360 #, fuzzy, c-format msgid "cannot update job ticket file for '%s'" msgstr "ne peut mettre à jour le fichier retenu pour '%s'" #: src/common/lpd_jobs.c:770 src/common/lpd_jobs.c:790 #, fuzzy, c-format msgid "Do_queue_jobs: cannot update job ticket file for '%s'" msgstr "Do_queue_jobs: ne peut mettre à jour le fichier retenu pour '%s'" #: src/common/lpd_jobs.c:774 src/common/lpd_jobs.c:794 #, c-format msgid "removing job '%s' - no permissions" msgstr "enlever le travail '%s' - pas d'autorisations" #: src/common/lpd_jobs.c:1063 #, fuzzy, c-format msgid "Do_queue_jobs: LOGIC ERROR - no identifer '%s'" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%s'" #: src/common/lpd_jobs.c:1072 #, fuzzy, c-format msgid "Do_queue_jobs: FORWARDING LOOP - '%s'" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%s'" #: src/common/lpd_jobs.c:1096 #, fuzzy, c-format msgid "cannot update job ticket file '%s'" msgstr "ne peut mettre à jour le fichier retenu '%s'" #: src/common/lpd_jobs.c:1098 #, fuzzy, c-format msgid "Do_queue_jobs: cannot update job ticket file '%s'" msgstr "Do_queue_jobs: ne peut mettre à jour le fichier retenu '%s'" #: src/common/lpd_jobs.c:1147 #, fuzzy, c-format msgid "Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%d'" #: src/common/lpd_jobs.c:1163 src/common/lpd_jobs.c:1227 msgid "sleeping, waiting for processes to exit" msgstr "sleeping, attente de l'arrêt des processus" #: src/common/lpd_jobs.c:1204 #, fuzzy, c-format msgid "Do_queue_jobs: write to fd '%d' failed" msgstr "Do_queue_control: écriture sur '%d' a échoué" #: src/common/lpd_jobs.c:1403 #, c-format msgid "Remote_job: %d datafiles and only allowed %d" msgstr "Remote_job: %d seuls les fichiers de données aont autorisés %d" #: src/common/lpd_jobs.c:1447 #, c-format msgid "link failure while sending job '%s'" msgstr "échec du lien lors de l'envoi du travail'%s'" #: src/common/lpd_jobs.c:1453 #, c-format msgid "no permission to spool job '%s'" msgstr "pas d'autorisation pour spoulé le travail '%s'" #: src/common/lpd_jobs.c:1459 #, c-format msgid "failed to send job '%s'" msgstr "échec de l'envoi du travail '%s'" #: src/common/lpd_jobs.c:1627 msgid "Fork_subserver: fork failed" msgstr "Fork_subserver: fork a échoué" #: src/common/lpd_jobs.c:1701 #, c-format msgid "subserver pid %ld exit status '%s'" msgstr "sous-serveur pid %ld état de sortie '%s'" #: src/common/lpd_jobs.c:1705 #, c-format msgid "subserver pid %ld died with signal '%s'" msgstr "sous-serveur pid %ld tué avec le signal '%s'" #: src/common/lpd_jobs.c:1751 msgid "Wait_for_subserver: Mergesort failed" msgstr "Wait_for_subserver: Mergesort a échoué" #: src/common/lpd_jobs.c:1762 #, fuzzy, c-format msgid "Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed" msgstr "Wait_for_subserver: Mergesort a échoué" #: src/common/lpd_jobs.c:1787 msgid "succ" msgstr "succ" #: src/common/lpd_jobs.c:1788 msgid "jsucc" msgstr "jsucc" #: src/common/lpd_jobs.c:1789 msgid "success" msgstr "success" #: src/common/lpd_jobs.c:1790 msgid "jsuccess" msgstr "jsuccess" #: src/common/lpd_jobs.c:1791 msgid "abort" msgstr "abort" #: src/common/lpd_jobs.c:1792 msgid "jabort" msgstr "jabort" #: src/common/lpd_jobs.c:1793 msgid "hold" msgstr "hold" #: src/common/lpd_jobs.c:1794 msgid "jhold" msgstr "jhold" #: src/common/lpd_jobs.c:1795 msgid "remove" msgstr "remove" #: src/common/lpd_jobs.c:1796 msgid "jremove" msgstr "jremove" #: src/common/lpd_jobs.c:1975 #, c-format msgid "Update_status: no identifier for '%s'" msgstr "" #: src/common/lpd_jobs.c:2008 src/common/lpd_jobs.c:2115 #: src/common/lpd_jobs.c:2157 src/common/lpd_jobs.c:2201 #, c-format msgid "job '%s' saved" msgstr "travail '%s' sauvé" #: src/common/lpd_jobs.c:2013 src/common/lpd_jobs.c:2121 #: src/common/lpd_jobs.c:2163 src/common/lpd_jobs.c:2207 #, c-format msgid "could not remove job '%s'" msgstr "ne peut enlever le travail '%s'" #: src/common/lpd_jobs.c:2015 src/common/lpd_jobs.c:2123 #: src/common/lpd_jobs.c:2165 src/common/lpd_jobs.c:2209 #, c-format msgid "job '%s' removed" msgstr "travail '%s' enlevé" #: src/common/lpd_jobs.c:2045 #, c-format msgid "job '%s', attempt %d, allowed %d" msgstr "travail '%s', essai %d, autorisé %d" #: src/common/lpd_jobs.c:2049 msgid "treating as successful" msgstr "traité comme un succès" #: src/common/lpd_jobs.c:2050 msgid "retrying job" msgstr "reessai du travail" #: src/common/lpd_jobs.c:2051 msgid "no retry" msgstr "pas de reessai" #: src/common/lpd_jobs.c:2052 msgid "aborting server" msgstr "serveur avorté" #: src/common/lpd_jobs.c:2053 msgid "removing job - status JREMOVE" msgstr "travail enlevé - état JREMOVE" #: src/common/lpd_jobs.c:2054 msgid "holding job" msgstr "travail retenu" #: src/common/lpd_jobs.c:2057 #, c-format msgid "unexpected status 0x%x" msgstr "état inattendu 0x%x" #: src/common/lpd_jobs.c:2062 #, c-format msgid "job '%s', %s" msgstr "travail '%s', %s" #: src/common/lpd_jobs.c:2066 #, c-format msgid "job '%s' attempt %d, trying %d times" msgstr "travail '%s' tentative %d, essayé %d fois" #: src/common/lpd_jobs.c:2069 #, fuzzy, c-format msgid "job '%s' attempt %d, trying indefinitely" msgstr "travail '%s' tentative %d, essayé indéfiniment" #: src/common/lpd_jobs.c:2088 msgid "failed, no retry" msgstr "échec, pas de réessai" #: src/common/lpd_jobs.c:2119 #, fuzzy, c-format msgid "removing job '%s' - JFAILNORETRY" msgstr "élimination du travail '%s' - ABORT" #: src/common/lpd_jobs.c:2131 msgid "aborting operations" msgstr "avortement des opérations" #: src/common/lpd_jobs.c:2161 #, fuzzy, c-format msgid "removing job '%s' - JABORT" msgstr "élimination du travail '%s' - ABORT" #: src/common/lpd_jobs.c:2170 msgid "stopping printing on filter JABORT exit code" msgstr "arrêt du filtre d'impression, code d'arrêt JABORT" #: src/common/lpd_jobs.c:2180 msgid "removing destination due to errors" msgstr "élimination de la destination due à des erreurs" #: src/common/lpd_jobs.c:2191 msgid "too many errors" msgstr "" #: src/common/lpd_jobs.c:2205 #, c-format msgid "removing job '%s' - JREMOVE" msgstr "élimination du travail '%s' - JREMOVE" #: src/common/lpd_jobs.c:2334 #, c-format msgid "Service_worker: cannot open lockfile '%s'" msgstr "Service_worker: ne peut ouvrir le fichier de blocage '%s'" #: src/common/lpd_jobs.c:2363 #, fuzzy, c-format msgid "Service_worker: cannot update job ticket file for '%s'" msgstr "Service_worker: ne peut mettre à jour le fichier reteniu pour '%s'" #: src/common/lpd_jobs.c:2371 #, fuzzy, c-format msgid "Service_worker: no identifier for '%s'" msgstr "Service_worker: ne peut mettre à jour le fichier reteniu pour '%s'" #: src/common/lpd_jobs.c:2757 #, fuzzy, c-format msgid "job '%s' removed- status expired" msgstr "travail '%s' enlevé" #: src/common/lpd_rcvjob.c:139 src/common/lpd_rcvjob.c:559 msgid "bad command line" msgstr "mauvaise ligne de commande" #: src/common/lpd_rcvjob.c:143 src/common/lpd_rcvjob.c:563 msgid "bad printer name" msgstr "mauvais nom d'imprimante" #: src/common/lpd_rcvjob.c:151 #, c-format msgid "%s: cannot set up print queue" msgstr "%s: ne peut initialiser la file d'impression" #: src/common/lpd_rcvjob.c:187 src/common/lpd_rcvjob.c:602 #: src/common/lpd_secure.c:188 #, c-format msgid "%s: spooling disabled" msgstr "%s: spoulage désarmé" #: src/common/lpd_rcvjob.c:198 #, c-format msgid "%s: Receive_job: sending ACK 0 failed" msgstr "%s: Receive_job: envoi de ACK 0 a échoué" #: src/common/lpd_rcvjob.c:210 #, fuzzy, c-format msgid "Receive_job: cannot open lockfile '%s'" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%s'" #: src/common/lpd_rcvjob.c:215 #, fuzzy, c-format msgid "Receive_job: cannot lock lockfile '%s'" msgstr "Do_queue_jobs: ne peut ouvrir fichier de blocage '%s'" #: src/common/lpd_rcvjob.c:254 msgid "Recovering from incorrect job submission" msgstr "" #: src/common/lpd_rcvjob.c:268 #, c-format msgid "%s: Receive_job - bad control line '%s', len %0.0f, name '%s'" msgstr "" "%s: Receive_job - mauvaise ligne de commande '%s', len %0.0f, name '%s'" #: src/common/lpd_rcvjob.c:289 src/common/lpd_rcvjob.c:366 #: src/common/lpd_rcvjob.c:403 src/common/lpd_rcvjob.c:454 #: src/common/lpd_rcvjob.c:617 src/common/lpd_rcvjob.c:799 #: src/common/lpd_rcvjob.c:846 src/common/lpd_rcvjob.c:881 #: src/common/lpd_rcvjob.c:917 #, c-format msgid "size %0.3fK exceeds %dK" msgstr "" #: src/common/lpd_rcvjob.c:296 src/common/lpd_rcvjob.c:624 #: src/common/lpd_secure.c:202 #, c-format msgid "%s: insufficient file space" msgstr "%s: espace de fichier insuffisant" #: src/common/lpd_rcvjob.c:311 src/common/lpd_rcvjob.c:676 #, c-format msgid "%s: sending ACK 0 for '%s' failed" msgstr "%s: envoi de ACK 0 pour '%s' a échoué" #: src/common/lpd_rcvjob.c:345 src/common/lpd_rcvjob.c:649 #, c-format msgid "%s: transfer of '%s' from '%s' failed" msgstr "%s: transfert de '%s' depuis '%s' a échoué" #: src/common/lpd_rcvjob.c:375 src/common/lpd_rcvjob.c:412 #: src/common/lpd_rcvjob.c:463 src/common/lpd_rcvjob.c:854 #: src/common/lpd_rcvjob.c:890 src/common/lpd_rcvjob.c:926 #: src/common/lpd_rcvjob.c:1337 src/common/lpd_rcvjob.c:1413 #, c-format msgid "Error setting up job ticket file - %s" msgstr "" #: src/common/lpd_rcvjob.c:505 #, fuzzy, c-format msgid "Receive_jobs: write to fd '%d' failed" msgstr "Do_queue_control: écriture sur '%d' a échoué" #: src/common/lpd_rcvjob.c:570 #, c-format msgid "%s: cannot set up printer" msgstr "%s: ne peut initialiser l'imprimante" #: src/common/lpd_rcvjob.c:638 #, c-format msgid "%s: Receive_block_job: sending ACK 0 failed" msgstr "%s: Receive_block_job: envoi ACK 0 a échoué" #: src/common/lpd_rcvjob.c:659 #, c-format msgid "Receive_block_job: lseek failed '%s'" msgstr "Receive_block_job: lseek a échoué '%s'" #: src/common/lpd_rcvjob.c:706 #, fuzzy, c-format msgid "Receive_block_jobs: write to fd '%d' failed" msgstr "Do_queue_control: écriture sur '%d' a échoué" #: src/common/lpd_rcvjob.c:772 src/common/lpd_rcvjob.c:831 #, c-format msgid "Scan_block_file: lseek failed '%s'" msgstr "Scan_block_file: lseek a échoué '%s'" #: src/common/lpd_rcvjob.c:787 #, c-format msgid "bad length information '%s'" msgstr "mauvaise longueur d'information '%s'" #: src/common/lpd_rcvjob.c:819 #, c-format msgid "Scan_block_file: read failed '%s'" msgstr "Scan_block_file: read a échoué '%s'" #: src/common/lpd_rcvjob.c:824 msgid "Scan_block_file: read unexecpted EOF" msgstr "Scan_block_file: read EOF intempestif" #: src/common/lpd_rcvjob.c:1017 #, c-format msgid "%s: no permission to print" msgstr "%s: pas d'autorisation pour imprimer" #: src/common/lpd_rcvjob.c:1500 src/common/lpd_rcvjob.c:1525 #, fuzzy, c-format msgid "Do_incoming_control_filter: lseek failed '%s'" msgstr "Scan_block_file: lseek a échoué '%s'" #: src/common/lpd_rcvjob.c:1613 #, fuzzy, c-format msgid "Get_route: lseek failed '%s'" msgstr "Scan_block_file: lseek a échoué '%s'" #: src/common/lpd_remove.c:73 msgid "missing user or printer name" msgstr "manque le nom d'utilisateur ou d'imprimante" #: src/common/lpd_remove.c:81 src/common/lpd_status.c:175 #, c-format msgid "printer '%s' has illegal character at '%s' in name" msgstr "l'imprimante '%s' a un caractère illégal a '%s' dans le nom" #: src/common/lpd_remove.c:110 #, c-format msgid "Job_remove: error '%s'" msgstr "Job_remove: erreur '%s'" #: src/common/lpd_remove.c:203 #, c-format msgid "Printer %s@%s:\n" msgstr "Imprimante %s@%s:\n" #: src/common/lpd_remove.c:232 #, c-format msgid " checking perms '%s'\n" msgstr " vérification des autorisations '%s'\n" #: src/common/lpd_remove.c:249 #, c-format msgid " no permissions '%s'\n" msgstr " pas d'autorisations '%s'\n" #: src/common/lpd_remove.c:263 #, fuzzy, c-format msgid " removing incoming job '%s'\n" msgstr "élimination du travail '%s' - ABORT" #: src/common/lpd_remove.c:266 #, c-format msgid " dequeued '%s'\n" msgstr " enlevé de la file d'attente '%s'\n" #: src/common/lpd_remove.c:275 #, c-format msgid "error: could not remove '%s'" msgstr "erreur: ne peut enlever '%s'" #: src/common/lpd_remove.c:384 msgid " ERROR: " msgstr " ERREUR: " #: src/common/lpd_secure.c:81 #, c-format msgid "bad command line '%s'" msgstr "mauvaise ligne de commande '%s'" #: src/common/lpd_secure.c:113 #, c-format msgid "bad printer name '%s'" msgstr "mauvais nom d'imprimante '%s'" #: src/common/lpd_secure.c:124 #, c-format msgid "bad printer '%s'" msgstr "mauvaise imprimante '%s'" #: src/common/lpd_secure.c:166 #, c-format msgid "unsupported authentication '%s'" msgstr "authentification non supportée '%s'" #: src/common/lpd_secure.c:173 #, c-format msgid "no receive method supported for '%s'" msgstr "pas de méthode de réception supportée pour '%s'" #: src/common/lpd_secure.c:195 #, c-format msgid "%s: job size %0.0f is larger than %d K" msgstr "%s: taille du travail %0.0f plus grande que %d K" #: src/common/lpd_status.c:357 #, c-format msgid "%s: no permission to show status" msgstr "%s: pas d'autorisation pour montrer l'état" #: src/common/lpd_status.c:476 #, fuzzy, c-format msgid " (originally %s)" msgstr "(originellment %s) " #: src/common/lpd_status.c:486 msgid "" "\n" " Error: " msgstr "" "\n" " Erreur: " #: src/common/lpd_status.c:491 #, c-format msgid " - %s" msgstr " - %s" #: src/common/lpd_status.c:494 #, c-format msgid " - printer %s@%s not in printcap" msgstr " - printer %s@%s pas dans printcap" #: src/common/lpd_status.c:498 #, c-format msgid " - printer %s@%s has bad printcap entry" msgstr " - printer %s@%s a une entrée incorrecte dans printcap" #: src/common/lpd_status.c:724 #, c-format msgid " " msgstr " " #: src/common/lpd_status.c:736 #, c-format msgid " Job: %s" msgstr " Travail: %s" #: src/common/lpd_status.c:737 #, c-format msgid "%s status= %s" msgstr "%s état= %s" #: src/common/lpd_status.c:740 #, fuzzy, c-format msgid "%s size= %0.0f" msgstr "%s taille= %0.0f" #: src/common/lpd_status.c:743 #, c-format msgid "%s time= %s" msgstr "%s heure= %s" #: src/common/lpd_status.c:747 #, c-format msgid "%s error= %s" msgstr "%s erreur= %s" #: src/common/lpd_status.c:752 #, c-format msgid "%s CONTROL=" msgstr "%s CONTROL=" #: src/common/lpd_status.c:758 #, c-format msgid "%s HOLDFILE=" msgstr "%s HOLDFILE=" #: src/common/lpd_status.c:778 #, fuzzy, c-format msgid " %d job" msgid_plural " %d jobs" msgstr[0] " %d travail" msgstr[1] " %d travail" #: src/common/lpd_status.c:782 #, c-format msgid " (%d held)" msgstr "" #: src/common/lpd_status.c:787 #, c-format msgid " (%d move)" msgstr "" #: src/common/lpd_status.c:810 #, c-format msgid " Comment: %s" msgstr " Commentaire: %s" #: src/common/lpd_status.c:821 #, c-format msgid "" "\n" " Printing: %s\n" " Aborted: %s\n" " Spooling: %s" msgstr "" "\n" " Impression: %s\n" " Avortement: %s\n" " Spoulage: %s" #: src/common/lpd_status.c:867 #, c-format msgid "" "\n" " %s: " msgstr "" "\n" " %s: " #: src/common/lpd_status.c:875 #, c-format msgid " (%s" msgstr " (%s" #: src/common/lpd_status.c:890 #, c-format msgid "" "\n" " Redirected_to: %s" msgstr "" "\n" " Redirected_to: %s" #: src/common/lpd_status.c:893 #, c-format msgid " (redirect %s)" msgstr " (redirigé %s)" #: src/common/lpd_status.c:903 #, c-format msgid " (dest %s@%s)" msgstr " (destination %s@%s)" #: src/common/lpd_status.c:910 #, c-format msgid "" "\n" " Serving: %s" msgstr "" "\n" " Servant: %s" #: src/common/lpd_status.c:913 #, c-format msgid " (serving %s)" msgstr " (servant %s)" #: src/common/lpd_status.c:920 #, c-format msgid "" "\n" " Classes: %s" msgstr "" "\n" " Classes: %s" #: src/common/lpd_status.c:923 #, c-format msgid " (classes %s)" msgstr " (classes %s)" #: src/common/lpd_status.c:930 msgid "" "\n" " Hold_all: on" msgstr "" "\n" " Hold_all: oui" #: src/common/lpd_status.c:933 msgid " (holdall)" msgstr " (tous retenus)" #: src/common/lpd_status.c:940 msgid "" "\n" " Auto_hold: on" msgstr "" "\n" " Auto_hold: oui" #: src/common/lpd_status.c:943 msgid " (autohold)" msgstr " (retenue automatique)" #: src/common/lpd_status.c:951 #, c-format msgid "" "\n" " Message: %s" msgstr "" "\n" " Message: %s" #: src/common/lpd_status.c:954 #, c-format msgid " (message: %s)" msgstr " (message: %s)" #: src/common/lpd_status.c:983 msgid " Queue: no printable jobs in queue\n" msgstr " Queue: pas de travail imprimable dans la file d'attente\n" #: src/common/lpd_status.c:987 #, fuzzy, c-format msgid " Queue: %d printable job\n" msgid_plural " Queue: %d printable jobs\n" msgstr[0] " Queue: %d travail imprimable\n" msgstr[1] " Queue: %d travail imprimable\n" #: src/common/lpd_status.c:994 #, c-format msgid " Holding: %d held jobs in queue\n" msgstr " Holding: %d travaux retenus dans la file d'attente\n" #: src/common/lpd_status.c:1000 msgid " Server: no server active" msgstr " Server: pas de serveur actif" #: src/common/lpd_status.c:1003 #, c-format msgid " Server: pid %d active" msgstr " Server: pid %d actif" #: src/common/lpd_status.c:1011 #, c-format msgid " Unspooler: pid %d active" msgstr " Unspooler: pid %d actif" #: src/common/lpd_status.c:1023 #, c-format msgid "%s SPOOLCONTROL=\n" msgstr "%s SPOOLCONTROL=\n" #: src/common/lpd_status.c:1037 msgid " Status: " msgstr " Status: " #: src/common/lpd_status.c:1041 msgid " Filter_status: " msgstr " Filter_status: " #: src/common/lpd_dispatch.c:39 #, fuzzy, c-format msgid "Dispatch_input: bad request line '%s' from %s" msgstr "Dispatch_input: mauvaise ligne '%s' demandée %s" #: src/common/lpd_dispatch.c:177 msgid "Service_connection: getpeername failed" msgstr "Service_connection: getpeername a échoué" #: src/common/lpd_dispatch.c:224 #, fuzzy msgid "Service_connection: BAD LocalHost_IP value" msgstr "Service_connection: ne peut demander à lire" #: src/common/lpd_dispatch.c:230 #, c-format msgid "Service_connection: bad protocol family '%d'" msgstr "Service_connection: mauvaise famille '%d' de protocole" #: src/common/lpd_dispatch.c:261 #, fuzzy msgid "no connect permissions" msgstr "pas d'autorisations de connexion" #: src/common/lpd_dispatch.c:284 #, c-format msgid "Service_connection: peek of length %d failed" msgstr "" #: src/common/lpd_dispatch.c:326 #, c-format msgid "Service_connection: cannot read request from %s in %d seconds" msgstr "" #: src/common/lpd_dispatch.c:330 #, c-format msgid "Service_connection: short request line '%s', from '%s'" msgstr "" #: src/common/lpq.c:119 #, fuzzy, c-format msgid "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n" msgstr "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - utiliser l'authentification spécifiée par la variable\n" " d'environnement AUTH\n" " -a - toutes les imprimantes\n" " -c - effacer l'écran avant mise à jour\n" " -l - augmenter (plus long) le détail des informations d'état\n" " drapeau(x) l additionnel(s) ajout de plus de détail.\n" " -L - maximum de détail pour les informations d'état\n" " -Ddebuglevel - debug level\n" " -n linecount - linecount lignes d'information détaillées d'état\n" " -Pprinter - specifie l'imprimante\n" " -s - format court (sommaire)\n" " -tsleeptime - temps de sommeil entre mises à jour\n" " -V - imprimer des information de version\n" " -v - print in key: value format\n" #: src/common/lpq.c:245 #, c-format msgid "Printer: %s is %s@%s\n" msgstr "Printer: %s est %s@%s\n" #: src/common/lpq.c:252 #, c-format msgid "Printer: %s - cannot use printer, not in privileged group\n" msgstr "" "Printer: %s - ne peut utiliser l'imprimante, pas dans un groupe privilégié\n" #: src/common/lpq.c:369 src/common/lpq.c:374 src/common/lpq.c:384 #: src/common/lpq.c:431 src/common/lpq.c:438 msgid "Printer:" msgstr "Printer:" #: src/common/lpq.c:477 msgid "fork() failed" msgstr "fork() a échoué" #: src/common/lpq.c:484 #, c-format msgid "Term_clear: waitpid(%d) failed" msgstr "Term_clear: waitpid(%d) a échoué" #: src/common/lpq.c:510 msgid "lpq: please use the LPRng lpstat program\n" msgstr "lpq: veuillez utiliser le programme LPRng lpstat\n" #: src/common/lpstat.c:195 msgid "scheduler is running\n" msgstr "" #: src/common/lpstat.c:199 msgid "no system default destination\n" msgstr "" #: src/common/lpstat.c:201 #, c-format msgid "system default destination: %s\n" msgstr "" #: src/common/lpstat.c:208 #, c-format msgid "system for %s: %s\n" msgstr "" #: src/common/lpstat.c:250 #, fuzzy, c-format msgid " Printer: %s - cannot use printer, not in privileged group\n" msgstr "" "Printer: %s - ne peut utiliser l'imprimante, pas dans un groupe privilégié\n" #: src/common/lpstat.c:259 #, c-format msgid " Printer: %s - direct connection to device '%s'\n" msgstr "" #: src/common/lpstat.c:387 #, c-format msgid "" "%s not accepting requests since %s -\n" "\tunknown reason\n" msgstr "" #: src/common/lpstat.c:389 #, c-format msgid "%s accepting requests since %s\n" msgstr "" #: src/common/lpstat.c:397 #, c-format msgid "printer %s unknown state. disabled since %s. available\n" msgstr "" #: src/common/lpstat.c:398 #, c-format msgid "printer %s unknown state. enabled since %s. available\n" msgstr "" #: src/common/lpstat.c:404 #, c-format msgid "\tDescription: %s@%s\n" msgstr "" #: src/common/lpr.c:157 msgid "nothing to print" msgstr "rien à imprimer" #: src/common/lpr.c:162 msgid "cannot use printer - not in privileged group\n" msgstr "ne peut utiliser l'imprimante - pas dans le groupe privilégié\n" #: src/common/lpr.c:168 #, c-format msgid "no remote support for %s@%s" msgstr "pas de support distant pour %s@%s" #: src/common/lpr.c:179 #, c-format msgid "%d data files and maximum allowed %d" msgstr "%d fichiers de données et maximum autorisé %d" #: src/common/lpr.c:221 src/common/lpr.c:1164 #, c-format msgid "Cannot open file '%s', %s" msgstr "Ne peut ouvrir le fichier '%s', %s" #: src/common/lpr.c:232 msgid "(lpr_filter)" msgstr "(lpr_filter)" #: src/common/lpr.c:295 src/common/lpr.c:332 #, fuzzy, c-format msgid "Status Information, attempt %d:\n" msgstr "" "Information d'Etat:\n" " " #: src/common/lpr.c:299 src/common/lpr.c:336 #, fuzzy, c-format msgid " of %d:\n" msgstr "Fait %d\n" #: src/common/lpr.c:312 #, fuzzy, c-format msgid "Waiting %d seconds before retry\n" msgstr "mise en veille %d secondes avant re-essai, debut de veille" #: src/common/lpr.c:351 #, c-format msgid "request id is %s\n" msgstr "id demandé est %s\n" #: src/common/lpr.c:354 #, c-format msgid "request id is %d\n" msgstr "id demandé est %d\n" #: src/common/lpr.c:366 #, c-format msgid "Error unlinking '%s' - %s" msgstr "Erreur en déliant '%s' - %s" #: src/common/lpr.c:374 #, c-format msgid "Done %d\n" msgstr "Fait %d\n" #: src/common/lpr.c:430 src/common/lpr.c:603 msgid "USER environment variable undefined" msgstr "variable d'environnement USER non définie" #: src/common/lpr.c:448 msgid "-ncopies -number of copies must be greater than 0\n" msgstr "-ncopies - nombre de copies doit être supérieur à 0\n" #: src/common/lpr.c:452 msgid "nobanner" msgstr "pas de bannière" #: src/common/lpr.c:455 msgid "width" msgstr "largeur" #: src/common/lpr.c:530 #, c-format msgid "bad -F format string '%s'\n" msgstr "mauvaise chîne de format -F '%s'\n" #: src/common/lpr.c:533 #, c-format msgid "duplicate format specification -F%s\n" msgstr "spécification de format dupliquée -F%s\n" #: src/common/lpr.c:545 msgid "-Kcopies -number of copies must be greater than 0\n" msgstr "-Kcopies - nombre de copies doit être supérieur à 0\n" #: src/common/lpr.c:608 msgid "Missing mail name" msgstr "Manque nom de boîte à lettre" #: src/common/lpr.c:622 #, c-format msgid "duplicate format specification -%c\n" msgstr "spécification de format dupliquée -%c\n" #: src/common/lpr.c:666 #, fuzzy, c-format msgid "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default " "printer.\n" msgstr "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o option] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " simulation de lp avec LPRng, les fonctionalités peuvent différer " "légèrement\n" " -A - utiliser l'authentification spécifiée par la variable " "d'environnement AUTH\n" " -B - filtrer le travail avant envoi\n" " -c - (faire une copie avant d'imprimer - ignoré)\n" " -d printer[@host] - imprimante sur l'hôte\n" " -D debugflags - drapeaux de mise au point\n" " -f formname - première lettre utilisée comme format du travail\n" " -G - filter individual job files before sending\n" " -H handling - (passé comme -Z handling)\n" " -m - envoi d'un mail à $USER lors de l'achèvement\n" " -n copies - nombre de copies\n" " -o option nobanner, largeur reconnue\n" " (autres passés comme -Z option)\n" " -P pagelist - (imprimer la liste de la page - ignoré)\n" " -p - (notification à l'achèvement - ignoré)\n" " -q - priorité - 0 -> Z (la plus haute), 25 -> A (la plus basse)\n" " -s - (suppression des messages - ignoré)\n" " -S charset - (passé comme -Z charset)\n" " -t title - jtitre du travail\n" " -T content - (passé comme -Z content)\n" " -w - (écrire un message à l'achèvement - ignoré)\n" " -X path - filtre spécifié par l'utilisateur pour les fichiers des " "travaux\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passé comme -Z mode)\n" " sans commande, lecture depuis STDIN\n" " les variables d'environnement PRINTER, LPDEST, NGPRINTER, NPRINTER " "positionnent l'imprimante par défaut.\n" #: src/common/lpr.c:702 #, fuzzy, c-format msgid "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default " "printer.\n" msgstr "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - utiliser l'authentification spécifiée par la variable " "d'environnement AUTH\n" " -B - filtrer le travail avant envoi\n" " -C class - classe du travail\n" " -D debugopt - drapeaux de mise au point\n" " -F format - format du travail\n" " -b,-l - format binaire ou litéral\n" " c,d,f,g,l,m,p,t,v sont aussi des options de format\n" " -G - filtrer le travail avant envoi\n" " -J info - information de bannière et de travail\n" " -K copies, -# copies - nombre de copies\n" " -P printer[@host] - imprimante sur le hôte\n" " -Q - mettre 'queuename' dans le fichier de contrôle\n" " -Raccntname - information de nom de compte\n" " -T title - titre pour mise au format 'pr' (-p)\n" " -U username - surcharge du nom d'utilisateur (privilégié)\n" " -V - Information verbeuse durant le spoulage\n" " -X path - filtre spécifié par l'utilisateur pour les fichiers des " "travaux\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options à donner au filtre\n" " -h - pas d'en-tête ou de bannière de page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - envoyer par mail à mailaddr l'état final\n" " -r - supprimer les fichiers après spoulage\n" " -w width - largeur à utiliser\n" " -- - end of options, files follow\n" " sans commande, lecture depuis STDIN\n" " variables d'environnement PRINTER, LPDEST, NPRINTER, NGPRINTER qui " "positionnent l'imprimante par défaut.\n" #: src/common/lpr.c:803 msgid "Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)" msgstr "" "Priorité (première lettre de Class) pas 'A' (le plus bas) à 'Z' (le plus " "haut)" #: src/common/lpr.c:827 src/common/lpr.c:832 msgid "(STDIN)" msgstr "(STDIN)" #: src/common/lpr.c:881 msgid "-U (username) can only be used by ROOT" msgstr "-U (username) ne peut être utilisé que par ROOT" #: src/common/lpr.c:897 #, c-format msgid "Get_local_host: '%s' FQDN name not found!" msgstr "Get_local_host: '%s' nom FQDN non trouvé!" #: src/common/lpr.c:924 #, c-format msgid "Bad format specification '%c'" msgstr "Mauvaise spécification de format '%c'" #: src/common/lpr.c:931 #, c-format msgid "Sorry, can only print %d files at a time, split job up" msgstr "" "Désolé, seulement %d fichiers peuvent être imprimés à la fois, revoir la " "division du travail" #: src/common/lpr.c:937 #, c-format msgid "Maximum of %d copies allowed" msgstr "%d copies maximum autorisées" #: src/common/lpr.c:1001 msgid "authentication conficts with -k option" msgstr "" #: src/common/lpr.c:1004 msgid "send_block_format configuration option conficts with -k option" msgstr "" #: src/common/lpr.c:1007 msgid "send_data_first configuration option conficts with -k option" msgstr "" #: src/common/lpr.c:1010 msgid "multiple copies conficts with -k option" msgstr "" #: src/common/lpr.c:1013 msgid "files on command line conflicts with -k option" msgstr "" #: src/common/lpr.c:1101 msgid "Make_temp_fd failed" msgstr "Make_temp_fd a échoué" #: src/common/lpr.c:1103 msgid "You have closed STDIN! cannot pipe from a closed connection" msgstr "Vous avez fermé STDIN! ne peut faire pipe depuis une connexion fermée" #: src/common/lpr.c:1110 msgid "Copy_STDIN: write to temp file failed" msgstr "Copy_STDIN: écriture vers le fichier temporaire a échoué" #: src/common/lpr.c:1115 #, c-format msgid "Copy_STDIN: stat of temp fd '%d' failed" msgstr "Copy_STDIN: atteindre les données temporaire '%d' a échoué" #: src/common/lpr.c:1171 #, fuzzy, c-format msgid "Check_files: stat of temp fd '%d' failed" msgstr "Copy_STDIN: atteindre les données temporaire '%d' a échoué" #: src/common/lpr.c:1215 #, c-format msgid "cannot print '%s': %s" msgstr "ne peut imprimer '%s': %s" #: src/common/lpr.c:1224 msgid "not a regular file" msgstr "pas un fichier régulier" #: src/common/lpr.c:1229 msgid "cannot read it" msgstr "ne peut le lire" #: src/common/lpr.c:1244 msgid "" "unprintable characters at start of file, check your LANG environment " "variable as well as the input file" msgstr "" "cractères non-imprimables au début du fichier, vérifier votre variable LANG " "ainsi que le fichier d'entrée" #: src/common/lpr.c:1251 #, c-format msgid "option '%c' missing argument" msgstr "option '%c' manque un argument" #: src/common/lpr.c:1270 #, c-format msgid "option %c parameter `%s` is not positive integer value" msgstr "option %c paramètre `%s` n'est pas un entier positif" #: src/common/lpr.c:1274 #, c-format msgid "option %c parameter `%s` is not integer value from 0 - %d" msgstr "option %c paramètre `%s` n'est pas une valeur entière dans 0 - %d" #: src/common/lprm.c:234 #, c-format msgid "Printer: %s - cannot remove jobs from device '%s'\n" msgstr "" #: src/common/lprm.c:246 #, fuzzy, c-format msgid "Printer: %s - not in privileged group\n" msgstr "ne peut utiliser l'imprimante - pas dans le groupe privilégié\n" #: src/common/lprm.c:354 #, c-format msgid "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n" msgstr "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - toutes les imprimantes\n" " -A - utiliser l'authentification\n" " -Pprinter - printer (valeur par défaut variable PRINTER)\n" " -Uuser - prendre la personnalité de ce user (seulement root ou " "utilisateur privilégié)\n" " -Ddebuglevel - debug level\n" " -V - montrer les informations de version\n" " user enlève les travaux utilisateur\n" " all enlève tous les travaux\n" " jobid enlève le travail numéro jobid\n" " Example:\n" " Exemple:\n" " 'lprm -Plp 30' enlever le trvail 30 de l'imprimante lp\n" " 'lprm -a' enlever tous vos travaux de toutes les imprimantes\n" " 'lprm -a all' enlever tous les travaux de toutes les imprimantes\n" " Remarque: lprm n'enlève que les travaux pour lesquels vous avez " "l'autorisation d'enlèvement\n" #: src/common/lprm.c:372 #, c-format msgid "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n" msgstr "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - utiliser l'authentification\n" " -Ddebuglevel - debug level\n" " user enlève les travaux utilisateur\n" " all enlève tous les travaux\n" " jobid enlève le travail numéro jobid\n" " Exemple:\n" " 'clean 30 lp' enlève le travail 30 de l'imprimante lp\n" " 'clean' enlève le premier travail de l'imprimante par défaut\n" " 'clean all' enlève tous les travaux de l'imprimante par défaut\n" " 'clean all all' enlève tous les travaux de toutes les imprimantes\n" " Remarque: lprm n'enlève que les travaux pour lesquels vous avez " "l'autorisation d'enlèvement\n" #: src/common/sendjob.c:169 #, c-format msgid "sleeping %d secs before retry, starting sleep" msgstr "mise en veille %d secondes avant re-essai, debut de veille" #: src/common/sendmail.c:87 #, c-format msgid "printer %s job %s" msgstr "imprimante %s travail %s" #: src/common/sendmail.c:93 msgid " was successful.\n" msgstr " est réussi.\n" #: src/common/sendmail.c:98 msgid " failed, and retry count was exceeded.\n" msgstr " a échoué, et le nombre de re-essais est dépassé.\n" #: src/common/sendmail.c:103 msgid " failed and could not be retried.\n" msgstr " a échoué et ne peut être re-essayé.\n" #: src/common/sendmail.c:108 msgid " died a horrible death.\n" msgstr " mort d'une mort horrible.\n" #: src/common/sendreq.c:114 #, fuzzy, c-format msgid "no network support for '%s' operation" msgstr "pas de support réseau pour la demande" #: src/common/getopt.c:82 msgid "--X option form illegal\n" msgstr "" #: src/common/getopt.c:93 #, c-format msgid "%s: Illegal option '%c'\n" msgstr "" #: src/common/getopt.c:115 #, fuzzy, c-format msgid "%s: missing argument for '%c'\n" msgstr "%s: option '%c' manque un argument\n" #~ msgid " Example: -D10,remote=5\n" #~ msgstr " Exemple: -D10,remote=5\n" #~ msgid " set debug level to 10, remote flag = 5\n" #~ msgstr "" #~ " positionner le niveau de debug à 10, remote flag = 5\n" #~ msgid " Example: -D10,remote=5\n" #~ msgstr " Exemple: -D10,remote=5\n" #~ msgid "kill load balance server PID %d with %s\n" #~ msgstr "serveur d'équilibrage de charge PID %d tué avec %s\n" #~ msgid "removing job '%s' - failed, no retry" #~ msgstr " 'élimination du travail %s' - échec, pas de réessai" #~ msgid "removing job due to errors" #~ msgstr "élimination du travail due à des erreurs" #~ msgid "job failed - %s\n" #~ msgstr "travail a échoué - %s\n" #~ msgid "missing printer name in -P option\n" #~ msgstr "il manque le nom d'imprimante dans l'option -P\n" #~ msgid "(bounce queue)" #~ msgstr "(file de rebond)" #~ msgid "Cannot stat file '%s', %s" #~ msgstr "Ne peut atteidre le fichier '%s', %s" #~ msgid "Filter '%s' failed" #~ msgstr "Le filtre '%s' a échoué" #~ msgid "no network support for verbose status" #~ msgstr "pas de support réseau pour un état verbeux" lprng-3.8.B/po/de.po0000644000131400013140000015073111531672130011153 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #: src/common/lpc.c:270 src/common/lpc.c:435 src/common/lpq.c:547 msgid "" msgstr "" "Project-Id-Version: LPRng 3.8.28\n" "Report-Msgid-Bugs-To: lprng-devel@lists.sf.net\n" "POT-Creation-Date: 2011-02-03 19:40+0100\n" "PO-Revision-Date: $Id: de.po,v 1.3 2004/09/24 20:19:55 papowell Exp $\n" "Last-Translator: Walter Harms \n" "Language-Team:de \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" #: src/common/accounting.c:134 #, c-format msgid "connection to accounting server '%s' failed '%s'" msgstr "Verbinden zum Abrechnen auf Server '%s' unmöglich '%s'" # # # # schlüsselworte nicht übersetzen #: src/common/controlword.c:16 msgid "ABORT" msgstr "ABORT" #: src/common/controlword.c:17 msgid "ACTIVE" msgstr "AKTIVE" #: src/common/controlword.c:18 msgid "CLASS" msgstr "CLASS" #: src/common/controlword.c:19 msgid "CLIENT" msgstr "CLIENT" #: src/common/controlword.c:20 msgid "DEBUG" msgstr "DEBUG" #: src/common/controlword.c:21 msgid "DEFAULTQ" msgstr "DEFAULTQ" #: src/common/controlword.c:22 msgid "DISABLE" msgstr "DISABLE" #: src/common/controlword.c:23 msgid "DOWN" msgstr "DOWN" #: src/common/controlword.c:24 msgid "ENABLE" msgstr "ENABLE" #: src/common/controlword.c:25 msgid "HOLD" msgstr "HOLD" #: src/common/controlword.c:26 msgid "HOLDALL" msgstr "HOLDALL" #: src/common/controlword.c:27 msgid "KILL" msgstr "ENDE" #: src/common/controlword.c:28 msgid "LPD" msgstr "LPD" #: src/common/controlword.c:29 msgid "LPQ" msgstr "LPQ" #: src/common/controlword.c:30 msgid "LPRM" msgstr "LPRM" #: src/common/controlword.c:31 msgid "MOVE" msgstr "MOVE" #: src/common/controlword.c:32 msgid "MSG" msgstr "MSG" #: src/common/controlword.c:33 msgid "NOHOLDALL" msgstr "NOHOLDALL" #: src/common/controlword.c:34 msgid "PRINTCAP" msgstr "" #: src/common/controlword.c:35 msgid "REDIRECT" msgstr "" #: src/common/controlword.c:36 msgid "REDO" msgstr "" #: src/common/controlword.c:37 msgid "RELEASE" msgstr "" #: src/common/controlword.c:38 msgid "REREAD" msgstr "" #: src/common/controlword.c:39 msgid "START" msgstr "" #: src/common/controlword.c:40 msgid "STATUS" msgstr "" #: src/common/controlword.c:41 msgid "STOP" msgstr "" #: src/common/controlword.c:42 msgid "TOPQ" msgstr "" #: src/common/controlword.c:43 msgid "UP" msgstr "" #: src/common/controlword.c:44 msgid "SERVER" msgstr "" #: src/common/controlword.c:45 msgid "DEFAULTS" msgstr "" #: src/common/controlword.c:46 msgid "FLUSH" msgstr "" #: src/common/controlword.c:47 msgid "LANG" msgstr "" #: src/common/controlword.c:48 msgid "PPD" msgstr "" #: src/common/lpc.c:129 src/common/lpq.c:181 src/common/lpstat.c:147 #: src/common/lpr.c:91 src/common/lprm.c:146 msgid "" "authentication requested (-A option) and AUTH environment variable not set" msgstr "" "Authentifizierung verlangt (Option -A) aber keine Umgebungsvariable AUTH" #: src/common/lpc.c:198 msgid "exit" msgstr "exit" #: src/common/lpc.c:242 src/common/lpq.c:237 #, c-format msgid "Printer: %s - cannot get status from device '%s'\n" msgstr "Drucker: %s - keine Statusinformation von Gerät '%s'\n" #: src/common/lpc.c:249 src/common/lpq.c:259 src/common/lprm.c:253 #, c-format msgid "Printer: %s - direct connection to device '%s'\n" msgstr "Drucker: %s - Direktverbindung zum Gerät '%s'\n" #: src/common/lpc.c:267 #, c-format msgid "Locale information directory '%s'\n" msgstr "Lokales Verzeichnis '%s'\n" #: src/common/lpc.c:269 src/common/lpc.c:434 src/common/lpq.c:546 #, c-format msgid "LANG environment variable '%s'\n" msgstr "Variable LANG ist: '%s'\n" #: src/common/lpc.c:272 src/common/lpc.c:437 src/common/lpq.c:549 #, c-format msgid "gettext translation information '%s'\n" msgstr "gettext: Übersetzungen '%s'\n" #: src/common/lpc.c:274 src/common/lpc.c:439 src/common/lpq.c:551 msgid "No translation available\n" msgstr "keine Übersetzung vorhanden\n" #: src/common/lpc.c:276 msgid "TRANSLATION TEST" msgstr "TRANSLATION TEST" #: src/common/lpc.c:306 src/common/lpc.c:317 src/common/lpc.c:335 msgid "all" msgstr "all" #: src/common/lpc.c:312 src/common/lpc.c:321 msgid "# Printcap Information\n" msgstr "# Printcap Information\n" #: src/common/lpc.c:350 #, c-format msgid "execvp failed - '%s'" msgstr "execvp fehlgeschlagen - '%s'" #: src/common/lpc.c:353 #, c-format msgid "fork failed - '%s'" msgstr "" #: src/common/lpc.c:361 #, c-format msgid "doaction: waitpid(%ld) failed" msgstr "doaction: waitpid(%ld) fehlgeschlagen" #: src/common/lpc.c:452 #, c-format msgid "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke " "LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect " "jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint " "jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release " "jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder " "jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) " "support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n" msgstr "" "Verwendung: %s [-a][-Ddebuglevel][-Pdrucker][-Shost][-Uname][-V] [befehl]\n" " Befehle werden von STDIN gelesen, falls keiner angegeben wurde.\n" " -a - alias für -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - Druckername\n" " -Pprinter@HOST - Drucker des lpd-Servers auf HOST nutzen\n" " -SHOST - Verbinden zum lpd-Server auf HOST\n" " -U USER - ausgeben als USER (nur als root möglich)\n" " -V - Gesprächiger werden\n" " Befehle:\n" " active (printer[@host]) - suche nach aktiven Servern\n" " abort (printer[@host] | all) - Server anhalten\n" " class printer[@host] (class | off) - Setzen/Anzeigen von " "Druckerklassen\n" " disable (printer[@host] | all) - Warteschlange abschalten\n" " debug (printer[@host] | all) debugparms - setze debug level\n" " down (printer[@host] | all) - Drucken und Warteschlange abschalten\n" " enable (printer[@host] | all) - Warteschlange einschalten\n" " flush (printer[@host] | all) - Statusspeicher leeren\n" " hold (printer[@host] | all) (name[@host] | job | all)* - Job " "zurückhalten\n" " holdall (printer[@host] | all) - alle Jobs zurückhalten\n" " kill (printer[@host] | all) - Server anhalten und neu starten\n" " lpd (printer[@host]) - PID von LPD ermitteln \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - LPQ aufrufen\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - LPRM " "aufrufen\n" " msg printer message text - Statustext setzen\n" " move printer (user|jobid)* target - Jobs in eine andere Warteschlange\n" " verschieben\n" " noholdall (printer[@host] | all) - Alle Jobs weitermachen\n" " printcap (printer[@host] | all) - printcap Daten ausgeben\n" " quit - LPC beenden\n" " redirect (printer[@host] | all) (printer@host | off )* - Jobs umleiten\n" " redo (printer[@host] | all) (name[@host] | job | all)* - Job " "wiederholen\n" " release (printer[@host] | all) (name[@host] | job | all)* - Jobs " "freigeben\n" " reread - Konfiguration neu lesen\n" " start (printer[@host] | all) - Drucken einschalten\n" " status (printer[@host] | all) - Status des Druckers ausgeben\n" " stop (printer[@host] | all) - Drucken ausschalten\n" " topq (printer[@host] | all) (name[@host] | job | all)*\n" " - Neuorganisation der Jobs\n" " up (printer[@host] | all) - Drucken und Warteschlange einschalten\n" " Diagnostisches:\n" " defaultq - Zeige standard Warteschlange\n" " defaults - Zeige standard Einstellungen\n" " lang - Zeige aktuelle Spracheinstellungen\n" " client (printer | all) - Klient Einstellung und printcap\n" " server (printer | all) - Server Einstellung und printcap\n" #: src/common/lpd.c:178 msgid "No LPD lockfile specified!" msgstr "" #: src/common/lpd.c:189 src/common/lpd.c:202 #, c-format msgid "Another print spooler active, possibly lpd process '%ld'" msgstr "Ein anderer LPD ist da, PID ='%ld'" #: src/common/lpd.c:194 #, c-format msgid "cannot open or lock lockfile - %s" msgstr "" #: src/common/lpd.c:267 msgid "lpd: main() dofork failed" msgstr "" #: src/common/lpd.c:312 src/common/lpd.c:323 msgid "lpd: pipe call failed" msgstr "" #: src/common/lpd.c:330 msgid "lpd: cannot start initial logger process" msgstr "" #: src/common/lpd.c:683 msgid "lpd: select error!" msgstr "" #: src/common/lpd.c:710 msgid "lpd: Lpd_request pipe EOF! cannot happen" msgstr "" #: src/common/lpd.c:735 src/common/lpd.c:738 msgid "Setup_log: open /dev/null failed" msgstr "" #: src/common/lpd.c:745 src/common/lpd.c:749 #, c-format msgid "Setup_log: dup2(%d,%d) failed" msgstr "" #: src/common/lpd.c:754 #, c-format msgid "Setup_log: open %s failed" msgstr "" #: src/common/lpd.c:792 msgid "lpd: Cannot truncate lock file" msgstr "" #: src/common/lpd.c:810 #, c-format msgid "lpd: Cannot open lock file '%s'" msgstr "" #: src/common/lpd.c:912 #, c-format msgid "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" msgstr "" "Verwendung: %s [-FV][-D dbg][-L log][-P path][-p port][-R port]\n" " Optionen\n" " -D dbg - setze debug level und flags\n" " -F - im Vordergrund laufen, Protokoll nach STDERR\n" " -L logfile - Protokoll an logfile anhängen\n" " -V - Versionsangaben\n" " -p PORT - Lauschen auf TCP/IP Port PORT, 'off' schaltet Lauschen ab\n" " (lpd_listen_port)\n" " -P PATH - Lauschen auf UNIX Socket PATH, 'off' schaltet Lauschen ab\n" " (unix_socket_path)\n" " -R PORT - zu kontaktierender TCP/IP Port bei entfernten LPD-Servern\n" " (lpd_port)\n" #: src/common/lpd.c:1001 msgid "lpd: fork() failed" msgstr "" #: src/common/lpd.c:1012 msgid "lpd: accept on listening socket failed" msgstr "" #: src/common/lpd.c:1031 msgid "Start_all: pipe failed!" msgstr "" #: src/common/lpd_control.c:87 #, c-format msgid "bad control command '%s'" msgstr "" #: src/common/lpd_control.c:102 #, c-format msgid "printer '%s' has illegal char at '%s' in name" msgstr "Drucker '%s' hat ein unzulässiges Zeichen im Namen an Position '%s'" #: src/common/lpd_control.c:114 #, c-format msgid "%s: unknown control request '%s'" msgstr "" #: src/common/lpd_control.c:195 msgid "Use: move printer (user|jobid)* target" msgstr "Use: move printer (user|jobid)* target" #: src/common/lpd_control.c:206 msgid "no permission to control server" msgstr "kein Recht auf Serverkontrolle" #: src/common/lpd_control.c:460 msgid "not implemented yet" msgstr "Nicht Eingebaut" #: src/common/lpd_control.c:486 #, c-format msgid "server process PID %ld exited\n" msgstr "Serverprozess PID %ld beendet\n" #: src/common/lpd_control.c:489 #, c-format msgid "kill server process PID %ld with %s\n" msgstr "Erledige Serverprocess PID %ld mit %s\n" #: src/common/lpd_control.c:497 msgid "enabled and started" msgstr "eingeschaltet und gestartet" #: src/common/lpd_control.c:498 msgid "disabled and stopped" msgstr "abgeschaltet und gestoppt" #: src/common/lpd_control.c:499 msgid "stopped" msgstr "gestoppt" #: src/common/lpd_control.c:501 msgid "started" msgstr "gestartet" #: src/common/lpd_control.c:502 msgid "disabled" msgstr "abgeschaltet" #: src/common/lpd_control.c:503 msgid "enabled" msgstr "eingeschaltet" #: src/common/lpd_control.c:504 msgid "redirected" msgstr "umgelenkt" #: src/common/lpd_control.c:505 msgid "holdall on" msgstr "Alles Halt" #: src/common/lpd_control.c:506 msgid "holdall off" msgstr "Alles Weitermachen" #: src/common/lpd_control.c:507 msgid "move done" msgstr "Verschoben" #: src/common/lpd_control.c:508 msgid "class updated" msgstr "Klasse ergänzt" #: src/common/lpd_control.c:509 msgid "killed job" msgstr "Job getötet" #: src/common/lpd_control.c:510 msgid "aborted job" msgstr "Job abgebrochen" #: src/common/lpd_control.c:511 msgid "flushed status" msgstr "Statusspeicher geleert" #: src/common/lpd_control.c:531 #, c-format msgid "" "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n" msgstr "" #: src/common/lpd_control.c:565 #, c-format msgid "Do_queue_control: write to fd '%d' failed" msgstr "" #: src/common/lpd_control.c:654 #, c-format msgid "%s: no permission '%s'\n" msgstr "%s: keine Erlaubnis '%s'\n" #: src/common/lpd_control.c:738 #, c-format msgid "%s: selected '%s'\n" msgstr "%s: gewählt '%s'\n" #: src/common/lpd_control.c:748 #, c-format msgid "%s: cannot set hold file '%s'\n" msgstr "" #: src/common/lpd_control.c:855 msgid " holdall" msgstr " alles Halt" #: src/common/lpd_control.c:859 #, c-format msgid " class=%s" msgstr " Klasse=%s" #: src/common/lpd_control.c:863 msgid " autohold" msgstr "" #: src/common/lpd_control.c:935 src/common/lpd_control.c:990 #: src/common/lpd_control.c:1045 #, c-format msgid "wrong number arguments, %d" msgstr "Falsche Anzahl von Angaben %d" #: src/common/lpd_control.c:941 #, c-format msgid "forwarding to '%s'\n" msgstr "Weiterleitung an:'%s'\n" #: src/common/lpd_control.c:943 msgid "forwarding off\n" msgstr "Weiterleitung aus\n" #: src/common/lpd_control.c:997 #, c-format msgid "classes printed '%s'\n" msgstr "Klassen angegeben: '%s'\n" #: src/common/lpd_control.c:1000 msgid "all classes printed\n" msgstr "Alle Klassen angegeben\n" #: src/common/lpd_control.c:1051 #, c-format msgid "debugging override set to '%s'" msgstr "" #: src/common/lpd_control.c:1053 msgid "debugging override off" msgstr "" #: src/common/lpd_jobs.c:435 #, c-format msgid "Do_queue_jobs: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_jobs.c:767 src/common/lpd_jobs.c:787 #: src/common/lpd_jobs.c:2360 #, c-format msgid "cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:770 src/common/lpd_jobs.c:790 #, c-format msgid "Do_queue_jobs: cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:774 src/common/lpd_jobs.c:794 #, c-format msgid "removing job '%s' - no permissions" msgstr "Kein Recht Job '%s' zu löschen" #: src/common/lpd_jobs.c:1063 #, c-format msgid "Do_queue_jobs: LOGIC ERROR - no identifer '%s'" msgstr "" #: src/common/lpd_jobs.c:1072 #, c-format msgid "Do_queue_jobs: FORWARDING LOOP - '%s'" msgstr "" #: src/common/lpd_jobs.c:1096 #, c-format msgid "cannot update job ticket file '%s'" msgstr "Kann Job-Datei '%s' nicht öffnen" #: src/common/lpd_jobs.c:1098 #, c-format msgid "Do_queue_jobs: cannot update job ticket file '%s'" msgstr "" #: src/common/lpd_jobs.c:1147 #, c-format msgid "Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d" msgstr "" #: src/common/lpd_jobs.c:1163 src/common/lpd_jobs.c:1227 msgid "sleeping, waiting for processes to exit" msgstr "Warte bis Prozess endet" #: src/common/lpd_jobs.c:1204 #, c-format msgid "Do_queue_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_jobs.c:1403 #, c-format msgid "Remote_job: %d datafiles and only allowed %d" msgstr "Remote_job: %d Datafiles, Erlaubt sind %d" #: src/common/lpd_jobs.c:1447 #, c-format msgid "link failure while sending job '%s'" msgstr "Versandfehler bei Job '%s'" #: src/common/lpd_jobs.c:1453 #, c-format msgid "no permission to spool job '%s'" msgstr "Kein Recht Job '%s' zu spoolen" #: src/common/lpd_jobs.c:1459 #, c-format msgid "failed to send job '%s'" msgstr "Job '%s' nicht verschickt" #: src/common/lpd_jobs.c:1627 msgid "Fork_subserver: fork failed" msgstr "" #: src/common/lpd_jobs.c:1701 #, c-format msgid "subserver pid %ld exit status '%s'" msgstr "Unterserver PID %ld exit status '%s'" #: src/common/lpd_jobs.c:1705 #, c-format msgid "subserver pid %ld died with signal '%s'" msgstr "Unterserver pid %ld beendet mit Signal '%s'" #: src/common/lpd_jobs.c:1751 msgid "Wait_for_subserver: Mergesort failed" msgstr "Wait_for_subserver: Mergesort fehlgeschlagen" #: src/common/lpd_jobs.c:1762 #, c-format msgid "Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed" msgstr "" #: src/common/lpd_jobs.c:1787 msgid "succ" msgstr "" #: src/common/lpd_jobs.c:1788 msgid "jsucc" msgstr "" #: src/common/lpd_jobs.c:1789 msgid "success" msgstr "" #: src/common/lpd_jobs.c:1790 msgid "jsuccess" msgstr "" #: src/common/lpd_jobs.c:1791 msgid "abort" msgstr "" #: src/common/lpd_jobs.c:1792 msgid "jabort" msgstr "" #: src/common/lpd_jobs.c:1793 msgid "hold" msgstr "" #: src/common/lpd_jobs.c:1794 msgid "jhold" msgstr "" #: src/common/lpd_jobs.c:1795 msgid "remove" msgstr "" #: src/common/lpd_jobs.c:1796 msgid "jremove" msgstr "" #: src/common/lpd_jobs.c:1975 #, c-format msgid "Update_status: no identifier for '%s'" msgstr "" #: src/common/lpd_jobs.c:2008 src/common/lpd_jobs.c:2115 #: src/common/lpd_jobs.c:2157 src/common/lpd_jobs.c:2201 #, c-format msgid "job '%s' saved" msgstr "Job '%s' gespeichert" #: src/common/lpd_jobs.c:2013 src/common/lpd_jobs.c:2121 #: src/common/lpd_jobs.c:2163 src/common/lpd_jobs.c:2207 #, c-format msgid "could not remove job '%s'" msgstr "Job '%s' nicht entfernt" #: src/common/lpd_jobs.c:2015 src/common/lpd_jobs.c:2123 #: src/common/lpd_jobs.c:2165 src/common/lpd_jobs.c:2209 #, c-format msgid "job '%s' removed" msgstr "job '%s' entfernt" #: src/common/lpd_jobs.c:2045 #, c-format msgid "job '%s', attempt %d, allowed %d" msgstr "job '%s', %d Versuche,%d möglich" #: src/common/lpd_jobs.c:2049 msgid "treating as successful" msgstr "wird als Erfolg beurteilt" #: src/common/lpd_jobs.c:2050 msgid "retrying job" msgstr "Wiedervorlage" #: src/common/lpd_jobs.c:2051 msgid "no retry" msgstr "Keine Wiedervorlage" #: src/common/lpd_jobs.c:2052 msgid "aborting server" msgstr "Server beenden" #: src/common/lpd_jobs.c:2053 msgid "removing job - status JREMOVE" msgstr "entferne Job - status JREMOVE" #: src/common/lpd_jobs.c:2054 msgid "holding job" msgstr "halte Job" #: src/common/lpd_jobs.c:2057 #, c-format msgid "unexpected status 0x%x" msgstr "unerwarteter Status 0x%x" #: src/common/lpd_jobs.c:2062 #, c-format msgid "job '%s', %s" msgstr "" #: src/common/lpd_jobs.c:2066 #, c-format msgid "job '%s' attempt %d, trying %d times" msgstr "job '%s' Versuch %d , Versuche %d mal" #: src/common/lpd_jobs.c:2069 #, c-format msgid "job '%s' attempt %d, trying indefinitely" msgstr "job '%s' Versuche %d, Versuch weiter" #: src/common/lpd_jobs.c:2088 msgid "failed, no retry" msgstr "Fehlschlag, kein weiteren Versuche" #: src/common/lpd_jobs.c:2119 #, c-format msgid "removing job '%s' - JFAILNORETRY" msgstr "Entferne Job '%s' - JFAILNORETRY" #: src/common/lpd_jobs.c:2131 msgid "aborting operations" msgstr "Aktion abgebrochen" #: src/common/lpd_jobs.c:2161 #, c-format msgid "removing job '%s' - JABORT" msgstr "Entferne Job '%s' - JABORT" #: src/common/lpd_jobs.c:2170 msgid "stopping printing on filter JABORT exit code" msgstr "kein Druck (auf Filter) exit code JABORT" #: src/common/lpd_jobs.c:2180 msgid "removing destination due to errors" msgstr "Entferne Ziel wg. Fehlern" #: src/common/lpd_jobs.c:2191 msgid "too many errors" msgstr "zu viele Fehler" #: src/common/lpd_jobs.c:2205 #, c-format msgid "removing job '%s' - JREMOVE" msgstr "Entferne Job '%s' - JREMOVE" #: src/common/lpd_jobs.c:2334 #, c-format msgid "Service_worker: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_jobs.c:2363 #, c-format msgid "Service_worker: cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:2371 #, c-format msgid "Service_worker: no identifier for '%s'" msgstr "" #: src/common/lpd_jobs.c:2757 #, c-format msgid "job '%s' removed- status expired" msgstr "Job '%s' entfernt- Status abgelaufen" #: src/common/lpd_rcvjob.c:139 src/common/lpd_rcvjob.c:559 msgid "bad command line" msgstr "Commandozeile fehlerhaft" #: src/common/lpd_rcvjob.c:143 src/common/lpd_rcvjob.c:563 msgid "bad printer name" msgstr "Druckername falsch" #: src/common/lpd_rcvjob.c:151 #, c-format msgid "%s: cannot set up print queue" msgstr "Kann Warteschlange %s nicht starten" #: src/common/lpd_rcvjob.c:187 src/common/lpd_rcvjob.c:602 #: src/common/lpd_secure.c:188 #, c-format msgid "%s: spooling disabled" msgstr "%s: spooling abgeschaltet" #: src/common/lpd_rcvjob.c:198 #, c-format msgid "%s: Receive_job: sending ACK 0 failed" msgstr "" #: src/common/lpd_rcvjob.c:210 #, c-format msgid "Receive_job: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_rcvjob.c:215 #, c-format msgid "Receive_job: cannot lock lockfile '%s'" msgstr "" #: src/common/lpd_rcvjob.c:254 msgid "Recovering from incorrect job submission" msgstr "" #: src/common/lpd_rcvjob.c:268 #, c-format msgid "%s: Receive_job - bad control line '%s', len %0.0f, name '%s'" msgstr "" #: src/common/lpd_rcvjob.c:289 src/common/lpd_rcvjob.c:366 #: src/common/lpd_rcvjob.c:403 src/common/lpd_rcvjob.c:454 #: src/common/lpd_rcvjob.c:617 src/common/lpd_rcvjob.c:799 #: src/common/lpd_rcvjob.c:846 src/common/lpd_rcvjob.c:881 #: src/common/lpd_rcvjob.c:917 #, c-format msgid "size %0.3fK exceeds %dK" msgstr "Größe %0.3fK überschreitet %dK" #: src/common/lpd_rcvjob.c:296 src/common/lpd_rcvjob.c:624 #: src/common/lpd_secure.c:202 #, c-format msgid "%s: insufficient file space" msgstr "%s: zu wenig Speicher" #: src/common/lpd_rcvjob.c:311 src/common/lpd_rcvjob.c:676 #, c-format msgid "%s: sending ACK 0 for '%s' failed" msgstr "" #: src/common/lpd_rcvjob.c:345 src/common/lpd_rcvjob.c:649 #, c-format msgid "%s: transfer of '%s' from '%s' failed" msgstr "%s: Übertragung von '%s' nach '%s' fehlgeschlagen" #: src/common/lpd_rcvjob.c:375 src/common/lpd_rcvjob.c:412 #: src/common/lpd_rcvjob.c:463 src/common/lpd_rcvjob.c:854 #: src/common/lpd_rcvjob.c:890 src/common/lpd_rcvjob.c:926 #: src/common/lpd_rcvjob.c:1337 src/common/lpd_rcvjob.c:1413 #, c-format msgid "Error setting up job ticket file - %s" msgstr "" #: src/common/lpd_rcvjob.c:505 #, c-format msgid "Receive_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_rcvjob.c:570 #, c-format msgid "%s: cannot set up printer" msgstr "%s: Drucker kann nicht initialiert werden" #: src/common/lpd_rcvjob.c:638 #, c-format msgid "%s: Receive_block_job: sending ACK 0 failed" msgstr "" #: src/common/lpd_rcvjob.c:659 #, c-format msgid "Receive_block_job: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:706 #, c-format msgid "Receive_block_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_rcvjob.c:772 src/common/lpd_rcvjob.c:831 #, c-format msgid "Scan_block_file: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:787 #, c-format msgid "bad length information '%s'" msgstr "Falsche Längenangaben '%s'" #: src/common/lpd_rcvjob.c:819 #, c-format msgid "Scan_block_file: read failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:824 msgid "Scan_block_file: read unexecpted EOF" msgstr "" #: src/common/lpd_rcvjob.c:1017 #, c-format msgid "%s: no permission to print" msgstr "%s: kein Druckgenehmigung" #: src/common/lpd_rcvjob.c:1500 src/common/lpd_rcvjob.c:1525 #, c-format msgid "Do_incoming_control_filter: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:1613 #, c-format msgid "Get_route: lseek failed '%s'" msgstr "" #: src/common/lpd_remove.c:73 msgid "missing user or printer name" msgstr "Kein Nutzer oder Druckername angegeben" #: src/common/lpd_remove.c:81 src/common/lpd_status.c:175 #, c-format msgid "printer '%s' has illegal character at '%s' in name" msgstr "Drucker '%s' hat ein unzulässiges Zeichen im Namen an Position '%s'" #: src/common/lpd_remove.c:110 #, c-format msgid "Job_remove: error '%s'" msgstr "Job_remove: Fehler '%s'" #: src/common/lpd_remove.c:203 #, c-format msgid "Printer %s@%s:\n" msgstr "Drucker %s@%s:\n" #: src/common/lpd_remove.c:232 #, c-format msgid " checking perms '%s'\n" msgstr " Eingangskontrolle '%s'\n" #: src/common/lpd_remove.c:249 #, c-format msgid " no permissions '%s'\n" msgstr " Nicht Erlaubt '%s'\n" #: src/common/lpd_remove.c:263 #, c-format msgid " removing incoming job '%s'\n" msgstr " Entferne Job '%s'\n" #: src/common/lpd_remove.c:266 #, c-format msgid " dequeued '%s'\n" msgstr "" #: src/common/lpd_remove.c:275 #, c-format msgid "error: could not remove '%s'" msgstr "UPS: '%s' wurde nicht entfernt" #: src/common/lpd_remove.c:384 msgid " ERROR: " msgstr " FEHLER: " #: src/common/lpd_secure.c:81 #, c-format msgid "bad command line '%s'" msgstr "Commandozeile fehlerhaft '%s'" #: src/common/lpd_secure.c:113 #, c-format msgid "bad printer name '%s'" msgstr "Druckername falsch '%s'" #: src/common/lpd_secure.c:124 #, c-format msgid "bad printer '%s'" msgstr "Falscher Drucker '%s'" #: src/common/lpd_secure.c:166 #, c-format msgid "unsupported authentication '%s'" msgstr "Authentifizierung nicht unterstüzt '%s'" #: src/common/lpd_secure.c:173 #, c-format msgid "no receive method supported for '%s'" msgstr "Kein Empfang unterstützt für '%s'" #: src/common/lpd_secure.c:195 #, c-format msgid "%s: job size %0.0f is larger than %d K" msgstr "%s: Jobgröße von %0.3fK ist größer als %d K" #: src/common/lpd_status.c:357 #, c-format msgid "%s: no permission to show status" msgstr "%s: Keine Rechte für Statusanzeige" #: src/common/lpd_status.c:476 #, c-format msgid " (originally %s)" msgstr " (ursprünglich %s)" #: src/common/lpd_status.c:486 msgid "" "\n" " Error: " msgstr "" "\n" " Fehler: " #: src/common/lpd_status.c:491 #, c-format msgid " - %s" msgstr "" #: src/common/lpd_status.c:494 #, c-format msgid " - printer %s@%s not in printcap" msgstr " - Drucker %s@%s nicht in printcap" #: src/common/lpd_status.c:498 #, c-format msgid " - printer %s@%s has bad printcap entry" msgstr " - Drucker %s@%s hat fehlerhafter printcap Eintrag" #: src/common/lpd_status.c:724 #, c-format msgid " " msgstr "" #: src/common/lpd_status.c:736 #, c-format msgid " Job: %s" msgstr "" #: src/common/lpd_status.c:737 #, c-format msgid "%s status= %s" msgstr "%s Status= %s" #: src/common/lpd_status.c:740 #, c-format msgid "%s size= %0.0f" msgstr "%s Größe=%0.0f" #: src/common/lpd_status.c:743 #, c-format msgid "%s time= %s" msgstr "%s Zeit= %s" #: src/common/lpd_status.c:747 #, c-format msgid "%s error= %s" msgstr "%s Fehler= %s" #: src/common/lpd_status.c:752 #, c-format msgid "%s CONTROL=" msgstr "" #: src/common/lpd_status.c:758 #, c-format msgid "%s HOLDFILE=" msgstr "" #: src/common/lpd_status.c:778 #, c-format msgid " %d job" msgid_plural " %d jobs" msgstr[0] " %d Job" msgstr[1] " %d Jobs" #: src/common/lpd_status.c:782 #, c-format msgid " (%d held)" msgstr "" #: src/common/lpd_status.c:787 #, c-format msgid " (%d move)" msgstr "" #: src/common/lpd_status.c:810 #, c-format msgid " Comment: %s" msgstr " Kommentar: %s" #: src/common/lpd_status.c:821 #, c-format msgid "" "\n" " Printing: %s\n" " Aborted: %s\n" " Spooling: %s" msgstr "" "\n" " Drucken: %s\n" " Abgebrochen: %s\n" " Spooling: %s" #: src/common/lpd_status.c:867 #, c-format msgid "" "\n" " %s: " msgstr "" #: src/common/lpd_status.c:875 #, c-format msgid " (%s" msgstr "" #: src/common/lpd_status.c:890 #, c-format msgid "" "\n" " Redirected_to: %s" msgstr "" "\n" " Umgeleitet nach: %s" #: src/common/lpd_status.c:893 #, c-format msgid " (redirect %s)" msgstr " (Umgeleitet %s)" #: src/common/lpd_status.c:903 #, c-format msgid " (dest %s@%s)" msgstr " (Ziel %s@%s)" #: src/common/lpd_status.c:910 #, c-format msgid "" "\n" " Serving: %s" msgstr "" "\n" " in Arbeit: %s" #: src/common/lpd_status.c:913 #, c-format msgid " (serving %s)" msgstr " (bearbeite %s)" #: src/common/lpd_status.c:920 #, c-format msgid "" "\n" " Classes: %s" msgstr "" "\n" " Klassen: %s" #: src/common/lpd_status.c:923 #, c-format msgid " (classes %s)" msgstr " (Klassen %s)" #: src/common/lpd_status.c:930 msgid "" "\n" " Hold_all: on" msgstr "" "\n" " Hold_all: ein" #: src/common/lpd_status.c:933 msgid " (holdall)" msgstr "" #: src/common/lpd_status.c:940 msgid "" "\n" " Auto_hold: on" msgstr "" "\n" " Auto_hold: ein" #: src/common/lpd_status.c:943 msgid " (autohold)" msgstr "" #: src/common/lpd_status.c:951 #, c-format msgid "" "\n" " Message: %s" msgstr "" "\n" " Mitteilung: %s" #: src/common/lpd_status.c:954 #, c-format msgid " (message: %s)" msgstr " (Mitteilung: %s)" #: src/common/lpd_status.c:983 msgid " Queue: no printable jobs in queue\n" msgstr " Warteschlange: keine druckbaren Jobs\n" #: src/common/lpd_status.c:987 #, c-format msgid " Queue: %d printable job\n" msgid_plural " Queue: %d printable jobs\n" msgstr[0] " Warteschlange: %d druckbarer Job\n" msgstr[1] " Warteschlange: %d druckbare Jobs\n" #: src/common/lpd_status.c:994 #, c-format msgid " Holding: %d held jobs in queue\n" msgstr " Halt: halte %d Jobs vor\n" #: src/common/lpd_status.c:1000 msgid " Server: no server active" msgstr " Server: kein Server aktiv" #: src/common/lpd_status.c:1003 #, c-format msgid " Server: pid %d active" msgstr " Server: PID %d aktiv" #: src/common/lpd_status.c:1011 #, c-format msgid " Unspooler: pid %d active" msgstr " Unspooler: PID %d aktiv" #: src/common/lpd_status.c:1023 #, c-format msgid "%s SPOOLCONTROL=\n" msgstr "" #: src/common/lpd_status.c:1037 msgid " Status: " msgstr "" #: src/common/lpd_status.c:1041 msgid " Filter_status: " msgstr "Filterstatus: " #: src/common/lpd_dispatch.c:39 #, c-format msgid "Dispatch_input: bad request line '%s' from %s" msgstr "" #: src/common/lpd_dispatch.c:177 msgid "Service_connection: getpeername failed" msgstr "" #: src/common/lpd_dispatch.c:224 msgid "Service_connection: BAD LocalHost_IP value" msgstr "" #: src/common/lpd_dispatch.c:230 #, c-format msgid "Service_connection: bad protocol family '%d'" msgstr "" #: src/common/lpd_dispatch.c:261 msgid "no connect permissions" msgstr "Verbindungsaufnahme nicht erlaubt" #: src/common/lpd_dispatch.c:284 #, c-format msgid "Service_connection: peek of length %d failed" msgstr "" #: src/common/lpd_dispatch.c:326 #, c-format msgid "Service_connection: cannot read request from %s in %d seconds" msgstr "" #: src/common/lpd_dispatch.c:330 #, c-format msgid "Service_connection: short request line '%s', from '%s'" msgstr "" #: src/common/lpq.c:119 #, c-format msgid "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n" msgstr "" "Verwendung: %s [-aAclV] [-Ddebuglevel] [-Pdrucker] [-t SECS]\n" " -A - benutze die durch die Umgebungsvariable AUTH angegebenene\n" " Authentifikation\n" " -a - alle Drucker\n" " -c - Bildschirm löschen vor Neuausgabe\n" " -l - zeige detaillierte Statusinformation\n" " zusätzliche l Flags zeigen noch mehr Details\n" " -L - wirklich alle Statusinformation\n" " -n NR - NR Zeilen an Statusinformation\n" " -Pprinter - Druckerangabe\n" " -s - Kurzfassung\n" " -t SECS - Ausgabe nach SECS Sekunden wiederholen\n" " -V - Versionsinformation anzeigen\n" " -v - im Ausgabeformat Schlüssel: Wert\n" #: src/common/lpq.c:245 #, c-format msgid "Printer: %s is %s@%s\n" msgstr "Drucker: %s ist %s@%s\n" #: src/common/lpq.c:252 #, c-format msgid "Printer: %s - cannot use printer, not in privileged group\n" msgstr "Drucker: %s - Nutzung unzulässig, nicht in der zugelassenen Gruppe\n" #: src/common/lpq.c:369 src/common/lpq.c:374 src/common/lpq.c:384 #: src/common/lpq.c:431 src/common/lpq.c:438 msgid "Printer:" msgstr "Drucker:" #: src/common/lpq.c:477 msgid "fork() failed" msgstr "" #: src/common/lpq.c:484 #, c-format msgid "Term_clear: waitpid(%d) failed" msgstr "" #: src/common/lpq.c:510 msgid "lpq: please use the LPRng lpstat program\n" msgstr "lpq: Bitte lpstat von LPRng benutzen\n" #: src/common/lpstat.c:195 msgid "scheduler is running\n" msgstr "" #: src/common/lpstat.c:199 msgid "no system default destination\n" msgstr "" #: src/common/lpstat.c:201 #, c-format msgid "system default destination: %s\n" msgstr "" #: src/common/lpstat.c:208 #, c-format msgid "system for %s: %s\n" msgstr "" #: src/common/lpstat.c:250 #, c-format msgid " Printer: %s - cannot use printer, not in privileged group\n" msgstr " Drucker: %s - Nutzung unzulässig, nicht in der zugelassenen Gruppe\n" #: src/common/lpstat.c:259 #, c-format msgid " Printer: %s - direct connection to device '%s'\n" msgstr " Drucker: %s - Direktverbindung zum Gerät '%s'\n" #: src/common/lpstat.c:387 #, c-format msgid "" "%s not accepting requests since %s -\n" "\tunknown reason\n" msgstr "" #: src/common/lpstat.c:389 #, c-format msgid "%s accepting requests since %s\n" msgstr "%s nimmt Aufträge an seit %s\n" #: src/common/lpstat.c:397 #, c-format msgid "printer %s unknown state. disabled since %s. available\n" msgstr "" #: src/common/lpstat.c:398 #, c-format msgid "printer %s unknown state. enabled since %s. available\n" msgstr "" #: src/common/lpstat.c:404 #, c-format msgid "\tDescription: %s@%s\n" msgstr "\tBeschreibung: %s@%s\n" #: src/common/lpr.c:157 msgid "nothing to print" msgstr "Nichts zu tun" #: src/common/lpr.c:162 msgid "cannot use printer - not in privileged group\n" msgstr "Nutzung unzulässig, nicht in der zugelassenen Gruppe\n" #: src/common/lpr.c:168 #, c-format msgid "no remote support for %s@%s" msgstr "Kein Zugriff auf %s@%s" #: src/common/lpr.c:179 #, c-format msgid "%d data files and maximum allowed %d" msgstr "%d Datenfiles und %d maximal zulässig" #: src/common/lpr.c:221 src/common/lpr.c:1164 #, c-format msgid "Cannot open file '%s', %s" msgstr "Kann Datei '%s' nicht öffnen; '%s'" #: src/common/lpr.c:232 msgid "(lpr_filter)" msgstr "" #: src/common/lpr.c:295 src/common/lpr.c:332 #, c-format msgid "Status Information, attempt %d:\n" msgstr "Statusinformation, Versuch %d:\n" #: src/common/lpr.c:299 src/common/lpr.c:336 #, c-format msgid " of %d:\n" msgstr " von %d:·\n" #: src/common/lpr.c:312 #, c-format msgid "Waiting %d seconds before retry\n" msgstr "Neuer Versuch nach %d Sekunden\n" #: src/common/lpr.c:351 #, c-format msgid "request id is %s\n" msgstr "" #: src/common/lpr.c:354 #, c-format msgid "request id is %d\n" msgstr "" #: src/common/lpr.c:366 #, c-format msgid "Error unlinking '%s' - %s" msgstr "" #: src/common/lpr.c:374 #, c-format msgid "Done %d\n" msgstr "Erledigt %d\n" #: src/common/lpr.c:430 src/common/lpr.c:603 msgid "USER environment variable undefined" msgstr "Variable $USER undefiniert" #: src/common/lpr.c:448 msgid "-ncopies -number of copies must be greater than 0\n" msgstr "-n NR - NR muß größer als 0 sein\n" #: src/common/lpr.c:452 msgid "nobanner" msgstr "Kein Banner" #: src/common/lpr.c:455 msgid "width" msgstr "Breite" #: src/common/lpr.c:530 #, c-format msgid "bad -F format string '%s'\n" msgstr "-F -F Formatangabe fehlerhaft: '%s'\n" #: src/common/lpr.c:533 #, c-format msgid "duplicate format specification -F%s\n" msgstr "Doppelte Formatangaben -F%s\n" #: src/common/lpr.c:545 msgid "-Kcopies -number of copies must be greater than 0\n" msgstr "-K NR - NR muß größer als 0 sein\n" #: src/common/lpr.c:608 msgid "Missing mail name" msgstr "Fehlender Email Name" #: src/common/lpr.c:622 #, c-format msgid "duplicate format specification -%c\n" msgstr "Doppelte Formatangabe -%c\n" #: src/common/lpr.c:666 #, c-format msgid "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default " "printer.\n" msgstr "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d drucker@[host]]\n" " [-f FORMAT] [-H special-handling]\n" " [-n NR] [-o Optionen] [-P Seitenzahlen]\n" " [-q Priorität] [-S Zeichensatz]\n" " [-t Titel] [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ DATEINAMEN ... ]\n" " lp Simulation durch LPRng (Leichte Unterschiede nicht ausgeschlossen)\n" " -A - benutze die durch die Umgebungsvariable AUTH angegebenene\n" " Authentifikationsmethode\n" " -B - Filter Files und reduziere Job auf ein File vor dem Senden\n" " -c - (Kopieren vor dem Drucken - ignoriert)\n" " -d Drucker[@HOST] - Drucke auf Drucker von HOST\n" " -D debugflags - debugging flags\n" " -f FORMAT - Erster Buchstabe bestimmt Job Format\n" " -G - filter einzelne Jobs vor dem Senden\n" " -H Option - (Weitergeleitet als -Z Option)\n" " -m - Schicke Abschlußbericht als Email an $USER\n" " -n NR - Anzahl von Kopien\n" " -o option - 'nobanner' und 'width' Optionen werden erkannt,\n" " alles andere wird als -Z option weitergeleitet\n" " -P pagelist - (Drucke Seitenliste - ignoriert)\n" " -p - (Meldung am Ende - ignoriert)\n" " -q - Priorität - 0 -> Z (Höchste), 25 -> A (Kleinste)\n" " -s - (unterdrücke Ausgaben - ignoriert)\n" " -S charset - (Weitergeleitet als -Z charset)\n" " -t title - Jobtitel\n" " -T content - (Weitergeleitet als -Z content)\n" " -w - (Schicke Nachricht bei Beendigung - ignoriert)\n" " -X path - nutze benutzerspezifizierten Filter für die Jobs\n" " -Y - direktes Verbinden und Senden an TCP/IP Port\n" " -y mode - (Weitergeleitet als -Z mode)\n" " -- - Ende aller Optionen, nur noch DATEINAMEN folgen\n" " Dateiname '-' bedeutet: Lese von STDIN\n" " Die Variablen PRINTER, LPDEST, NPRINTER, NGPRINTER bestimmen den\n" "standard Drucker\n" #: src/common/lpr.c:702 #, c-format msgid "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default " "printer.\n" msgstr "" "Verwendung: %s [-Pdrucker[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G]\n" " [-Jinfo] [-(K|#)kopien] [-Q] [-Raccount] [-Ttitel] [-Uuser[@host]]\n" " [-V] [-Zoptions] [-b] [-m mailaddr] [-h] [-i einrück] [-l] [-w breite]\n" " [-r] [-Ddebugopt ] [--] [ DATEINAMEN ... ]\n" " -A - benutze die durch die Umgebungsvariable AUTH angegebenene\n" " Authentifikationsmethode\n" " -B - Filter Files und reduziere Job auf ein File vor dem Senden\n" " -C Klasse - Job Klasse\n" " -D debugopt - debugging flags\n" " -F format - Job Format\n" " -b,-l - binäry oder direktes Format\n" " c,d,f,g,l,m,p,t,v sind auch Formatangaben\n" " -G - filtere einzelne Jobs vor dem Senden\n" " -J info - banner und Job Angaben\n" " -K NR, -# NR - Anzahl der Kopien\n" " -P Drucker[@HOST] - Drucke auf Drucker von HOST\n" " -Q - Name der Warteschlage im Controlfile speichern\n" " -Raccntname - Angaben zur Abrechnung\n" " -T title - Titel für Formatierung mit 'pr' (-p)\n" " -U USER - ausgeben als USER (nur als root möglich)\n" " -V - Zeige Information während der Verarbeitung\n" " -X path - nutze benutzerspezifizierten Filter für die Jobs\n" " -Y - direktes Verbinden und Senden an TCP/IP Port\n" " -Z options - Optionen für den Filter\n" " -h - Kein Titelblatt oder Banner\n" " -i indent - Einrücken\n" " -k - keine temporären Files erstellen beim Senden\n" " -m EMAIL - sende Abschlußbericht an EMAIL\n" " -r - lösche Dateien nach dem Spooling\n" " -w breite - Nutzbare Breite\n" " -- - Ende aller Optionen, nur noch DATEINAMEN folgen\n" " Dateiname '-' bedeutet: Lese von STDIN\n" " Die Variablen PRINTER, LPDEST, NPRINTER, NGPRINTER bestimmen den\n" "standard Drucker\n" #: src/common/lpr.c:803 msgid "Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)" msgstr "" "Priotität (erster Buchstabe der Klasse) aber nicht 'A' (Kleinste) bis " "'Z' (Höchste)" #: src/common/lpr.c:827 src/common/lpr.c:832 msgid "(STDIN)" msgstr "" #: src/common/lpr.c:881 msgid "-U (username) can only be used by ROOT" msgstr "-U (username) kann nur ROOT benutzen" #: src/common/lpr.c:897 #, c-format msgid "Get_local_host: '%s' FQDN name not found!" msgstr "Get_local_host: '%s' FQDN nicht gefunden!" #: src/common/lpr.c:924 #, c-format msgid "Bad format specification '%c'" msgstr "Falsche Formatangaben '%c'" #: src/common/lpr.c:931 #, c-format msgid "Sorry, can only print %d files at a time, split job up" msgstr "Es sind nur %d Files möglich, Job besser aufteilen" #: src/common/lpr.c:937 #, c-format msgid "Maximum of %d copies allowed" msgstr "Maximal %d Kopien möglich" #: src/common/lpr.c:1001 msgid "authentication conficts with -k option" msgstr "Authentication widerspricht der Option -k" #: src/common/lpr.c:1004 msgid "send_block_format configuration option conficts with -k option" msgstr "send_block_format Einstellungen widersprechen der Option -k" #: src/common/lpr.c:1007 msgid "send_data_first configuration option conficts with -k option" msgstr "send_data_first Einstellung widerspricht der Option -k" #: src/common/lpr.c:1010 msgid "multiple copies conficts with -k option" msgstr "Anzahl der Kopien widerspricht der Option -k" #: src/common/lpr.c:1013 msgid "files on command line conflicts with -k option" msgstr "Files auf der Kommandozeile widersprechen der Option -k" #: src/common/lpr.c:1101 msgid "Make_temp_fd failed" msgstr "" #: src/common/lpr.c:1103 msgid "You have closed STDIN! cannot pipe from a closed connection" msgstr "STDIN ist geschlossen! Pipe kann daher nicht gelesen werden" #: src/common/lpr.c:1110 msgid "Copy_STDIN: write to temp file failed" msgstr "" #: src/common/lpr.c:1115 #, c-format msgid "Copy_STDIN: stat of temp fd '%d' failed" msgstr "" #: src/common/lpr.c:1171 #, c-format msgid "Check_files: stat of temp fd '%d' failed" msgstr "" #: src/common/lpr.c:1215 #, c-format msgid "cannot print '%s': %s" msgstr "'%s' kann nicht drucken werden: %s" #: src/common/lpr.c:1224 msgid "not a regular file" msgstr "keine richtige Datei" #: src/common/lpr.c:1229 msgid "cannot read it" msgstr "kann es nicht lesen" #: src/common/lpr.c:1244 msgid "" "unprintable characters at start of file, check your LANG environment " "variable as well as the input file" msgstr "" "Nichtdurckfähige Buchstaben am Anfang des File, $LANG und das File überprüfen" #: src/common/lpr.c:1251 #, c-format msgid "option '%c' missing argument" msgstr "Option '%c' fehlt das Argument" #: src/common/lpr.c:1270 #, c-format msgid "option %c parameter `%s` is not positive integer value" msgstr "Option %c Parameter `%s` ist keine positive ganze Zahl" #: src/common/lpr.c:1274 #, c-format msgid "option %c parameter `%s` is not integer value from 0 - %d" msgstr "Option %c Parameter `%s` ist keine ganze Zahl zwischen 0 und %d" #: src/common/lprm.c:234 #, c-format msgid "Printer: %s - cannot remove jobs from device '%s'\n" msgstr "Drucker: %s - kann Job bei Gerät '%s' nicht entfernen\n" #: src/common/lprm.c:246 #, c-format msgid "Printer: %s - not in privileged group\n" msgstr "Drucker: %s - keine zulässige Gruppe\n" #: src/common/lprm.c:354 #, c-format msgid "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n" msgstr "" " Verwendung: %s [-A] [-a | -Pdrucker] [-Ddebuglevel] (JOBID|USER|'all')*\n" " -a - alle Drucker\n" " -A - benutze die durch die Umgebungsvariable AUTH angegebenene\n" " Authentifikation\n" " -Pprinter - Druckerangabe (standard Drucker durch $PRINTER festgelegt)\n" " -U USER - ausgeben als USER (nur als root möglich)\n" " -Ddebuglevel - debug level\n" " -V - Versionsinformation ausgeben\n" " USER lösche Jobs von Benutzer USER\n" " all lösche alle Jobs\n" " JOBID lösche Job mit Nummer JOBID\n" " Beispiele:\n" " 'lprm -Plp 30' lösche Job 30 für Drucker lp\n" " 'lprm -a' alle Jobs für alle Drucker löschen\n" " 'lprm -a all' alle Jobs für alle Drucker löschen\n" " Hinweis: Man kann nur Jobs löschen wenn man das Recht dazu hat.\n" #: src/common/lprm.c:372 #, c-format msgid "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n" msgstr "" " Verwendung: %s [-A] [-Ddebuglevel] (JOBID|USER|'all')* [DRUCKER]\n" " -A - benutze die durch die Umgebungsvariable AUTH angegebenene\n" " Authentifikation\n" " -Ddebuglevel - debug level\n" " USER lösche Jobs von Benutzer USER\n" " all lösche alle Jobs\n" " JOBID lösche Job mit Nummer JOBID\n" " Beispiele:\n" " 'clean 30 lp' lösche Job 30 für Drucker lp\n" " 'clean' lösche den ersten Job für den Standarddrucker\n" " 'clean all' lösche alle Jobs für den Standarddrucker\n" " 'clean all all' lösche alle Jobs für alle Drucker\n" " Hinweis: Man kann nur Jobs löschen wenn man das Recht dazu hat.\n" #: src/common/sendjob.c:169 #, c-format msgid "sleeping %d secs before retry, starting sleep" msgstr "Warte %d Sekunden vor neuem Versuch, warte ..." #: src/common/sendmail.c:87 #, c-format msgid "printer %s job %s" msgstr "Drucker '%s' Job '%s'" #: src/common/sendmail.c:93 msgid " was successful.\n" msgstr " war erfolgreich.\n" #: src/common/sendmail.c:98 msgid " failed, and retry count was exceeded.\n" msgstr " Fehlschlag, und bereits zuviele Versuche.\n" #: src/common/sendmail.c:103 msgid " failed and could not be retried.\n" msgstr " Fehlschlag, kein weiterer Versuch.\n" #: src/common/sendmail.c:108 msgid " died a horrible death.\n" msgstr " qualvoll verstorben.\n" #: src/common/sendreq.c:114 #, c-format msgid "no network support for '%s' operation" msgstr " Keine Netzwerkunterstützung für Aktion '%s'" #: src/common/getopt.c:82 msgid "--X option form illegal\n" msgstr "Optionen der Form --X werden nicht unterstützt.\n" #: src/common/getopt.c:93 #, c-format msgid "%s: Illegal option '%c'\n" msgstr "%s: unbekannte Option '%c'.\n" #: src/common/getopt.c:115 #, c-format msgid "%s: missing argument for '%c'\n" msgstr "%s: Option '%c' fehlt ein Argument.\n" lprng-3.8.B/po/pl.gmo0000644000131400013140000012563511531672374011361 00000000000000Þ•Kt »Ì¸¹ÎÕ å óý )D X<f£ºË â íø ý   %0?P _m's › ¼ ÉÖß ð0#Ko‰  ª Ä ÎØ"ñ'<EN®k!$,$$D$ i$ u$‚$”$ ´$5Á$÷$ % % %+9%=e%%£%É%è%& &&<&c&‚&š& µ&Ö&!é& '%!' G'h' p'}'2–'&É'2ð'#()(80(i(‡((”((®('×(%ÿ(%)+)4)=)E)-J)-x))¦)%Ð).ö)<%*(b*1‹*5½*&ó*+#+%*+P+j+p+)Œ+¶+Ó+Ø+à+÷+ü+,!,%,),".,Q,V,Z,n,‹, ,§,Â,Ü,à,é,ù,1-24-:g-/¢-&Ò-ù-B.R.[.`.h.$o.+”.&À.&ç.%/(4/,]/Š/‘/—/ž/"£/!Æ/$è/* 0,80=e0&£0,Ê06÷0).16X1&1¶1Ô1 î162F2 ^22„2•2´2#·2%Û2C3E9&G?šn?: @$D@ i@;Š@Æ@ Ì@Ø@ì@ü@A&AJFDF$MF rF#}F¡FÁF(àF& G(0GYGlG†GœG*¯GÚG ÷G'H)H%@HfH†H$¦HËHçHðHII+I?I9PI6ŠIÁIÞI7ðI6(J-_J2J ÀJËJ"ÒJõJ K1K"MKpKŽK K ²K¿K>ÕK<LQLpL-ˆL'¶LÞLæL,îL'M"CMfMkMsM“M¦M¶MÍMgäMLNñlN¤^PÝ Sá\ç\à] ã^ñ^ø^ __$_C_0S_„_›_G«_ó_`,`C`V`k`p` ƒ` `œ`·`È`Ú`ï`ÿ`+a*1a\akaza‚a-“a Áa;Îa, b 7bXb pbzb•b ¦b°b3Ëb(ÿb(c=c„Ec(Êeóhi i ;i GiTifi ‚i3ŽiÂi Ôi àiìi7 jHAj1Šj-¼j&êjk0k/Lk&|k£k ¾k%ßkl-lEl,_l#Œl°l ¸lÄl-ãl1m-Cmqmwm;~mºmÙmßm!æmCnBLn7nÇnÍnÖnßnçn0ìn8o;Vo)’o5¼o:òo8-p=fpA¤p8æpq.q35qiq‰q%q/µq'åq rrr0r5r:rZr^rbr*gr’r—r›r¹rØr îr!ørs4s8sAs Rs:\s8—sEÐs:t,Qt~tI•tßtètítõt/üt=,u8ju6£u7Úu4v4Gv|vƒv‰vv-•v-Ãv0ñv/"w2Rw@…w0Æw9÷w:1x9lxB¦x,éx'y'>y.fyO•y!åyz'z,z(=zfz*iz+”zÀzÌà3­ˆžáˆG€‰.ȉ&÷‰HŠgŠmŠŠ”ЧаŠ-ÍŠQûŠ#M‹q‹ˆ‹¤‹!Ä‹æ‹û‹Œ8,ŒeŒƒŒ.Œ2ÌŒ8ÿŒ8K;cŸ½&Ü Ž Ž'$Ž$LŽ%qŽ—Ž Ž·ŽÓŽòŽ&ùŽ$ 0Evˆ¥½Ö&í,@V])c+¹%Ïõ ‘&‘D‘L‘R‘)[‘…‘.–‘.Å‘(ô‘)’5G’8}’¶’#Ó’$÷’“(.“#W“{“(’“»“$Ø“'ý“,%”.R”” ”!¯” єݔö”•@2•>s•!²•Ô•:ë•9&–6`–6—– ΖÜ–ã–—$ —E—&e—!Œ—®—À—Ò—ã—Aø—?:˜%z˜ ˜;¾˜#ú˜ ™ *™85™'n™-–™Ä™É™Ñ™ï™šš*šfDš$«šКêœ óŸ u««ÕAž R?"Ë3a㨀é›Kˆ7%ä«èÝÔëqìz¯fÖ7.E¡(ÈX×p CîØ‚vð´±å/s;“Q3yíV'}|Akµ ÁÓ¬6˜x5b*c¤\ÇI!¦¥ Ãôu®+ï ¼ò>ÏGÆÙJ]`w9@@ûÒd*ó:D$©Å>ñçþÐÑ=t i86#L{æ/$&4ÿlúŒ„M ¸…» Z™ÄƒJ̶W%áâ,m¢ 'ùBO—³PÛ22 œ))NY­H&·ªC; ¾’Žn=‘"²”4à–F1ÚeÜÞ°1 #!ß§÷[ÊSo½FBŠÉšŸ¹+ _†‹(DU<ê,º8--^üh50À:öÂEIT‰jÍ?Î9HGøý<r.õ~0K‡¿•g£ Description: %s@%s %s: Auto_hold: on Classes: %s Error: Hold_all: on Message: %s Printing: %s Aborted: %s Spooling: %s Redirected_to: %s Serving: %s Printer: %s - cannot use printer, not in privileged group checking perms '%s' dequeued '%s' no permissions '%s' (%d held) (%d move) (%s (autohold) (classes %s) (dest %s@%s) (holdall) (message: %s) (originally %s) (redirect %s) (serving %s) - %s - printer %s@%s has bad printcap entry - printer %s@%s not in printcap Comment: %s ERROR: Filter_status: Holding: %d held jobs in queue Job: %s Printer: %s - direct connection to device '%s' Queue: no printable jobs in queue Server: no server active Server: pid %d active Status: Unspooler: pid %d active autohold class=%s died a horrible death. failed and could not be retried. failed, and retry count was exceeded. holdall of %d: usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer] -A - use authentication -Ddebuglevel - debug level user removes user jobs all removes all jobs jobid removes job number jobid Example: 'clean 30 lp' removes job 30 on printer lp 'clean' removes first job on default printer 'clean all' removes all your jobs on default printer 'clean all all' removes all your jobs on all printers Note: clean removes only jobs for which you have removal permission usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')* -a - all printers -A - use authentication -Pprinter - printer (default PRINTER environment variable) -Uuser - impersonate this user (root or privileged user only) -Ddebuglevel - debug level -V - show version information user removes user jobs all removes all jobs jobid removes job number jobid Example: 'lprm -Plp 30' removes job 30 on printer lp 'lprm -a' removes all your jobs on all printers 'lprm -a all' removes all jobs on all printers Note: lprm removes only jobs for which you have removal permission was successful. # Printcap Information %d data files and maximum allowed %d%s CONTROL=%s HOLDFILE=%s SPOOLCONTROL= %s accepting requests since %s %s error= %s%s not accepting requests since %s - unknown reason %s size= %0.0f%s status= %s%s time= %s%s: Illegal option '%c' %s: Receive_block_job: sending ACK 0 failed%s: Receive_job - bad control line '%s', len %0.0f, name '%s'%s: Receive_job: sending ACK 0 failed%s: cannot set hold file '%s' %s: cannot set up print queue%s: cannot set up printer%s: insufficient file space%s: job size %0.0f is larger than %d K%s: missing argument for '%c' %s: no permission '%s' %s: no permission to print%s: no permission to show status%s: selected '%s' %s: sending ACK 0 for '%s' failed%s: spooling disabled%s: transfer of '%s' from '%s' failed%s: unknown control request '%s'(STDIN)(lpr_filter)--X option form illegal -Kcopies -number of copies must be greater than 0 -U (username) can only be used by ROOT-ncopies -number of copies must be greater than 0 ABORTACTIVEAnother print spooler active, possibly lpd process '%ld'Bad format specification '%c'CLASSCLIENTCannot open file '%s', %sCheck_files: stat of temp fd '%d' failedCopy_STDIN: stat of temp fd '%d' failedCopy_STDIN: write to temp file failedDEBUGDEFAULTQDEFAULTSDISABLEDOWNDispatch_input: bad request line '%s' from %sDo_incoming_control_filter: lseek failed '%s'Do_queue_control: write to fd '%d' failedDo_queue_jobs: FORWARDING LOOP - '%s'Do_queue_jobs: LOGIC ERROR - no identifer '%s'Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %dDo_queue_jobs: cannot open lockfile '%s'Do_queue_jobs: cannot update job ticket file '%s'Do_queue_jobs: cannot update job ticket file for '%s'Do_queue_jobs: write to fd '%d' failedDone %d ENABLEError setting up job ticket file - %sError unlinking '%s' - %sFLUSHFork_subserver: fork failedGet_local_host: '%s' FQDN name not found!Get_route: lseek failed '%s'HOLDHOLDALLJob_remove: error '%s'KILLLANGLANG environment variable '%s' LPDLPQLPRMLocale information directory '%s' MOVEMSGMake_temp_fd failedMaximum of %d copies allowedMissing mail nameNOHOLDALLNo LPD lockfile specified!No translation available PPDPRINTCAPPrinter %s@%s: Printer:Printer: %s - cannot get status from device '%s' Printer: %s - cannot remove jobs from device '%s' Printer: %s - cannot use printer, not in privileged group Printer: %s - direct connection to device '%s' Printer: %s - not in privileged group Printer: %s is %s@%s Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)REDIRECTREDORELEASEREREADReceive_block_job: lseek failed '%s'Receive_block_jobs: write to fd '%d' failedReceive_job: cannot lock lockfile '%s'Receive_job: cannot open lockfile '%s'Receive_jobs: write to fd '%d' failedRecovering from incorrect job submissionRemote_job: %d datafiles and only allowed %dSERVERSTARTSTATUSSTOPScan_block_file: lseek failed '%s'Scan_block_file: read failed '%s'Scan_block_file: read unexecpted EOFService_connection: BAD LocalHost_IP valueService_connection: bad protocol family '%d'Service_connection: cannot read request from %s in %d secondsService_connection: getpeername failedService_connection: peek of length %d failedService_connection: short request line '%s', from '%s'Service_worker: cannot open lockfile '%s'Service_worker: cannot update job ticket file for '%s'Service_worker: no identifier for '%s'Setup_log: dup2(%d,%d) failedSetup_log: open %s failedSetup_log: open /dev/null failedSorry, can only print %d files at a time, split job upStart_all: pipe failed!Status Information, attempt %d: TOPQTRANSLATION TESTTerm_clear: waitpid(%d) failedUPUSER environment variable undefinedUpdate_status: no identifier for '%s'Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]] [-f form-name] [-H special-handling] [-n number] [-o options] [-P page-list] [-q priority-level] [-S character-set] [-S print-wheel] [-t title] [-T content-type [-r]] [-y mode-list] [-Ddebugopt ] [ filenames ... ] lp simulator using LPRng, functionality may differ slightly -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -c - (make copy before printing - ignored) -d printer[@host] - printer on host -D debugflags - debugging flags -f formname - first letter used as job format -G - filter individual job files before sending -H handling - (passed as -Z handling) -m - mail sent to $USER on completion -n copies - number of copies -o option nobanner, width recognized (others passed as -Z option) -P pagelist - (print page list - ignored) -p - (notification on completion - ignored) -q - priority - 0 -> Z (highest), 25 -> A (lowest) -s - (suppress messages - ignored) -S charset - (passed as -Z charset) -t title - job title -T content - (passed as -Z content) -w - (write message on completion - ignored) -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -y mode - (passed as -Z mode) -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default printer. Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo] [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V] [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r] [-Ddebugopt ] [--] [ filenames ... ] -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -C class - job class -D debugopt - debugging flags -F format - job format -b,-l - binary or literal format c,d,f,g,l,m,p,t,v are also format options -G - filter individual job files before sending -J info - banner and job information -K copies, -# copies - number of copies -P printer[@host] - printer on host -Q - put 'queuename' in control file -Raccntname - accounting information -T title - title for 'pr' (-p) formatting -U username - override user name (restricted) -V - Verbose information during spooling -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -Z options - options to pass to filter -h - no header or banner page -i indent - indentation -k - do not use tempfile when sending to server -m mailaddr - mail final status to mailaddr -r - remove files after spooling -w width - width to use -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default printer. Use: move printer (user|jobid)* targetWARNING: the main load balance server may have exited before it could be informed that there were new jobs. Please use 'lpc start %s' to start the server Wait_for_subserver: LOGIC ERROR! waiting for pid %d failedWait_for_subserver: Mergesort failedWaiting %d seconds before retry You have closed STDIN! cannot pipe from a closed connectionabortaborted jobaborting operationsaborting serverallall classes printed authentication conficts with -k optionauthentication requested (-A option) and AUTH environment variable not setbad -F format string '%s' bad command linebad command line '%s'bad control command '%s'bad length information '%s'bad printer '%s'bad printer namebad printer name '%s'cannot open or lock lockfile - %scannot print '%s': %scannot read itcannot update job ticket file '%s'cannot update job ticket file for '%s'cannot use printer - not in privileged group class updatedclasses printed '%s' connection to accounting server '%s' failed '%s'could not remove job '%s'debugging override offdebugging override set to '%s'disableddisabled and stoppeddoaction: waitpid(%ld) failedduplicate format specification -%c duplicate format specification -F%s enabledenabled and startederror: could not remove '%s'execvp failed - '%s'exitfailed to send job '%s'failed, no retryfiles on command line conflicts with -k optionflushed statusfork failed - '%s'fork() failedforwarding off forwarding to '%s' gettext translation information '%s' holdholdall offholdall onholding jobjabortjholdjob '%s' attempt %d, trying %d timesjob '%s' attempt %d, trying indefinitelyjob '%s' removedjob '%s' removed- status expiredjob '%s' savedjob '%s', %sjob '%s', attempt %d, allowed %djremovejsuccjsuccesskill server process PID %ld with %s killed joblink failure while sending job '%s'lpd: Cannot open lock file '%s'lpd: Cannot truncate lock filelpd: Lpd_request pipe EOF! cannot happenlpd: accept on listening socket failedlpd: cannot start initial logger processlpd: fork() failedlpd: main() dofork failedlpd: pipe call failedlpd: select error!lpq: please use the LPRng lpstat program missing user or printer namemove donemultiple copies conficts with -k optionno connect permissionsno network support for '%s' operationno permission to control serverno permission to spool job '%s'no receive method supported for '%s'no remote support for %s@%sno retryno system default destination nobannernot a regular filenot implemented yetnothing to printoption %c parameter `%s` is not integer value from 0 - %doption %c parameter `%s` is not positive integer valueoption '%c' missing argumentprinter %s job %sprinter %s unknown state. disabled since %s. available printer %s unknown state. enabled since %s. available printer '%s' has illegal char at '%s' in nameprinter '%s' has illegal character at '%s' in nameredirectedremoveremoving destination due to errorsremoving job '%s' - JABORTremoving job '%s' - JFAILNORETRYremoving job '%s' - JREMOVEremoving job '%s' - no permissionsremoving job - status JREMOVErequest id is %d request id is %s retrying jobscheduler is running send_block_format configuration option conficts with -k optionsend_data_first configuration option conficts with -k optionserver process PID %ld exited size %0.3fK exceeds %dKsleeping %d secs before retry, starting sleepsleeping, waiting for processes to exitstartedstoppedstopping printing on filter JABORT exit codesubserver pid %ld died with signal '%s'subserver pid %ld exit status '%s'succsuccesssystem default destination: %s system for %s: %s too many errorstreating as successfulunexpected status 0x%xunprintable characters at start of file, check your LANG environment variable as well as the input fileunsupported authentication '%s'usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP destination port] Options -D dbg - set debug level and flags -F - run in foreground, log to STDERR -L logfile - append log information to logfile -V - show version info -p port - TCP/IP listen port, 'off' disables TCP/IP listening port (lpd_listen_port) -P path - UNIX socket path, 'off' disables UNIX listening socket (unix_socket_path) -R port - remote LPD server port (lpd_port) usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime] -A - use authentication specified by AUTH environment variable -a - all printers -c - clear screen before update -l - increase (lengthen) detailed status information additional l flags add more detail. -L - maximum detailed status information -n linecount - linecount lines of detailed status information -Ddebuglevel - debug level -Pprinter - specify printer -s - short (summary) format -tsleeptime - sleeptime between updates -V - print version information -v - print in key: value format usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command] with no command, reads from STDIN -a - alias for -Pall -Ddebuglevel - debug level -Pprinter - printer -Pprinter@host - printer on lpd server on host -Shost - connect to lpd server on host -Uuser - identify command as coming from user -V - increase information verbosity commands: active (printer[@host]) - check for active server abort (printer[@host] | all) - stop server class printer[@host] (class | off) - show/set class printing disable (printer[@host] | all) - disable queueing debug (printer[@host] | all) debugparms - set debug level for printer down (printer[@host] | all) - disable printing and queueing enable (printer[@host] | all) - enable queueing flush (printer[@host] | all) - flush cached status hold (printer[@host] | all) (name[@host] | job | all)* - hold job holdall (printer[@host] | all) - hold all jobs on kill (printer[@host] | all) - stop and restart server lpd (printer[@host]) - get LPD PID lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke LPRM msg printer message text - set status message move printer (user|jobid)* target - move jobs to new queue noholdall (printer[@host] | all) - hold all jobs off printcap (printer[@host] | all) - report printcap values quit - exit LPC redirect (printer[@host] | all) (printer@host | off )* - redirect jobs redo (printer[@host] | all) (name[@host] | job | all)* - reprint jobs release (printer[@host] | all) (name[@host] | job | all)* - release jobs reread - LPD reread database information start (printer[@host] | all) - start printing status (printer[@host] | all) - status of printers stop (printer[@host] | all) - stop printing topq (printer[@host] | all) (name[@host] | job | all)* - reorder jobs up (printer[@host] | all) - enable printing and queueing diagnostic: defaultq - show default queue for LPD server defaults - show default configuration values lang - show current i18n (iNTERNATIONALIZATIONn) support client (printer | all) - client config and printcap information server (printer | all) - server config and printcap widthwrong number arguments, %dProject-Id-Version: lprng 3.8.29-rc4 Report-Msgid-Bugs-To: lprng-devel@lists.sf.net POT-Creation-Date: 2011-02-03 19:40+0100 PO-Revision-Date: 2007-08-08 17:40+0200 Last-Translator: Jakub Bogusz Language-Team: Polish MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-2 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); Opis: %s@%s %s: Autowstrzymanie: tak Klasy: %s B³±d: Wstrzymanie_wszystkiego: tak Komunikat: %s Drukowanie: %s Przerwane: %s Buforowanie: %s Przekierowane_do: %s Wysy³anie: %s Drukarka: %s - nie mo¿na u¿yæ drukarki, spoza grupy uprzywilejowanej sprawdzanie uprawnieñ '%s' usuniêto z kolejki '%s' brak uprawnieñ '%s' (%d wstrzymanych) (%d przeniesionych) (%s (autowstrzymanie) (klasy %s) (cel %s@%s) (wstrzymanie wszystkiego) (komunikat: %s) (oryginalnie %s) (przekierowanie %s) (wysy³anie %s) - %s - drukarka %s@%s ma b³êdny wpis w printcap - drukarka %s@%s nie wystêpuje w printcap Komentarz: %s B£¡D: Status_filtra: Wstrzymane: %d wstrzymanych zadañ w kolejce Zadanie: %s Drukarka: %s - bezpo¶rednie po³±czenie z urz±dzeniem '%s' Kolejka: brak drukowalnych zadañ w kolejce Serwer: brak aktywnych serwerów Serwer: pid %d aktywny Status: Unspooler: pid %d aktywny autowstrzymanie klasa=%s zmar³o okropn± ¶mierci±. nie powiod³o siê i próba nie mo¿e byæ powtórzona. nie powiod³o siê, licznik prób wygas³. wszystko-wstrzymane z %d: Sk³adnia: %s [-A] [-Dpoziom] (idzad|u¿ytkownik|'all')* [drukarka] -A - u¿ycie uwierzytelnienia -Dpoziom - poziom ¶ledzenia (debug level) u¿ytkownik usuniêcie zadañ u¿ytkownika all usuniêcie wszystkich zadañ idzad usuniêcie zadania o tym identyfikatorze Przyk³ad: 'clean 30 lp' usuwa zadanie 30 z drukarki lp 'clean' usuwa pierwsze zadanie z domy¶lnej drukarki 'clean all' usuwa wszystkie w³asne zadania z domy¶lnej drukarki 'clean all all' usuwa wszystkie w³asne zadania ze wszystkich drukarek Uwaga: clean usuwa tylko te zadania, do których ma siê prawo usuwania Sk³adnia: %s [-A] [-a | -Pdrukarka] [-Dpoziom] (idzad|u¿ytkownik|'all')* -a - wszystkie drukarki -A - u¿ycie uwierzytelnienia -Pdrukarka - drukarka (domy¶lna jest podana przez zmienn± PRINTER) -Uu¿ytkownik - wcielenie siê w u¿ytkownika (tylko root lub uprzywilejowani) -Dpoziom - poziom ¶ledzenia (debug level) -V - pokazanie informacji o wersji u¿ytkownik usuniêcie zadañ u¿ytkownika all usuniêcie wszystkich zadañ idzad usuniêcie zadania o tym identyfikatorze Przyk³ad: 'lprm -Plp 30' usuwa zadanie 30 z drukarki lp 'lprm -a' usuwa wszystkie w³asne zadania ze wszystkich drukarek 'lprm -a all' usuwa wszystkie zadania ze wszystkich drukarek Uwaga: lprm usuwa tylko zadania do których ma siê prawo usuwania powiod³o siê. # Informacje printcap %d plików danych, a dozwolone %d%s CONTROL=%s HOLDFILE=%s SPOOLCONTROL= %s przyjmuje ¿±dania od %s %s b³±d= %s%s nie przyjmuje ¿±dañ od %s - przyczyna nieznana %s rozmiar= %0.0f%s stan= %s%s czas= %s%s: Niedozwolona opcja '%c' %s: Receive_block_job: wysy³anie ACK 0 nie powiod³o siê%s: Receive_job - b³êdna linia kontrolna '%s', d³ugo¶æ %0.0f, nazwa '%s'%s: Receive_job: wysy³anie ACK 0 nie powiod³o siê%s: nie mo¿na ustawiæ pliku wstrzymania '%s' %s: nie mo¿na ustawiæ kolejki wydruków%s: nie mo¿na ustawiæ drukarki%s: za ma³o miejsca na plik%s: rozmiar zadania %0.0f jest wiêkszy ni¿ %d K%s: przy opcji '%c' brakuje argumentu %s: brak uprawnienia '%s' %s: brak uprawnieñ do drukowania%s: brak uprawnieñ do pokazania stanu%s: wybrano '%s' %s: wysy³anie ACK 0 dla '%s' nie powiod³o siê%s: buforowanie wy³±czone%s: przesy³anie '%s' z '%s' nie powiod³o siê%s: nieznane ¿±danie kontrolne '%s'(STDIN)(filtr_lpr)Niedozwolona postaæ opcji --X -Kkopii - liczba kopii musi byæ wiêksza od 0 -U (u¿ytkownik) mo¿e byæ podany tylko przez ROOTa-nkopii - liczba kopii musi byæ wiêksza od 0 ABORTACTIVEInny demon wydruku aktywny, prawdopodobnie proces lpd '%ld'B³êdne okre¶lenie formatu '%c'CLASSCLIENTNie mo¿na otworzyæ pliku '%s': %sCheck_files: stat na tymczasowym deskryptorze '%d' nie powiod³o siêCopy_STDIN: stat na tymczasowym deskryptorze '%d' nie powiod³o siêCopy_STDIN: zapis do pliku tymczasowego nie powiód³ siêDEBUGDEFAULTQDEFAULTSDISABLEDOWNDisplatch_input: b³êdna linia ¿±dania '%s' od %sDo_incoming_control_filter: lseek nie powiod³o siê: '%s'Do_queue_control: zapis do deskryptora '%d' nie powiód³ siêDo_queue_jobs: PÊTLA PRZEKAZYWANIA - '%s'Do_queue_jobs: B£¡D LOGIKI - brak identyfikatora '%s'Do_queue_jobs: B£¡D LOGIKI! new_dest i use_subserver == %dDo_queue_jobs: nie mo¿na otworzyæ pliku blokuj±cego '%s'Do_queue_jobs: nie mo¿na uaktualniæ pliku biletu zadania '%s'Do_queue_jobs: nie mo¿na uaktualniæ pliku biletu zadania dla '%s'Do_queue_jobs: zapis do deskryptora '%d' nie powiód³ siêZakoñczono %d ENABLEB³±d podczas ustanawiania pliku biletu zadania - %sB³±d podczas usuwania '%s' - %sFLUSHFork_subserver: fork nie powiod³o siêGet_local_host: nie znaleziono nazwy FQDN '%s'!Get_route: lseek nie powiod³o siê: '%s'HOLDHOLDALLJob_remove: b³±d '%s'KILLLANGZmienna ¶rodowiskowa LANG '%s' LPDLPQLPRMKatalog z informacjami o lokalizacji '%s' MOVEMSGMake_temp_fd nie powiod³o siêDozwolone maksymalnie %d kopiiBrak nazwy dla pocztyNOHOLDALLNie podano pliku blokuj±cego LPD!T³umaczenie nie dostêpne PPDPRINTCAPDrukarka %s@%s: Drukarka:Drukarka: %s - nie mo¿na odczytaæ stanu z urz±dzenia '%s' Drukarka: %s - nie mo¿na usun±æ zadañ z urz±dzenia '%s' Drukarka: %s - nie mo¿na u¿yæ drukarki, spoza grupy uprzywilejowanej Drukarka: %s - bezpo¶rednie po³±czenie z urz±dzeniem '%s' Drukarka: %s - spoza uprzywilejowanej grupy Drukarka: %s to %s@%s Priorytet (pierwsza litera klasy), nie 'A' (najni¿szy) do 'Z' (najwy¿szy)REDIRECTREDORELEASEREREADReceive_block_job: lseek nie powiod³o siê: '%s'Receive_block_jobs: zapis do deskryptora '%d' nie powiód³ siêReceive_job: nie mo¿na zablokowaæ pliku blokuj±cego '%s'Receive_job: nie mo¿na otworzyæ pliku blokuj±cego '%s'Receive_jobs: zapis do deskryptora '%d' nie powiód³ siêPrzywracanie stanu po zleceniu niepoprawnego zadaniaRemote_job: %d plików danych, a dozwolonych tylko %dSERVERSTARTSTATUSSTOPScan_block_file: lseek nie powiod³o siê: '%s'Scan_block_file: odczyt nie powiód³ siê: '%s'Scan_block_file: nieoczekiwany EOF przy odczycieService_connection: b³êdna warto¶æ LocalHost_IPService_connection: b³êdna rodzina protoko³ów '%d'Service_connection: nie mo¿na odczytaæ ¿±dania od %s w %d sekundService_connection: getpeername nie powiod³o siêService_connection: podgl±d o d³ugo¶ci %d nie powiód³ siêService_connection: zbyt krótka linia ¿±dania '%s' od '%s'Service_worker: nie mo¿na otworzyæ pliku blokuj±cego '%s'Service_worker: nie mo¿na uaktualniæ pliku biletu zadania dla '%s'Service_worker: brak identyfikatora dla '%s'Setup_log: dup2(%d,%d) nie powiod³o siêSetup_log: otwarcie %s nie powiod³o siêSetup_log: otwarcie /dev/null nie powiod³o siêNiestety, mo¿na drukowaæ tylko %d plików jednocze¶nie, trzeba podzieliæ zadanieStart_all: pipe nie powiod³o siê!Informacje o stanie, próba %d: TOPQTEST T£UMACZENIATerm_clear: waitpid(%d) nie powiod³o siêUPNie zdefiniowana zmienna ¶rodowiskowa USERUpdate_status: brak identyfikatora dla '%s'Sk³adnia: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d drukarka[@host]] [-f nazwa-form] [-H specjalna-obs³uga] [-n liczba] [-o opcje] [-P lista-stron] [-q priorytet] [-S zestaw-znaków] [-S print-wheel] [-t tytu³] [-T content-type [-r]] [-y lista-trybów] [-Dopcje¶ledzenia] [ nazwy plików ... ] symulator lp u¿ywaj±cy LPRng, funkcjonalno¶æ mo¿e siê nieco ró¿niæ -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± AUTH -B - filtrowanie plików i zmniejszenie zadania do pojedynczego pliku przed wys³aniem -c - (tworzenie kopii przed drukowaniem - ignorowane) -d drukarka[@host] - drukarka na ho¶cie -D opcje¶ledzenia - flagi ¶ledzenia -f nazwaformatu - pierwsza litera u¿ywana jako format zadania -G - filtrowanie poszczególnych plików zadañ przed wys³aniem -H obs³uga - (przekazywane jako -Z obs³uga) -m - wys³anie poczty do $USER po zakoñczeniu zadania -n kopii - liczba kopii -o opcja rozpoznawane: nobanner, width (inne przekazywane jako opcja -Z) -P listastron - (lista stron do drukowania - ignorowana) -p - (powiadomienie po zakoñczeniu - ignorowane) -q - priorytet - 0 -> Z (najwy¿szy), 25 -> A (najni¿szy) -s - (pominiêcie komunikatów - ignorowane) -S zestaw - zestaw znaków (przekazywany jako -Z zestaw) -t tytu³ - tytu³ zadania -T tre¶æ - (przekazywane jako -Z tre¶æ) -w - (wypisanie komunikatu po zakoñczeniu - ignorowane) -X ¶cie¿ka - w³asny filtr dla plików zadañ -Y - po³±czenie i wys³anie na port TCP/IP (tryb bezpo¶redni) -y tryb - (przekazywane jako -Z tryb) -- - koniec opcji, reszta to pliki nazwa pliku '-' oznacza odczyt z STDIN Zmienne PRINTER, LPDEST, NGPRINTER, NPRINTER wybieraj± domy¶ln± drukarkê. Sk³adnia: %s [-Pdrukarka[@host]] [-A] [-B] [-Cklasa] [-Fformat] [-G] [-Jinfo] [-(K|#)kopii] [-Q] [-Rnazwakonta] [-Ttytu³] [-Uu¿ytkownik[@host]] [-V] [-Zopcje] [-b] [-m adrespoczty] [-h] [-i wciêcie] [-l] [-w szeroko¶æ] [-r] [-Dopcje¶ledzenia ] [--] [ nazwy plików ... ] -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± AUTH -B - filtrowanie plików i zmniejszenie zadania do pojedynczego pliku przed wys³aniem -C klasa - klasa zadania -D opcje¶ledzenia - flagi ¶ledzenia -F format - format zadania -b,-l - format binarny lub dok³adny c,d,f,g,l,m,p,t,v tak¿e s± opcjami formatu -G - filtrowanie poszczególnych plików zadañ przed wys³aniem -J info - informacje o nag³ówku i zadaniu -K kopii, -# kopii - liczba kopii -P drukarka[@host] - drukarka na ho¶cie -Q - umieszczenie 'nazwy kolejki' w pliku kontrolnym -Rnazwakonta - informacje do rozliczeñ -T tytu³ - tytu³ dla formatowania 'pr' (-p) -U u¿ytkownik - wymuszenie nazwy u¿ytkownika (ograniczone) -V - szczegó³owe informacje podczas kolejkowania -X ¶cie¿ka - w³asny filtr dla plików zadañ -Y - po³±czenie i wys³anie na port TCP/IP (tryb bezpo¶redni) -Z opcje - opcje do przekazania do filtra -h - bez nag³ówka ani strony nag³ówkowej -i wciêcie - obs³uga wciêæ -k - nie u¿ywanie pliku tymczasowego przy wysy³aniu do serwera -m adres - wys³anie statusu poczt± na adres -r - usuniêcie plików po skolejkowaniu -w szer - szeroko¶æ do wykorzystania -- - koniec opcji, reszta to pliki nazwa pliku '-' oznacza odczyt z STDIN Zmienne PRINTER, LPDEST, NPRINTER, NGPRINTER wybieraj± domy¶ln± drukarkê. Sk³adnia: move drukarka (u¿ytkownik|idzadania)* celUWAGA: g³ówny serwer rozk³adaj±cy obci±¿enie móg³ zakoñczyæ pracê przed poinformowaniem, ¿e s± nowe zadania. Proszê u¿yæ 'lpc start %s', aby uruchomiæ serwer Wait_for_subserver: B£¡D LOGIKI! oczekiwanie na pid %d nie powiod³o siêWait_for_subserver: Mergesort nie powiod³o siêczekanie %d sekund przed powtórzeniem STDIN jest zamkniête! nie mo¿na utworzyæ potoku z zamkniêtego po³±czeniaabortprzerwano zadanieprzerywanie operacjiprzerwanie zadaniawszystkowszystkie klasy wydrukowane uwierzytelnienie jest w konflikcie z opcj± -k¿±dano uwierzytelnienia (opcja -A), ale nie ustawiono zmiennej ¶rodowiskowej AUTHb³êdny ³añcuch formatuj±cy -F '%s' b³êdna linia poleceniab³êdna linia polecenia '%s'b³êdne polecenie kontrolne '%s'b³êdna informacja o d³ugo¶ci '%s'b³êdna drukarka '%s'b³êdna nazwa drukarkib³êdna nazwa drukarki '%s'nie mo¿na otworzyæ lub zablokowaæ pliku blokuj±cego - %snie mo¿na wydrukowaæ '%s': %snie mo¿na tego przeczytaænie mo¿na uaktualniæ pliku biletu zadania '%s'nie mo¿na uaktualniæ pliku biletu zadania dla '%s'nie mo¿na u¿yæ drukarki - spoza uprzywilejowalnej grupy klasa uaktualnionawydrukowane klasy '%s' po³±czenie z serwerem rozliczeñ '%s' nie powiod³o siê: '%s'nie mo¿na usun±æ zadania '%s'wymuszenie ¶ledzenia wy³±czonewymuszenie ¶ledzenia ustawione na '%s'wy³±czonowy³±czono i zatrzymanodoaction: waitpid(%ld) nie powiod³o siêpowtórzona specyfikacja formatu -%c powtórzona specyfikacja formatu -F%s w³±czonow³±czono i uruchomionob³±d: nie mo¿na usun±æ '%s'execvp nie powiod³o siê - '%s'koniecwys³anie zadania '%s' nie powiod³o siênie powiod³o siê, bez ponownych próbpliki w linii poleceñ s± w konflikcie z opcj± -kwyczyszczono stanfork nie powiod³o siê - '%s'fork() nie powiod³o siêprzekazywanie wy³±czone przekazywanie do '%s' informacje o t³umaczeniu gettext '%s' holdwznowiono wszystkowstrzymano wszystkowstrzymywanie zadaniajabortjholdzadanie '%s' próba %d, próbowanie %d razyzadanie '%s' próba %d, próbowanie bez koñcazadanie '%s' usuniêtezadanie '%s' usuniête - status wygas³zadanie '%s' zachowanezadanie '%s', %szadanie '%s', próba %d, dozwolonych %djremovejsuccjsuccesszabicie procesu serwera PID %ld przez %s usuniêto zadanieb³±d po³±czenia podczas wysy³ania zadania '%s'lpd: Nie mo¿na otworzyæ pliku blokuj±cego '%s'lpd: Nie mo¿na skróciæ pliku blokuj±cegolpd: EOF potoku w Lpd_request! niemo¿liwelpd: accept na gnie¼dzie s³uchaj±cym nie powiod³o siêlpd: nie mo¿na uruchomiæ pocz±tkowego procesu loguj±cegolpd: fork() nie powiod³o siêlpd: main() dofork nie powiod³o siêlpd: wywo³anie pipe nie powiod³o siêlpd: b³±d select!lpq: proszê u¿yæ programu LPRng lpstat brak nazwy u¿ytkownika lub drukarkiprzeniesienie wykonanewiele kopii jest w konflikcie z opcj± -kbrak uprawnieñ do po³±czeniabrak obs³ugi sieci dla operacji '%s'brak uprawnieñ do kontrolowania serwerabrak uprawnieñ do skolejkowania zadania '%s'brak obs³ugiwanej metody otrzymywania dla '%s'brak zdalnej obs³ugi dla %s@%sbez ponawianiabrak celu domy¶lnego dla systemu beznag³ówkanie jest zwyk³ym plikiemjeszcze nie zaimplementowanonie ma niczego do wydrukowaniaprzy opcji %c parametr `%s` nie jest liczb± ca³kowit± od 0 do %dprzy opcji %c parametr `%s` nie jest dodatni± liczb± ca³kowit±przy opcji '%c' brakuje argumentudrukarka %s zadanie %sdrukarka %s w nieznanym stanie. Wy³±czona od %s. Dostêpna drukarka %s w nieznanym stanie. W³±czona od %s. Dostêpna drukarka '%s' ma nieprawid³owy znak przy '%s' w nazwiedrukarka '%s' ma nieprawid³owy znak przy '%s' w nazwieprzekierowanoremoveusuwanie celu z powodu b³êdówusuwanie zadania '%s' - JABORTusuwanie zadania '%s' - JFAILNORETRYusuwanie zadania '%s' - JREMOVEusuwanie zadania '%s' - brak uprawnieñusuwanie zadania - status JREMOVEid ¿±dania to %d id ¿±dania to %s ponawianie próbyszeregowanie dzia³a opcja konfiguracji send_block_format jest w konflikcie z opcj± -kopcja konfiguracji send_data_first jest w konflikcie z opcj± -kproces serwera PID %ld zakoñczy³ siê rozmiar %0.3fK przekracza %dKczekanie %d sekund przed powtórzeniem, rozpoczêcie czekaniaoczekiwanie na zakoñczenie procesówuruchomionozatrzymanozatrzymywanie drukowania po kodzie wyj¶cia filtra JABORTpodserwer pid %ld umar³ od sygna³u '%s'podserwer pid %ld zakoñczony ze statusem '%s'succsuccesscel domy¶lny dla systemu: %s system dla %s: %s za du¿o b³êdówtraktowane jako pomy¶lnenieoczekiwany status 0x%xniedrukowalne znaki na pocz±tku pliku - nale¿y sprawdziæ zmienn± ¶rodowiskow± LANG oraz plik wej¶ciowynieobs³ugiwane uwierzytelnienie '%s'Sk³adnia: %s [-FV][-D dbg][-L log][-P gniazdo][-p port][-R port TCP/IP zdalnego LPD] Opcje -D dbg - ustawienie poziomu i flag ¶ledzenia -F - uruchomienie na pierwszym planie, logi na STDERR -L plikloga - do³±czanie logowanych informacji do plikuloga -V - pokazanie informacji o wersji -p port - port nas³uchuj±cy TCP/IP, 'off' wy³±cza nas³uch TCP/IP (lpd_listen_port) -P gniazdo - ¶cie¿ka gniazda uniksowego, 'off' wy³±cza gniazdo (unix_socket_path) -R port - port zdalnego serwera LPD (lpd_port) Sk³adnia: %s [-aAclV] [-Dpoziom] [-Pdrukarka] [-tczasoczek] -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± AUTH -a - wszystkie drukarki -c - wyczyszczenie ekranu przed uaktualnieniem -l - zwiêkszenie (wyd³u¿enie) szczegó³owych informacji o stanie dodatkowe flagi l dodaj± wiêcej szczegó³ów. -L - najbardziej szczegó³owe informacje o stanie -n linii - tyle linii szczegó³owych informacji o stanie -Dpoziom - poziom ¶ledzenia (debug level) -Pdrukarka - podanie drukarki -s - krótki (sumaryczny) format -tczasoczek - czas oczekiwania miêdzy uaktualnieniami -V - wypisanie informacji o wersji -v - wypisanie w postaci klucz: warto¶æ Sk³adnia: %s [-a][-Dpoziom][-Pdrukarka][-Shost][-Uu¿ytkownik][-V] [polecenie] bez podanego polecenia czyta ze standardowego wej¶cia -a - alias dla -Pall -Dpoziom - poziom ¶ledzenia (debug level) -Pdrukarka - drukarka -Pdrukarka@host - drukarka na serwerze lpd na ho¶cie -Shost - po³±czenie z serwerem lpd na ho¶cie -Uu¿ytkownik - identyfikacja polecenia jako pochodz±ce od u¿ytkownika -V - zwiêkszenie ilo¶ci informacji polecenia: active (drukarka[@host]) - sprawdzenie aktywno¶ci serwera abort (drukarka[@host] | all) - zatrzymanie serwera class drukarka[@host] (klasa | off) - pokazanie/ustawienie drukowania klas disable (drukarka[@host] | all) - wy³±czenie kolejkowania debug (drukarka[@host] | all) parametry - ustawienie poziomu ¶ledzenia down (drukarka[@host] | all) - wy³±czenie drukowania i kolejkowania enable (drukarka[@host] | all) - w³±czenie kolejkowania flush (drukarka[@host] | all) - wyczyszczenie zapamiêtanego stanu hold (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - wstrzymanie zadania holdall (drukarka[@host] | all) - wstrzymanie wszystkich zadañ kill (drukarka[@host] | all) - zatrzymanie i restart serwera lpd (drukarka[@host]) - odczyt PID-u LPD lpq (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - wywo³anie LPQ lprm (drukarka[@host] | all) (nazwa[@host]|host|zad.|all)*- wywo³anie LPRM msg drukarka komunikat tekst - ustawienie komunikatu o stanie move drukarka (u¿ytkownik|idzad)* cel - wys³anie zadañ do nowej kolejki noholdall (drukarka[@host] | all) - wznowienie wszystkich zadañ printcap (drukarka[@host] | all) - przekazanie warto¶ci printcap quit - zakoñczenie LPC redirect (drukarka[@host] | all) (drukarka@host|off)* - przekierowanie zadañ redo (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - ponowny wydruk zadañ release (drukarka[@host] | all) (nazwa[@host]|zad.|all)* - uwolnienie zadañ reread - ponowne odczytanie bazy informacji LPD start (drukarka[@host] | all) - uruchomienie drukowania status (drukarka[@host] | all) - stan drukarek stop (drukarka[@host] | all) - zatrzymanie drukowania topq (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - zamiana zadañ up (drukarka[@host] | all) - w³±czenie drukowania i kolejkowania diagnostyka: defaultq - pokazanie domy¶lnej kolejki serwera LPD defaults - pokazanie domy¶lnych warto¶ci ustawieñ lang - pokazanie aktualnie obs³ugiwanej lokalizacji client (drukarka | all) - informacja o konfiguracji i printcap klienta server (drukarka | all) - konfiguracja i printcap serwera szeroko¶æb³êdna liczba argumentów - %dlprng-3.8.B/po/vi.gmo0000644000131400013140000013665411531672374011367 00000000000000Þ•Kt »Ì¸¹ÎÕ å óý )D X<f£ºË â íø ý   %0?P _m's › ¼ ÉÖß ð0#Ko‰  ª Ä ÎØ"ñ'<EN®k!$,$$D$ i$ u$‚$”$ ´$5Á$÷$ % % %+9%=e%%£%É%è%& &&<&c&‚&š& µ&Ö&!é& '%!' G'h' p'}'2–'&É'2ð'#()(80(i(‡((”((®('×(%ÿ(%)+)4)=)E)-J)-x))¦)%Ð).ö)<%*(b*1‹*5½*&ó*+#+%*+P+j+p+)Œ+¶+Ó+Ø+à+÷+ü+,!,%,),".,Q,V,Z,n,‹, ,§,Â,Ü,à,é,ù,1-24-:g-/¢-&Ò-ù-B.R.[.`.h.$o.+”.&À.&ç.%/(4/,]/Š/‘/—/ž/"£/!Æ/$è/* 0,80=e0&£0,Ê06÷0).16X1&1¶1Ô1 î162F2 ^22„2•2´2#·2%Û2C3E9&G?šn?: @$D@ i@;Š@Æ@ Ì@Ø@ì@ü@A&AJFDF$MF rF#}F¡FÁF(àF& G(0GYGlG†GœG*¯GÚG ÷G'H)H%@HfH†H$¦HËHçHðHII+I?I9PI6ŠIÁIÞI7ðI6(J-_J2J ÀJËJ"ÒJõJ K1K"MKpKŽK K ²K¿K>ÕK<LQLpL-ˆL'¶LÞLæL,îL'M"CMfMkMsM“M¦M¶MÍMgäMLNñlN¤^PÝ Sá\ç\¯]²^Ä^Ë^ Û^ è^ò^_A_#[__]˜_*ö_.!`P`o`†`˜`` ¹`Æ`Ö`ð` aa*aBa.Ha-wa ¥a²aÁaÊaBáa$bG6b4~b3³b"çb c&cBc \cgc*c>¬cëc dØdŽèfwj‡j=žjÜjðj k)+k UkEbk¨k½k Òkßk(ÿkW(l"€l1£l.Õl&m +m1Lm%~m&¤mËm1åmn"1n,Tn)n2«nÞn æn!òn/oSDo/˜o ÈoÓoPâo'3p[pbp(ipF’pEÙp1q Qq\q wq…q‹q;“q5Ïq(r7.rMfr@´r9õrL/sP|s)Ís÷st? t1Mt t‹t\«t$u -u9uPuku ru0~u¯u³u·u6¼uóuüu v #vDvVv'tvœv»v¿vÈvØvLávQ.w[€wFÜw6#xZxmqxßx ñx üx y,y.By8qy7ªy(ây1 z@=z~z‘z ˜z¦z*­z&Øz@ÿz/@{1p{I¢{Cì{:0|Ck|:¯|Qê|:<}!w}™}%²}VØ}/~*M~x~Œ~"Ÿ~Â~<Ç~9ˆ>\LJa$ï†8v‘(¯‘/Ø‘…’ Ž’™’¶’#Ö’ ú’“2“bN“'±“Ù“ê“#”"(”K”`”q”2‹”¾”Û”=ó”A1•Ks•!¿•á•Kú•,F–&s–:š–Õ–Û–!ø–)—'D—l—r—&—¶—Ê—!Ñ—'ó—C˜_˜$~˜5£˜Ù˜%õ˜#™ ?™!K™!m™™®™Æ™:ß™;š$VšG{š(Úìš3›:›Q›Z›?t›´›7Í›/œ.5œidœ4ΜCG^|™8¬'å ž8žWž?vž5¶ž@ìžA-Ÿ'oŸ—Ÿ3ªŸÞŸðŸ - SE O™ (é ¡@-¡@n¡;¯¡<ë¡(¢ ?¢I¢0i¢6š¢1Ñ¢<£6@£$w£$œ£Á£&à£t¤q|¤.î¤ ¥G>¥-†¥´¥Ç¥)Ú¥G¦>L¦‹¦ ’¦,Ÿ¦̦å¦!ø¦"§“=§/ѧï¨ñªk® |½"‰½ÕAž R?"Ë3a㨀é›Kˆ7%ä«èÝÔëqìz¯fÖ7.E¡(ÈX×p CîØ‚vð´±å/s;“Q3yíV'}|Akµ ÁÓ¬6˜x5b*c¤\ÇI!¦¥ Ãôu®+ï ¼ò>ÏGÆÙJ]`w9@@ûÒd*ó:D$©Å>ñçþÐÑ=t i86#L{æ/$&4ÿlúŒ„M ¸…» Z™ÄƒJ̶W%áâ,m¢ 'ùBO—³PÛ22 œ))NY­H&·ªC; ¾’Žn=‘"²”4à–F1ÚeÜÞ°1 #!ß§÷[ÊSo½FBŠÉšŸ¹+ _†‹(DU<ê,º8--^üh50À:öÂEIT‰jÍ?Î9HGøý<r.õ~0K‡¿•g£ Description: %s@%s %s: Auto_hold: on Classes: %s Error: Hold_all: on Message: %s Printing: %s Aborted: %s Spooling: %s Redirected_to: %s Serving: %s Printer: %s - cannot use printer, not in privileged group checking perms '%s' dequeued '%s' no permissions '%s' (%d held) (%d move) (%s (autohold) (classes %s) (dest %s@%s) (holdall) (message: %s) (originally %s) (redirect %s) (serving %s) - %s - printer %s@%s has bad printcap entry - printer %s@%s not in printcap Comment: %s ERROR: Filter_status: Holding: %d held jobs in queue Job: %s Printer: %s - direct connection to device '%s' Queue: no printable jobs in queue Server: no server active Server: pid %d active Status: Unspooler: pid %d active autohold class=%s died a horrible death. failed and could not be retried. failed, and retry count was exceeded. holdall of %d: usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer] -A - use authentication -Ddebuglevel - debug level user removes user jobs all removes all jobs jobid removes job number jobid Example: 'clean 30 lp' removes job 30 on printer lp 'clean' removes first job on default printer 'clean all' removes all your jobs on default printer 'clean all all' removes all your jobs on all printers Note: clean removes only jobs for which you have removal permission usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')* -a - all printers -A - use authentication -Pprinter - printer (default PRINTER environment variable) -Uuser - impersonate this user (root or privileged user only) -Ddebuglevel - debug level -V - show version information user removes user jobs all removes all jobs jobid removes job number jobid Example: 'lprm -Plp 30' removes job 30 on printer lp 'lprm -a' removes all your jobs on all printers 'lprm -a all' removes all jobs on all printers Note: lprm removes only jobs for which you have removal permission was successful. # Printcap Information %d data files and maximum allowed %d%s CONTROL=%s HOLDFILE=%s SPOOLCONTROL= %s accepting requests since %s %s error= %s%s not accepting requests since %s - unknown reason %s size= %0.0f%s status= %s%s time= %s%s: Illegal option '%c' %s: Receive_block_job: sending ACK 0 failed%s: Receive_job - bad control line '%s', len %0.0f, name '%s'%s: Receive_job: sending ACK 0 failed%s: cannot set hold file '%s' %s: cannot set up print queue%s: cannot set up printer%s: insufficient file space%s: job size %0.0f is larger than %d K%s: missing argument for '%c' %s: no permission '%s' %s: no permission to print%s: no permission to show status%s: selected '%s' %s: sending ACK 0 for '%s' failed%s: spooling disabled%s: transfer of '%s' from '%s' failed%s: unknown control request '%s'(STDIN)(lpr_filter)--X option form illegal -Kcopies -number of copies must be greater than 0 -U (username) can only be used by ROOT-ncopies -number of copies must be greater than 0 ABORTACTIVEAnother print spooler active, possibly lpd process '%ld'Bad format specification '%c'CLASSCLIENTCannot open file '%s', %sCheck_files: stat of temp fd '%d' failedCopy_STDIN: stat of temp fd '%d' failedCopy_STDIN: write to temp file failedDEBUGDEFAULTQDEFAULTSDISABLEDOWNDispatch_input: bad request line '%s' from %sDo_incoming_control_filter: lseek failed '%s'Do_queue_control: write to fd '%d' failedDo_queue_jobs: FORWARDING LOOP - '%s'Do_queue_jobs: LOGIC ERROR - no identifer '%s'Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %dDo_queue_jobs: cannot open lockfile '%s'Do_queue_jobs: cannot update job ticket file '%s'Do_queue_jobs: cannot update job ticket file for '%s'Do_queue_jobs: write to fd '%d' failedDone %d ENABLEError setting up job ticket file - %sError unlinking '%s' - %sFLUSHFork_subserver: fork failedGet_local_host: '%s' FQDN name not found!Get_route: lseek failed '%s'HOLDHOLDALLJob_remove: error '%s'KILLLANGLANG environment variable '%s' LPDLPQLPRMLocale information directory '%s' MOVEMSGMake_temp_fd failedMaximum of %d copies allowedMissing mail nameNOHOLDALLNo LPD lockfile specified!No translation available PPDPRINTCAPPrinter %s@%s: Printer:Printer: %s - cannot get status from device '%s' Printer: %s - cannot remove jobs from device '%s' Printer: %s - cannot use printer, not in privileged group Printer: %s - direct connection to device '%s' Printer: %s - not in privileged group Printer: %s is %s@%s Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)REDIRECTREDORELEASEREREADReceive_block_job: lseek failed '%s'Receive_block_jobs: write to fd '%d' failedReceive_job: cannot lock lockfile '%s'Receive_job: cannot open lockfile '%s'Receive_jobs: write to fd '%d' failedRecovering from incorrect job submissionRemote_job: %d datafiles and only allowed %dSERVERSTARTSTATUSSTOPScan_block_file: lseek failed '%s'Scan_block_file: read failed '%s'Scan_block_file: read unexecpted EOFService_connection: BAD LocalHost_IP valueService_connection: bad protocol family '%d'Service_connection: cannot read request from %s in %d secondsService_connection: getpeername failedService_connection: peek of length %d failedService_connection: short request line '%s', from '%s'Service_worker: cannot open lockfile '%s'Service_worker: cannot update job ticket file for '%s'Service_worker: no identifier for '%s'Setup_log: dup2(%d,%d) failedSetup_log: open %s failedSetup_log: open /dev/null failedSorry, can only print %d files at a time, split job upStart_all: pipe failed!Status Information, attempt %d: TOPQTRANSLATION TESTTerm_clear: waitpid(%d) failedUPUSER environment variable undefinedUpdate_status: no identifier for '%s'Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]] [-f form-name] [-H special-handling] [-n number] [-o options] [-P page-list] [-q priority-level] [-S character-set] [-S print-wheel] [-t title] [-T content-type [-r]] [-y mode-list] [-Ddebugopt ] [ filenames ... ] lp simulator using LPRng, functionality may differ slightly -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -c - (make copy before printing - ignored) -d printer[@host] - printer on host -D debugflags - debugging flags -f formname - first letter used as job format -G - filter individual job files before sending -H handling - (passed as -Z handling) -m - mail sent to $USER on completion -n copies - number of copies -o option nobanner, width recognized (others passed as -Z option) -P pagelist - (print page list - ignored) -p - (notification on completion - ignored) -q - priority - 0 -> Z (highest), 25 -> A (lowest) -s - (suppress messages - ignored) -S charset - (passed as -Z charset) -t title - job title -T content - (passed as -Z content) -w - (write message on completion - ignored) -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -y mode - (passed as -Z mode) -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default printer. Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo] [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V] [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r] [-Ddebugopt ] [--] [ filenames ... ] -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -C class - job class -D debugopt - debugging flags -F format - job format -b,-l - binary or literal format c,d,f,g,l,m,p,t,v are also format options -G - filter individual job files before sending -J info - banner and job information -K copies, -# copies - number of copies -P printer[@host] - printer on host -Q - put 'queuename' in control file -Raccntname - accounting information -T title - title for 'pr' (-p) formatting -U username - override user name (restricted) -V - Verbose information during spooling -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -Z options - options to pass to filter -h - no header or banner page -i indent - indentation -k - do not use tempfile when sending to server -m mailaddr - mail final status to mailaddr -r - remove files after spooling -w width - width to use -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default printer. Use: move printer (user|jobid)* targetWARNING: the main load balance server may have exited before it could be informed that there were new jobs. Please use 'lpc start %s' to start the server Wait_for_subserver: LOGIC ERROR! waiting for pid %d failedWait_for_subserver: Mergesort failedWaiting %d seconds before retry You have closed STDIN! cannot pipe from a closed connectionabortaborted jobaborting operationsaborting serverallall classes printed authentication conficts with -k optionauthentication requested (-A option) and AUTH environment variable not setbad -F format string '%s' bad command linebad command line '%s'bad control command '%s'bad length information '%s'bad printer '%s'bad printer namebad printer name '%s'cannot open or lock lockfile - %scannot print '%s': %scannot read itcannot update job ticket file '%s'cannot update job ticket file for '%s'cannot use printer - not in privileged group class updatedclasses printed '%s' connection to accounting server '%s' failed '%s'could not remove job '%s'debugging override offdebugging override set to '%s'disableddisabled and stoppeddoaction: waitpid(%ld) failedduplicate format specification -%c duplicate format specification -F%s enabledenabled and startederror: could not remove '%s'execvp failed - '%s'exitfailed to send job '%s'failed, no retryfiles on command line conflicts with -k optionflushed statusfork failed - '%s'fork() failedforwarding off forwarding to '%s' gettext translation information '%s' holdholdall offholdall onholding jobjabortjholdjob '%s' attempt %d, trying %d timesjob '%s' attempt %d, trying indefinitelyjob '%s' removedjob '%s' removed- status expiredjob '%s' savedjob '%s', %sjob '%s', attempt %d, allowed %djremovejsuccjsuccesskill server process PID %ld with %s killed joblink failure while sending job '%s'lpd: Cannot open lock file '%s'lpd: Cannot truncate lock filelpd: Lpd_request pipe EOF! cannot happenlpd: accept on listening socket failedlpd: cannot start initial logger processlpd: fork() failedlpd: main() dofork failedlpd: pipe call failedlpd: select error!lpq: please use the LPRng lpstat program missing user or printer namemove donemultiple copies conficts with -k optionno connect permissionsno network support for '%s' operationno permission to control serverno permission to spool job '%s'no receive method supported for '%s'no remote support for %s@%sno retryno system default destination nobannernot a regular filenot implemented yetnothing to printoption %c parameter `%s` is not integer value from 0 - %doption %c parameter `%s` is not positive integer valueoption '%c' missing argumentprinter %s job %sprinter %s unknown state. disabled since %s. available printer %s unknown state. enabled since %s. available printer '%s' has illegal char at '%s' in nameprinter '%s' has illegal character at '%s' in nameredirectedremoveremoving destination due to errorsremoving job '%s' - JABORTremoving job '%s' - JFAILNORETRYremoving job '%s' - JREMOVEremoving job '%s' - no permissionsremoving job - status JREMOVErequest id is %d request id is %s retrying jobscheduler is running send_block_format configuration option conficts with -k optionsend_data_first configuration option conficts with -k optionserver process PID %ld exited size %0.3fK exceeds %dKsleeping %d secs before retry, starting sleepsleeping, waiting for processes to exitstartedstoppedstopping printing on filter JABORT exit codesubserver pid %ld died with signal '%s'subserver pid %ld exit status '%s'succsuccesssystem default destination: %s system for %s: %s too many errorstreating as successfulunexpected status 0x%xunprintable characters at start of file, check your LANG environment variable as well as the input fileunsupported authentication '%s'usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP destination port] Options -D dbg - set debug level and flags -F - run in foreground, log to STDERR -L logfile - append log information to logfile -V - show version info -p port - TCP/IP listen port, 'off' disables TCP/IP listening port (lpd_listen_port) -P path - UNIX socket path, 'off' disables UNIX listening socket (unix_socket_path) -R port - remote LPD server port (lpd_port) usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime] -A - use authentication specified by AUTH environment variable -a - all printers -c - clear screen before update -l - increase (lengthen) detailed status information additional l flags add more detail. -L - maximum detailed status information -n linecount - linecount lines of detailed status information -Ddebuglevel - debug level -Pprinter - specify printer -s - short (summary) format -tsleeptime - sleeptime between updates -V - print version information -v - print in key: value format usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command] with no command, reads from STDIN -a - alias for -Pall -Ddebuglevel - debug level -Pprinter - printer -Pprinter@host - printer on lpd server on host -Shost - connect to lpd server on host -Uuser - identify command as coming from user -V - increase information verbosity commands: active (printer[@host]) - check for active server abort (printer[@host] | all) - stop server class printer[@host] (class | off) - show/set class printing disable (printer[@host] | all) - disable queueing debug (printer[@host] | all) debugparms - set debug level for printer down (printer[@host] | all) - disable printing and queueing enable (printer[@host] | all) - enable queueing flush (printer[@host] | all) - flush cached status hold (printer[@host] | all) (name[@host] | job | all)* - hold job holdall (printer[@host] | all) - hold all jobs on kill (printer[@host] | all) - stop and restart server lpd (printer[@host]) - get LPD PID lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke LPRM msg printer message text - set status message move printer (user|jobid)* target - move jobs to new queue noholdall (printer[@host] | all) - hold all jobs off printcap (printer[@host] | all) - report printcap values quit - exit LPC redirect (printer[@host] | all) (printer@host | off )* - redirect jobs redo (printer[@host] | all) (name[@host] | job | all)* - reprint jobs release (printer[@host] | all) (name[@host] | job | all)* - release jobs reread - LPD reread database information start (printer[@host] | all) - start printing status (printer[@host] | all) - status of printers stop (printer[@host] | all) - stop printing topq (printer[@host] | all) (name[@host] | job | all)* - reorder jobs up (printer[@host] | all) - enable printing and queueing diagnostic: defaultq - show default queue for LPD server defaults - show default configuration values lang - show current i18n (iNTERNATIONALIZATIONn) support client (printer | all) - client config and printcap information server (printer | all) - server config and printcap widthwrong number arguments, %dProject-Id-Version: lprng 3.8.A Report-Msgid-Bugs-To: lprng-devel@lists.sf.net POT-Creation-Date: 2011-02-03 19:40+0100 PO-Revision-Date: 2008-07-15 23:31+0930 Last-Translator: Clytie Siddall Language-Team: Vietnamese MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; X-Generator: LocFactoryEditor 1.7b3 Mô tả: %s@%s %s: Auto_hold: on Hạng: %s Lá»—i: Hold_all: bật Thông Ä‘iệp: %s Äang in: %s Äã há»§y bá» : %s Äang cuá»™n vào ống: %s Äã_chuyển_hướng_đến: %s Äang phục vụ : %s Máy in: %s — không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n Ä‘ang kiểm tra quyá»n hạn « %s » đã gỡ bỠ« %s » khá»i hàng đợi không có quyá»n « %s » (%d đã giữ lại) (%d di chuyển) (%s (tá»± động giữ lại) (hạng %s) (đích %s@%s) (giữ lại tất cả) (thông Ä‘iệp: %s) (gốc %s) (chuyển hướng %s) (Ä‘ang phục vụ %s) - %s - máy in %s@%s có mục nhập printcap sai - máy in %s@%s không phải trong printcap Ghi chú : %s Lá»–I: Trạng_thái_lá»c: Giữ lại: %d công việc đã giữ lại trong hàng đợi Công việc: %s Máy in: %s — kết nối trá»±c tiếp tá»›i thiết bị « %s » Hàng đợi: không có công việc có thể in Phục vụ : không có trình phục vụ chạy Phục vụ : PID %d Ä‘ang chạy Trạng thái: Bá»™ bá» cuá»™n: PID %d Ä‘ang chạy tá»± động giữ lại hạng=%s chết khá»§ng khiếp. bị lá»—i và không thể thá»­ lại. bị lá»—i, cÅ©n vượt quá số đếm lần thá»­ lại. giữ lại tất cả trên %d: usage: %s [-A] [-Dcấp_gỡ_lá»—i] (jobid|user|'all')* [máy_in] -A — dùng sá»± xác thá»±c -Dcấp_gỡ_lá»—i — cấp gỡ lá»—i user — gỡ bá» các công việc cá»§a ngưá»i dùng all — gỡ bá» má»i công việc jobid — gỡ bá» công việc có mã nhận diện này Thí dụ : 'clean 30 lp' gỡ bá» công việc 30 trên máy in lp 'clean' gỡ bá» công việc thứ nhất trên máy in mặc định 'clean all' gỡ bá» má»i công việc cá»§a bạn trên máy in mặc định 'clean all all' gỡ bá» má»i công việc cá»§a bạn trên má»i máy in Ghi chú : clean gỡ bá» chỉ những công việc cho đó bạn có quyá»n gỡ bá». cách sá»­ dụng: %s [-A] [-a | -Pmáy_in] [-Dcấp_gỡ_lá»—i] (jobid|user|'all')* -a — má»i máy in -A — dùng sá»± xác thá»±c -Pmáy_in — máy in (biến môi trưá»ng PRINTER mặc định) -Ungưá»i_dùng — nhận diện là ngưá»i dùng này (chỉ ngưá»i chá»§ hay ngưá»i dùng có quyá»n đặc biệt) -Dcấp_gỡ_lá»—i — cấp gỡ lá»—i -V — hiển thị thông tin phiên bản user — gỡ bá» các công việc cá»§a ngưá»i dùng all — gỡ bá» má»i công việc jobid — gỡ bá» công việc có mã nhận diện này Thí dụ : 'lprm -Plp 30' gỡ bá» công việc 30 trên máy in lp 'lprm -a' gỡ bá» má»i công việc cá»§a bạn trên má»i máy in 'lprm -a all' gỡ bá» má»i công việc trên má»i máy in Ghi chú : lprm gỡ bá» chỉ những công việc cho đó bạn có quyá»n gỡ bá». thành công. # Thông tin Printcap có %d tập tin dữ liệu còn cho phép số tối Ä‘a %d%s ÄIỀU_KHIỂN=%s TẬP_TIN_GIá»®_LẠI=%s ÄIỀU KHIỂN á»NG CHỈ= %s chấp nhận yêu cầu kể từ %s %s lá»—i= %s%s không chấp nhận yêu cầu kể từ %s - không biết sao %s kích cỡ= %0.0f%s trạng thái= %s%s giá»= %s%s: tùy chá»n cấm « %c » %s: Receive_block_job: lá»—i gá»­i ACK 0%s: Receive_job — dòng Ä‘iá»u khiển sai « %s », độ dài %0.0f, tên « %s »%s: Receive_job: lá»—i gá»­i ACK 0%s: không thể đặt tập tin giữ lại %s %s: không thể thiết lập hàng đợi in%s: không thể thiết lập máy in%s: không đủ chá»— tập tin%s: kích cỡ công việc %0.0f lá»›n hÆ¡n %d K%s: thiếu đối số cho « %c » %s: không có quyá»n hạn « %s » %s: không có quyá»n in%s: không có quyá»n hiển thị trạng thái%s: đã chá»n « %s » %s: lá»—i gá»­i ACK 0 cho « %s »%s: khả năng cuá»™n vào ống bị tắt%s: lá»—i truyá»n « %s » từ « %s »%s: yêu cầu Ä‘iá»u khiển không rõ « %s »(STDIN)(lá»c_lpr)Tùy chá»n --X có dạng cấm -Kcopies — tổng số bản sao phải ≥0 -U (tên ngưá»i dùng) chỉ có thể được dùng bởi ngưá»i chá»§ (root)-ncopies — tổng số bản sao phải ≥0 HỦY_BỎHOẠT_ÄỘNGBá»™ cuá»™n vào ống khác Ä‘ang chạy, có thể tiến trình lpd « %ld »Äặc tả định dạng sai « %c »HẠNGKHÃCHKhông thể mở tập tin « %s », %sCheck_files: lá»—i lấy các thông tin vá» fd tạm thá»i « %d »Copy_STDIN: lá»—i lấy các thông tin vá» fd tạm thá»i « %d »Copy_STDIN: lá»—i ghi vào tập tin tạm thá»iGá»  Lá»–IHÀNG ÄỢI MẶC ÄỊNHMẶC ÄỊNHTẮTXUá»NGDispatch_input: dòng yêu cầu sai « %s » từ « %s »Do_incoming_control_filter: lseek bị lá»—i « %s »Do_queue_control: lá»—i ghi vào fd '%d'Do_queue_jobs: VÃ’NG LẶP CHUYỂN TIẾP — « %s »Do_queue_jobs: Lá»–I HỢP Là — không có bá»™ nhận diện cho « %s »Do_queue_jobs: Lá»–I HỢP LÃ. new_dest và use_subserver == %dDo_queue_jobs: không thể mở tập tin khoá « %s »Do_queue_jobs: không thể cập nhật tập tin vé công việc « %s »Do_queue_jobs: không thể cập nhật tập tin vé công việc cho « %s »Do_queue_jobs: lá»—i ghi vào fd « %d »Hoàn tất %d BẬTGặp lá»—i khi thiết lập tập tin vé công việc — %sGặp lá»—i khi há»§y liên kết « %s » — %sXOà SẠCHFork_subserver: fork bị lá»—iGet_local_host: không tìm thấy tên miá»n có khả năng đầy đủ (FQDN) « %s ».Get_route: lseek bị lá»—i « %s »GIá»® LẠIGIá»® LẠI TẤT CẢJob_remove: lá»—i « %s »GIẾTNGÔN NGá»®Biến môi trưá»ng ngôn ngữ LANG « %s » LPDLPQLPRMThư mục thông tin miá»n địa phương « %s » CHUYỂNTHÔNG ÄIỆPMake_temp_fd bị lá»—iCho phép %d bản sao tối Ä‘aThiếu tên thưKHÔNG GIá»® LẠI TẤT CẢChưa xác định tập tin khoá LPD.Không có sẵn bản dịch PPDPRINTCAPMáy in %s@%s: Máy in:Máy in: %s — không thể lấy trạng thái từ thiết bị « %s » Máy in: %s — không thể gỡ bá» công việc khá»i thiết bị « %s » Máy in: %s — không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n Máy in: %s — kết nối trá»±c tiếp tá»›i thiết bị « %s » Máy in: %s — không phải trong nhóm có quyá»n Máy in: %s là %s@%s Äá»™ ưu tiên (chữ đầu cá»§a Hạng) không phải « A » (thấp nhất) đến « Z » (cao nhất)CHUYỂN HƯỚNGLÀM LẠIPHÃT HÀNHÄỌC LẠIReceive_block_job: lseek bị lá»—i « %s »Receive_block_jobs: lá»—i ghi vào fd « %d »Receive_job: không thể khoá tập tin khoá « %s »Receive_job: không thể mở tập tin khoá « %s »Receive_jobs: lá»—i ghi vào fd « %d »Äang phục hồi sau khi gá»­i sai công việcRemote_job: có %d tập tin dữ liệu còn chỉ cho phép %dTRÃŒNH PHỤC VỤCHẠYTRẠNG THÃIDỪNGScan_block_file: lseek bị lá»—i « %s »Scan_block_file: lá»—i Ä‘á»c « %s »Scan_block_file: Ä‘á»c kết thúc tập tin không ngoài lệService_connection: giá trị LocalHost_IP SAIService_connection: há» giao thức sai « %d »Service_connection: không thể Ä‘á»c yêu cầu từ %s trong %d giâyService_connection: getpeername (lấy tên ngang hàng) bị lá»—iService_connection: hé nhìn có độ dài %d bị lá»—iService_connection: dòng yêu cầu ngắn « %s », từ « %s »Service_worker: không thể mở tập tin khoá « %s »Service_worker: không thể cập nhật tập tin vé công việc cho « %s »Service_worker: không có bá»™ nhận diện cho « %s »Setup_log: dup2(%d,%d) bị lá»—iSetup_log: lá»—i mở %sSetup_log: lá»—i mở « /dev/null »Tiếc là chỉ có thể in ra %d tập tin đồng thá»i nên chia công việc raStart_all: lá»—i ống dẫn.Thông tin trạng thái, lần thá»­ %d: HÀNG ÄỢI ÄẦUTHỬ BẢN DỊCHTerm_clear: waitpid(%d) bị lá»—iLÊNchưa xác định biến môi trưá»ng ngưá»i dùng USERUpdate_status: không có bá»™ nhận diện cho « %s »Cách sá»­ dụng: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d máy_in@[máy]] [-f tên_dạng] [-H quản_lý_đặc_biệt] [-n số] [-o tùy_chá»n] [-P danh_sách_trang] [-q cấp_ưu_tiên] [-S bá»™_ký_tá»±] [-S bánh_xe_in] [-t tá»±a] [-T kiểu_ná»™i_dung [-r]] [-y danh_sách_chế_độ] [-Dtùy_chá»n_gỡ_lá»—i ] [ các_tên_tập_tin ... ] Mô phá»ng lp dùng LPRng, chức năng có thể khác biệt má»™t ít -A — dùng sá»± xác thá»±c ghi rõ bởi biến môi trưá»ng AUTH -B — lá»c các tập tin và giảm công việc thành tập tin riêng lẻ trước khi gá»­i -c — (tạo bản sao trước khi in — bị bá» qua) -d máy_in[@máy] — máy in trên máy -D cá»_gỡ_lá»—i — các cá» gỡ lá»—i -f tên_dạng — chữ đầu dùng làm định dạng công việc -G — lá»c tập tin công việc riêng trước khi gá»­i -H quản_lý — (được gá»­i như « -Z quản_lý » -m — thư được gá»­i cho ngưá»i dùng $USER khi in xong -n SỠ— tổng số bản sao -o tùy_chá»n — nhận ra nobanner (không băng cá») và width (độ rá»™ng), (các tùy chá»n khác được gá»­i như « -Z tùy chá»n ») -P danh_sách_trang — (in danh sách trang — bị bá» qua) -p — (thông báo khi in xong — bị bá» qua) -q — độ ưu tiên: 0 -> Z (cao nhất), 25 -> A (thấp nhất) -s — (thu hồi các thông Ä‘iệp — bị bá» qua) -S bá»™_ký_tá»± — (được gá»­i như « -Z bá»™_ký_tá»± ») -t tá»±a — tá»±a cá»§a công việc -T ná»™i_dung — (được gá»­i như « -Z ná»™i_dung ») -w — (ghi thông Ä‘iệp khi in xong — bị bá» qua) -X đưá»ng_dẫn — bá»™ lá»c tá»± ghi ra cho các tập tin công việc -Y — kết nối và gá»­i tá»›i cổng TCP/IP (chế độ trá»±c tiếp) -y chế_độ — (được gá»­i như « -Z chế_độ ») -- — kết thúc các tùy chá»n, các tập tin theo sau tên tập tin « - » thì Ä‘á»c từ thiết bị nhâp chuẩn STDIN Các biến môi trưá»ng PRINTER, LPDEST, NGPRINTER, NPRINTER đặt máy in mặc định. Usage: %s [-Pmáy_in[@máy]] [-A] [-B] [-Chạng] [-Fđịnh_dạng] [-G] [-Jthông_tin] [-(K|#)số_bản_sao] [-Q] [-Rtên_tài_khoản] [-Ttá»±a] [-Ungưá»i_dùng[@máy]] [-V] [-Ztùy_chá»n] [-b] [-m địa_chỉ_thư] [-h] [-i thụt_lá»] [-l] [-w rá»™ng ] [-r] [-Dtùy_chá»n_gỡ_lá»—i ] [--] [ tên_tập_tin ... ] -A — dùng sá»± xác thá»±c ghi rõ bởi biến môi trưá»ng AUTH -B — lá»c các tập tin và giảm công việc thành tập tin riêng lẻ trước khi gá»­i -C class - job class -D tùy_chá»n_gỡ_lá»—i — các cá» gỡ lá»—i -F định_dạng — định dạng công việc -b,-l — định dạng nhị phân hay nghÄ©a chữ c,d,f,g,l,m,p,t,v cÅ©ng là tùy chá»n định dạng -G — lá»c tập tin công việc riêng trước khi gá»­i -J thông_tin — thông tin vá» băng cá» và công việc -K SỠ— tổng số bản sao -P máy_in[@máy] — máy in trên máy -Q — chèn « queuename » (tên hàng đợi) vào tập tin Ä‘iá»u khiển -Rtên_tài_khoản — thông tin kế toán -T tá»±a — tá»±a đỠcho định dạng « pr » (-p) -U tên_ngưá»i_dùng — có quyá»n cao hÆ¡n tên ngưá»i dùng (bị hạn chế) -V — xuất thông tin chi tiết trong khi cuá»™n vào ống -X đưá»ng_dẫn — bá»™ lá»c tá»± ghi rõ cho tập tin công việc -Y — kết nối và gá»­i tá»›i cổng TCP/IP (chế độ trá»±c tiếp) -Z tùy_chá»n — các tùy chá»n cần gá»­i cho bá»™ lá»c -h — không có phần đầu hay trang băng cá» -i thụt_lỠ— sá»± thụt lá» -k — không dùng tập tin tạm thá»i khi gá»­i cho trình phục vụ -m địa_chỉ_thư — gá»­i thư chứa trạng thái cuối cùng cho địa chỉ này -r — gỡ bá» các tập tin sau khi cuá»™n vào ống -w rá»™ng — độ rá»™ng cần dùng -- — kết thúc các tùy chá»n, các tập tin theo sau tên tập tin « - » thì Ä‘á»c từ thiết bị nhâp chuẩn STDIN Các biến môi trưá»ng PRINTER, LPDEST, NGPRINTER, NPRINTER đặt máy in mặc định. Hãy dùng: move máy_in (ND|MC)* đích [ND ngưá»i dùng MC mã nhận diện công việc]CẢNH BÃO : trình phục vụ cán cân trá»ng tải chính có thể đã thoát trước khi nó có thể nhận thông tin vá» công việc má»›i. Hãy dùng lệnh « lpc start %s » để khởi chạy lại trình phục vụ. Wait_for_subserver: Lá»–I HỢP LÃ. Lá»—i đợi PID %dWait_for_subserver: Mergesort bị lá»—iÄang đợi %d giây trước khi thá»­ lại Bạn đã đóng thiết bị nhập chuẩn STDIN. Không thể gá»­i dữ liệu cho ống dẫn từ sá»± kết nối bị đónghá»§y bá»công việc bị há»§y bá»Ä‘ang há»§y bá» các thao tácÄ‘ang há»§y bá» trình phục vụtất cảmá»i hạng đã in xác thá»±c xung đột vá»›i tùy chá»n « -k »yêu cầu xác thá»±c (tùy chá»n -A) nhưng chưa đặt biến môi trưá»ng xác thá»±c AUTHgặp chuá»—i định dạng -F sai %s dòng lệnh saidòng lệnh sai « %s »lệnh Ä‘iá»u khiển sai « %s »thông tin độ dài sai « %s »máy in sai « %s »tên máy in saitên máy in sai « %s »không thể mở hay khoá tập tin khoá — %skhông thể in « %s »: %skhông thể Ä‘á»c nókhông thể cập nhật tập tin vé công việc « %s »không thể cập nhật tập tin vé công việc cho « %s »không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n hạng đã được cập nhậthạng đã in « %s » kết nối đến máy phục vụ kế toán « %s » bị lá»—i « %s »không thể gỡ bá» công việc « %s »quyá»n cao hÆ¡n gỡ lá»—i bị tắtquyá»n cao hÆ¡n gỡ lá»—i được đăt thành « %s »tắtbị tắt và dừng chạydoaction: waitpid(%ld) bị lá»—iđặc tả định dạng trùng — %c đặc tả định dạng trùng -F%s bậtđã bật và khởi chạylá»—i: không thể gỡ bỠ« %s »lá»—i execvp - '%s'thoátlá»—i gá»­i công việc « %s »không thành công, không thá»­ lạitập tin trên dòng lệnh xung đột vá»›i tùy chá»n « -k »trạng thái bị xoá sạchlá»—i tạo tiến trình con - '%s'fork() (tạo tiến trình con) không thành công.chuyển tiếp bị tắt Ä‘ang chuyển tiếp tá»›i « %s » Thông tin dịch gettext « %s » giữ lạigiữ lại tất cả bị tắtgiữ lại tất cả đã bậtÄ‘ang giữ lại công việchá»§y bá» công việcgiữ lại công việccông việc « %s », lần thá»­ %d, sẽ thá»­ %d lầncông việc « %s », lần thá»­ %d, sẽ thá»­ vô hạncông việc « %s » bị gỡ bá»công việc « %s » bị gỡ bỠ— trạng thái đã hết hạncông việc « %s » đã được lưucông việc « %s », %scông việc « %s », lần thá»­ %d, cho phép %dgỡ bá» công việccvtcôngcông việc thành côngbuá»™c kết thúc tiến trình phục vụ PID %ld bằng %s công việc bị giếtlá»—i liên kết trong khi gá»­i công việc « %s »lpd: không thể mở tập tin khoá « %s »lpd: không thể cắt ngắn tập tin khoálpd: gặp kết thúc tập tin khi gá»­i yêu cầu Lpd_request qua ống dẫn: không thể xảy ra.lpd: lá»—i chấp nhận trên ổ cắm lắng nghelpd: không thể khởi chạy tiến trình ghi lưu đầu tiênlpd: fork() bị lá»—ilpd: main() dofork bị lá»—ilpd: lá»—i gá»i ống dẫnlpd: lá»—i chá»n.lpq: hãy dùng chưng trình thống kê lpstat LPRng thiếu ngưá»i dùng hay tên máy inđã di chuyểnnhiá»u bản sao xung đột vá»›i tùy chá»n « -k »không có quyá»n kết nốikhông có khả năng há»— trợ mạng cho thao tác « %s »không có quyển Ä‘iá»u khiển trình phục vụkhông có quyá»n để cuá»™n công việc « %s » vào ốngkhông có phương pháp nhận được há»— trợ cho « %s »không có há»— trợ từ xa cho %s@%skhông thá»­ lạikhông có đích mặc định trên hệ thống không băng cá»không phải tập tin chuẩnchưa được thá»±c hiệnkhông có gì để intùy chá»n %c tham số « %s » không phải giá trị số nguyên từ 0 - %dtùy chá»n %c tham số « %s » không phải giá trị số nguyên dươngtùy chá»n « %c » thiếu đối sốmáy in %s công việc %smáy in %s tình trạng không rõ. tắt từ %s. sẵn sàng máy in %s tình trạng không rõ. bật từ %s. sẵn sàng máy in « %s » có ký tá»± cấm ở « %s » trong tênmáy in « %s » có tên chứa ký tá»± cấm ở « %s »bị chuyển hướnggỡ bá»Ä‘ang gỡ bỠđích do lá»—iÄ‘ang gỡ bá» công việc « %s » — JABORTÄ‘ang gỡ bá» công việc « %s » — JFAILNORETRYÄ‘ang gỡ bá» công việc « %s » — JREMOVEÄ‘ang gỡ bá» công việc « %s » — không có quyá»nÄ‘ang gỡ bá» công việc — trạng thái JREMOVEmã nhận diện yêu cầu là %d mã nhận diện yêu cầu là %s Ä‘ang thá»­ lại công việcbá»™ lập lịch biểu Ä‘ang chạy tùy chá»n cấu hình « send_block_format » (gá»­i định dạng khối) cung đột vá»›i tùy chá»n « -k »tùy chá»n cấu hình « send_data_first » (gá»­i dữ liệu trước) cung đột vá»›i tùy chá»n « -k »tiến trình phục vụ PID %ld đã thoát kích cỡ %0.3fK lá»›n hÆ¡n %dKngá»§ trong %d giây trước khi thá»­ lại, Ä‘ang bắt đầu ngá»§Ä‘ang ngá»§, đợi các tiến trình thoátđã khởi chạybị dừng chạyđã dừng in do lá»c mã thoát JABORTtrình phục vụ phụ PID %ld đã chết vá»›i tín hiệu « %s »trình phục vụ phụ PID %ld trạng thái thoát « %s »tcôngthành côngđích mặc định trên hệ thống: %s hệ thống cho %s: %s quá nhiá»u lá»—iÄ‘ang xá»­ lý như thành công.trạng thái bất thưá»ng 0x%xgặp ký tá»± không thể in ở đầu tập tin: hãy kiểm tra lại biến môi trưá»ng ngôn ngữ LANG, cÅ©ng như tập tin nhập vàoxác thá»±c không được há»— trợ « %s »cách sá»­ dụng: %s [-FV][-D cấp_gỡ_lá»—i][-L bản_ghi][-P đưá»ng_dẫn][-p cổng][-R CX] [CX cổng đích TCP/IP LPD từ xa Tùy chá»n -D cấp_gỡ_lá»—i — đắt cấp gỡ lá»—i và các cá» -F — chạy trong cảnh gần, ghi lưu vào STDERR -L bản_ghi — phụ thêm thông tin ghi lưu vào tập tin bản ghi này -V — hiện thông tin phiên bản -p cổng — cổng lắng nghe TCP/IP: thêm cỠ« off » (tắt) thì tắt cổng nghê TCP/IP (lpd_listen_port) -P đưá»ng_dẫn — đưá»ng dẫn ổ cắm UNIX: thêm cỠ« off » (tắt) thì tắt ổ cắm lắng nghe UNIX (unix_socket_path) -R cổng — cổng trình phục vụ LPD từ xa (lpd_port) cách sá»­ dụng: %s [-aAclV] [-Dcấp_gỡ_lá»—i] [-Pmáy_in [-tthá»i_gian_ngá»§] -A — dùng sá»± xác thá»±c xác định bởi biến môi trưá»ng AUTH -a — má»i máy in -c — xoá màn hình trước khi cập nhật -l — tăng độ dài cá»§a thông tin trạng thái chi tiết, các cỠ« l » thêm nữa sẽ thêm chi tiết. -L — thông tin trạng thái có chi tiết tối Ä‘a -n SỠ— tổng Sá» dòng thông tin trạng thái chi tiết -Dcấp_gỡ_lá»—i — cấp gỡ lá»—i -Pmáy_in — xác định máy in -s — định dạng tóm tắt ngắn -tthá»i_gian_ngá»§ — thá»i gian cần ngá»§ giữa hai lần cập nhật -V — in ra thông tin phiên bản -v — in ra theo định dạng « khoá: giá trị » cách sá»­ dụng: %s [-a][-Dcấp_gỡ_lá»—i][-Pmáy_in][-Smáy][-Utên_ngưá»i_dùng][-V] [lệnh] không có lệnh thì Ä‘á»c từ thiết bị nhập chuẩn STDIN -a — bí danh cho « -Pall » -Dcấp_gỡ_lá»—i — cấp gỡ lá»—i -Pmáy_in — máy in -Pmáy_in@máy — máy in trên trình phục vụ lpd trên máy này -Smáy — kết nối tá»›i trình phục vụ lpd chạy trên máy này -Ungưá»i_dùng — nhận ra lệnh như đã đến từ ngưá»i dùng này -V — tăng cấp chi tiết lệnh: [all tất cả class hạng host máy job công việc jobid mã nhận diện công việc off tắt] active (máy_in[@máy]) — kiểm tra có trình phục vụ Ä‘ang chạy không (_hoạt động_) abort (máy_in[@máy] | all) — dừng chạy trình phục vụ (_há»§y bá»_) class máy_in[@máy] (class | off) — hiện/đặt cách in hạng (_hạng_) disable (máy_in[@máy] | all) — tắt khả năng dùng hàng đợi (_tắt_) debug (máy_in[@máy] | all) các_tham_số_gỡ_lá»—i đặt cấp gỡ lá»—i cho máy in (_gỡ lá»—i_) down (máy_in[@máy] | all) tắt khả năng in và dùng hàng đợi (_xuống_) enable (máy_in[@máy] | all) — bật khả năng dùng hàng đợi (_bật_) flush (máy_in[@máy] | all) — xoá sạch trạng thái đã nhá»› tạm (_xoá sạch_) hold (máy_in[@máy] | all) (tên[@máy] | job | all)* giữ lại công việc (_giữ lại_) holdall (máy_in[@máy] | all) — giữ lại má»i công việc đã bật (_giữ lại tất cả_) kill (máy_in[@máy] | all) — dừng chạy rồi khởi chạy lại trình phục vụ (_giết_) lpd (máy_in[@máy]) — lấy PID cá»§a LPD lpq (máy_in[@máy] | all) (tên[@máy] | job | all)* gá»i LPQ lprm (máy_in[@máy] | all) (tên[@máy]|host|job| all)* gá»i LPRM msg Ä‘oạn_thông_Ä‘iệp_máy_in đặt thông Ä‘iệp trạng thái (_thông Ä‘iệp [viết tắt]_) move máy_in (ngưá»i_dùng|jobid)* đích di chuyển các công việc vào hàng đợi má»›i (_di chuyển_) noholdall (máy_in[@máy] | all) — giữ lại má»i công việc bị tắt (_không giữ lại tất cả_) printcap (máy_in[@máy] | all) — thông báo các giá trị printcap quit — thoát khá»i LPC (_thoát_) redirect (máy_in[@máy] | all) (máy_in@máy | off )* chuyển hướng công việc (_chuyển tiếp_) redo (máy_in[@máy] | all) (tên[@máy] | job | all)* in lại công việc (_làm lại_) release (máy_in[@máy] | all) (tên[@máy] | job | all)* phát hành công việc (_phát hành_) reread — LPD Ä‘á»c lại thông tin cÆ¡ sở dữ liệu (_Ä‘á»c lại_) start (máy_in[@máy] | all) — bắt đầu in (_bắt đầu_) status (máy_in[@máy] | all) — trạng thái cá»§a máy in (_trạng thái_) stop (máy_in[@máy] | all) — dừng in (_dừng_) topq (máy_in[@máy] | all) (tên[@máy] | job | all)* thay đổi thứ tá»± các công việc (_thứ tá»± lại_) up (máy_in[@máy] | all) — bật khả năng in và dùng hàng đợi chẩn Ä‘oán: defaultq — hiện hàng đợi mặc định cho trình phục vụ LPD (_hàng đợi mặc định [viết tắt_) defaults — hiện các giá trị cấu hình mặc định (_các mặc định_) lang — hiện cấp há»— trợ quốc tế hoá hiện thá»i (_ngôn ngữ [viết tắt]_) client (máy_in | all) — thông tin vá» cấu hình trình khách và printcap (_khách_) server (máy_in | all) — thông tin vá» cấu hình trình phục vụ và printcap (_máy/trình phục vụ_) độ rá»™ngsố đối số không đúng, %dlprng-3.8.B/po/stamp-po0000644000131400013140000000001211531672374011702 00000000000000timestamp lprng-3.8.B/po/pl.po0000644000131400013140000016312411531672130011176 00000000000000# Polish translation for LPRng. # Copyright (C) 2007 Free Software Foundation, Inc. # This file is distributed under the same license as the LPRng package. # Jakub Bogusz , 2002-2007. # #: src/common/lpc.c:270 src/common/lpc.c:435 src/common/lpq.c:547 msgid "" msgstr "" "Project-Id-Version: lprng 3.8.29-rc4\n" "Report-Msgid-Bugs-To: lprng-devel@lists.sf.net\n" "POT-Creation-Date: 2011-02-03 19:40+0100\n" "PO-Revision-Date: 2007-08-08 17:40+0200\n" "Last-Translator: Jakub Bogusz \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ISO-8859-2\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: src/common/accounting.c:134 #, c-format msgid "connection to accounting server '%s' failed '%s'" msgstr "po³±czenie z serwerem rozliczeñ '%s' nie powiod³o siê: '%s'" #: src/common/controlword.c:16 msgid "ABORT" msgstr "ABORT" #: src/common/controlword.c:17 msgid "ACTIVE" msgstr "ACTIVE" #: src/common/controlword.c:18 msgid "CLASS" msgstr "CLASS" #: src/common/controlword.c:19 msgid "CLIENT" msgstr "CLIENT" #: src/common/controlword.c:20 msgid "DEBUG" msgstr "DEBUG" #: src/common/controlword.c:21 msgid "DEFAULTQ" msgstr "DEFAULTQ" #: src/common/controlword.c:22 msgid "DISABLE" msgstr "DISABLE" #: src/common/controlword.c:23 msgid "DOWN" msgstr "DOWN" #: src/common/controlword.c:24 msgid "ENABLE" msgstr "ENABLE" #: src/common/controlword.c:25 msgid "HOLD" msgstr "HOLD" #: src/common/controlword.c:26 msgid "HOLDALL" msgstr "HOLDALL" #: src/common/controlword.c:27 msgid "KILL" msgstr "KILL" #: src/common/controlword.c:28 msgid "LPD" msgstr "LPD" #: src/common/controlword.c:29 msgid "LPQ" msgstr "LPQ" #: src/common/controlword.c:30 msgid "LPRM" msgstr "LPRM" #: src/common/controlword.c:31 msgid "MOVE" msgstr "MOVE" #: src/common/controlword.c:32 msgid "MSG" msgstr "MSG" #: src/common/controlword.c:33 msgid "NOHOLDALL" msgstr "NOHOLDALL" #: src/common/controlword.c:34 msgid "PRINTCAP" msgstr "PRINTCAP" #: src/common/controlword.c:35 msgid "REDIRECT" msgstr "REDIRECT" #: src/common/controlword.c:36 msgid "REDO" msgstr "REDO" #: src/common/controlword.c:37 msgid "RELEASE" msgstr "RELEASE" #: src/common/controlword.c:38 msgid "REREAD" msgstr "REREAD" #: src/common/controlword.c:39 msgid "START" msgstr "START" #: src/common/controlword.c:40 msgid "STATUS" msgstr "STATUS" #: src/common/controlword.c:41 msgid "STOP" msgstr "STOP" #: src/common/controlword.c:42 msgid "TOPQ" msgstr "TOPQ" #: src/common/controlword.c:43 msgid "UP" msgstr "UP" #: src/common/controlword.c:44 msgid "SERVER" msgstr "SERVER" #: src/common/controlword.c:45 msgid "DEFAULTS" msgstr "DEFAULTS" #: src/common/controlword.c:46 msgid "FLUSH" msgstr "FLUSH" #: src/common/controlword.c:47 msgid "LANG" msgstr "LANG" #: src/common/controlword.c:48 msgid "PPD" msgstr "PPD" #: src/common/lpc.c:129 src/common/lpq.c:181 src/common/lpstat.c:147 #: src/common/lpr.c:91 src/common/lprm.c:146 msgid "" "authentication requested (-A option) and AUTH environment variable not set" msgstr "" "¿±dano uwierzytelnienia (opcja -A), ale nie ustawiono zmiennej ¶rodowiskowej " "AUTH" #: src/common/lpc.c:198 msgid "exit" msgstr "koniec" #: src/common/lpc.c:242 src/common/lpq.c:237 #, c-format msgid "Printer: %s - cannot get status from device '%s'\n" msgstr "Drukarka: %s - nie mo¿na odczytaæ stanu z urz±dzenia '%s'\n" #: src/common/lpc.c:249 src/common/lpq.c:259 src/common/lprm.c:253 #, c-format msgid "Printer: %s - direct connection to device '%s'\n" msgstr "Drukarka: %s - bezpo¶rednie po³±czenie z urz±dzeniem '%s'\n" #: src/common/lpc.c:267 #, c-format msgid "Locale information directory '%s'\n" msgstr "Katalog z informacjami o lokalizacji '%s'\n" #: src/common/lpc.c:269 src/common/lpc.c:434 src/common/lpq.c:546 #, c-format msgid "LANG environment variable '%s'\n" msgstr "Zmienna ¶rodowiskowa LANG '%s'\n" #: src/common/lpc.c:272 src/common/lpc.c:437 src/common/lpq.c:549 #, c-format msgid "gettext translation information '%s'\n" msgstr "informacje o t³umaczeniu gettext '%s'\n" #: src/common/lpc.c:274 src/common/lpc.c:439 src/common/lpq.c:551 msgid "No translation available\n" msgstr "T³umaczenie nie dostêpne\n" #: src/common/lpc.c:276 msgid "TRANSLATION TEST" msgstr "TEST T£UMACZENIA" #: src/common/lpc.c:306 src/common/lpc.c:317 src/common/lpc.c:335 msgid "all" msgstr "wszystko" #: src/common/lpc.c:312 src/common/lpc.c:321 msgid "# Printcap Information\n" msgstr "# Informacje printcap\n" #: src/common/lpc.c:350 #, c-format msgid "execvp failed - '%s'" msgstr "execvp nie powiod³o siê - '%s'" #: src/common/lpc.c:353 #, c-format msgid "fork failed - '%s'" msgstr "fork nie powiod³o siê - '%s'" #: src/common/lpc.c:361 #, c-format msgid "doaction: waitpid(%ld) failed" msgstr "doaction: waitpid(%ld) nie powiod³o siê" #: src/common/lpc.c:452 #, c-format msgid "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke " "LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect " "jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint " "jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release " "jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder " "jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) " "support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n" msgstr "" "Sk³adnia: %s [-a][-Dpoziom][-Pdrukarka][-Shost][-Uu¿ytkownik][-V] " "[polecenie]\n" " bez podanego polecenia czyta ze standardowego wej¶cia\n" " -a - alias dla -Pall\n" " -Dpoziom - poziom ¶ledzenia (debug level)\n" " -Pdrukarka - drukarka\n" " -Pdrukarka@host - drukarka na serwerze lpd na ho¶cie\n" " -Shost - po³±czenie z serwerem lpd na ho¶cie\n" " -Uu¿ytkownik - identyfikacja polecenia jako pochodz±ce od u¿ytkownika\n" " -V - zwiêkszenie ilo¶ci informacji\n" " polecenia:\n" " active (drukarka[@host]) - sprawdzenie aktywno¶ci serwera\n" " abort (drukarka[@host] | all) - zatrzymanie serwera\n" " class drukarka[@host] (klasa | off) - pokazanie/ustawienie drukowania " "klas\n" " disable (drukarka[@host] | all) - wy³±czenie kolejkowania\n" " debug (drukarka[@host] | all) parametry - ustawienie poziomu ¶ledzenia\n" " down (drukarka[@host] | all) - wy³±czenie drukowania i kolejkowania\n" " enable (drukarka[@host] | all) - w³±czenie kolejkowania\n" " flush (drukarka[@host] | all) - wyczyszczenie zapamiêtanego stanu\n" " hold (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - " "wstrzymanie\n" " zadania\n" " holdall (drukarka[@host] | all) - wstrzymanie wszystkich zadañ\n" " kill (drukarka[@host] | all) - zatrzymanie i restart serwera\n" " lpd (drukarka[@host]) - odczyt PID-u LPD\n" " lpq (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - wywo³anie " "LPQ\n" " lprm (drukarka[@host] | all) (nazwa[@host]|host|zad.|all)*- wywo³anie " "LPRM\n" " msg drukarka komunikat tekst - ustawienie komunikatu o stanie\n" " move drukarka (u¿ytkownik|idzad)* cel - wys³anie zadañ do nowej " "kolejki\n" " noholdall (drukarka[@host] | all) - wznowienie wszystkich zadañ\n" " printcap (drukarka[@host] | all) - przekazanie warto¶ci printcap\n" " quit - zakoñczenie LPC\n" " redirect (drukarka[@host] | all) (drukarka@host|off)* - przekierowanie " "zadañ\n" " redo (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - ponowny " "wydruk\n" " zadañ\n" " release (drukarka[@host] | all) (nazwa[@host]|zad.|all)* - uwolnienie " "zadañ\n" " reread - ponowne odczytanie bazy informacji LPD\n" " start (drukarka[@host] | all) - uruchomienie drukowania\n" " status (drukarka[@host] | all) - stan drukarek\n" " stop (drukarka[@host] | all) - zatrzymanie drukowania\n" " topq (drukarka[@host] | all) (nazwa[@host] | zad. | all)* - zamiana " "zadañ\n" " up (drukarka[@host] | all) - w³±czenie drukowania i kolejkowania\n" " diagnostyka:\n" " defaultq - pokazanie domy¶lnej kolejki serwera LPD\n" " defaults - pokazanie domy¶lnych warto¶ci ustawieñ\n" " lang - pokazanie aktualnie obs³ugiwanej lokalizacji\n" " client (drukarka | all) - informacja o konfiguracji i printcap " "klienta\n" " server (drukarka | all) - konfiguracja i printcap serwera\n" #: src/common/lpd.c:178 msgid "No LPD lockfile specified!" msgstr "Nie podano pliku blokuj±cego LPD!" #: src/common/lpd.c:189 src/common/lpd.c:202 #, c-format msgid "Another print spooler active, possibly lpd process '%ld'" msgstr "Inny demon wydruku aktywny, prawdopodobnie proces lpd '%ld'" #: src/common/lpd.c:194 #, c-format msgid "cannot open or lock lockfile - %s" msgstr "nie mo¿na otworzyæ lub zablokowaæ pliku blokuj±cego - %s" #: src/common/lpd.c:267 msgid "lpd: main() dofork failed" msgstr "lpd: main() dofork nie powiod³o siê" #: src/common/lpd.c:312 src/common/lpd.c:323 msgid "lpd: pipe call failed" msgstr "lpd: wywo³anie pipe nie powiod³o siê" #: src/common/lpd.c:330 msgid "lpd: cannot start initial logger process" msgstr "lpd: nie mo¿na uruchomiæ pocz±tkowego procesu loguj±cego" #: src/common/lpd.c:683 msgid "lpd: select error!" msgstr "lpd: b³±d select!" #: src/common/lpd.c:710 msgid "lpd: Lpd_request pipe EOF! cannot happen" msgstr "lpd: EOF potoku w Lpd_request! niemo¿liwe" #: src/common/lpd.c:735 src/common/lpd.c:738 msgid "Setup_log: open /dev/null failed" msgstr "Setup_log: otwarcie /dev/null nie powiod³o siê" #: src/common/lpd.c:745 src/common/lpd.c:749 #, c-format msgid "Setup_log: dup2(%d,%d) failed" msgstr "Setup_log: dup2(%d,%d) nie powiod³o siê" #: src/common/lpd.c:754 #, c-format msgid "Setup_log: open %s failed" msgstr "Setup_log: otwarcie %s nie powiod³o siê" #: src/common/lpd.c:792 msgid "lpd: Cannot truncate lock file" msgstr "lpd: Nie mo¿na skróciæ pliku blokuj±cego" #: src/common/lpd.c:810 #, c-format msgid "lpd: Cannot open lock file '%s'" msgstr "lpd: Nie mo¿na otworzyæ pliku blokuj±cego '%s'" #: src/common/lpd.c:912 #, c-format msgid "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" msgstr "" "Sk³adnia: %s [-FV][-D dbg][-L log][-P gniazdo][-p port][-R port TCP/IP " "zdalnego LPD]\n" " Opcje\n" " -D dbg - ustawienie poziomu i flag ¶ledzenia\n" " -F - uruchomienie na pierwszym planie, logi na STDERR\n" " -L plikloga - do³±czanie logowanych informacji do plikuloga\n" " -V - pokazanie informacji o wersji\n" " -p port - port nas³uchuj±cy TCP/IP, 'off' wy³±cza nas³uch TCP/IP " "(lpd_listen_port)\n" " -P gniazdo - ¶cie¿ka gniazda uniksowego, 'off' wy³±cza gniazdo " "(unix_socket_path)\n" " -R port - port zdalnego serwera LPD (lpd_port)\n" #: src/common/lpd.c:1001 msgid "lpd: fork() failed" msgstr "lpd: fork() nie powiod³o siê" #: src/common/lpd.c:1012 msgid "lpd: accept on listening socket failed" msgstr "lpd: accept na gnie¼dzie s³uchaj±cym nie powiod³o siê" #: src/common/lpd.c:1031 msgid "Start_all: pipe failed!" msgstr "Start_all: pipe nie powiod³o siê!" #: src/common/lpd_control.c:87 #, c-format msgid "bad control command '%s'" msgstr "b³êdne polecenie kontrolne '%s'" #: src/common/lpd_control.c:102 #, c-format msgid "printer '%s' has illegal char at '%s' in name" msgstr "drukarka '%s' ma nieprawid³owy znak przy '%s' w nazwie" #: src/common/lpd_control.c:114 #, c-format msgid "%s: unknown control request '%s'" msgstr "%s: nieznane ¿±danie kontrolne '%s'" #: src/common/lpd_control.c:195 msgid "Use: move printer (user|jobid)* target" msgstr "Sk³adnia: move drukarka (u¿ytkownik|idzadania)* cel" #: src/common/lpd_control.c:206 msgid "no permission to control server" msgstr "brak uprawnieñ do kontrolowania serwera" #: src/common/lpd_control.c:460 msgid "not implemented yet" msgstr "jeszcze nie zaimplementowano" #: src/common/lpd_control.c:486 #, c-format msgid "server process PID %ld exited\n" msgstr "proces serwera PID %ld zakoñczy³ siê\n" #: src/common/lpd_control.c:489 #, c-format msgid "kill server process PID %ld with %s\n" msgstr "zabicie procesu serwera PID %ld przez %s\n" #: src/common/lpd_control.c:497 msgid "enabled and started" msgstr "w³±czono i uruchomiono" #: src/common/lpd_control.c:498 msgid "disabled and stopped" msgstr "wy³±czono i zatrzymano" #: src/common/lpd_control.c:499 msgid "stopped" msgstr "zatrzymano" #: src/common/lpd_control.c:501 msgid "started" msgstr "uruchomiono" #: src/common/lpd_control.c:502 msgid "disabled" msgstr "wy³±czono" #: src/common/lpd_control.c:503 msgid "enabled" msgstr "w³±czono" #: src/common/lpd_control.c:504 msgid "redirected" msgstr "przekierowano" #: src/common/lpd_control.c:505 msgid "holdall on" msgstr "wstrzymano wszystko" #: src/common/lpd_control.c:506 msgid "holdall off" msgstr "wznowiono wszystko" #: src/common/lpd_control.c:507 msgid "move done" msgstr "przeniesienie wykonane" #: src/common/lpd_control.c:508 msgid "class updated" msgstr "klasa uaktualniona" #: src/common/lpd_control.c:509 msgid "killed job" msgstr "usuniêto zadanie" #: src/common/lpd_control.c:510 msgid "aborted job" msgstr "przerwano zadanie" #: src/common/lpd_control.c:511 msgid "flushed status" msgstr "wyczyszczono stan" #: src/common/lpd_control.c:531 #, c-format msgid "" "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n" msgstr "" "UWAGA: g³ówny serwer rozk³adaj±cy obci±¿enie móg³ zakoñczyæ\n" "pracê przed poinformowaniem, ¿e s± nowe zadania.\n" "Proszê u¿yæ 'lpc start %s', aby uruchomiæ serwer\n" #: src/common/lpd_control.c:565 #, c-format msgid "Do_queue_control: write to fd '%d' failed" msgstr "Do_queue_control: zapis do deskryptora '%d' nie powiód³ siê" #: src/common/lpd_control.c:654 #, c-format msgid "%s: no permission '%s'\n" msgstr "%s: brak uprawnienia '%s'\n" #: src/common/lpd_control.c:738 #, c-format msgid "%s: selected '%s'\n" msgstr "%s: wybrano '%s'\n" #: src/common/lpd_control.c:748 #, c-format msgid "%s: cannot set hold file '%s'\n" msgstr "%s: nie mo¿na ustawiæ pliku wstrzymania '%s'\n" #: src/common/lpd_control.c:855 msgid " holdall" msgstr " wszystko-wstrzymane" #: src/common/lpd_control.c:859 #, c-format msgid " class=%s" msgstr " klasa=%s" #: src/common/lpd_control.c:863 msgid " autohold" msgstr " autowstrzymanie" #: src/common/lpd_control.c:935 src/common/lpd_control.c:990 #: src/common/lpd_control.c:1045 #, c-format msgid "wrong number arguments, %d" msgstr "b³êdna liczba argumentów - %d" #: src/common/lpd_control.c:941 #, c-format msgid "forwarding to '%s'\n" msgstr "przekazywanie do '%s'\n" #: src/common/lpd_control.c:943 msgid "forwarding off\n" msgstr "przekazywanie wy³±czone\n" #: src/common/lpd_control.c:997 #, c-format msgid "classes printed '%s'\n" msgstr "wydrukowane klasy '%s'\n" #: src/common/lpd_control.c:1000 msgid "all classes printed\n" msgstr "wszystkie klasy wydrukowane\n" #: src/common/lpd_control.c:1051 #, c-format msgid "debugging override set to '%s'" msgstr "wymuszenie ¶ledzenia ustawione na '%s'" #: src/common/lpd_control.c:1053 msgid "debugging override off" msgstr "wymuszenie ¶ledzenia wy³±czone" #: src/common/lpd_jobs.c:435 #, c-format msgid "Do_queue_jobs: cannot open lockfile '%s'" msgstr "Do_queue_jobs: nie mo¿na otworzyæ pliku blokuj±cego '%s'" #: src/common/lpd_jobs.c:767 src/common/lpd_jobs.c:787 #: src/common/lpd_jobs.c:2360 #, c-format msgid "cannot update job ticket file for '%s'" msgstr "nie mo¿na uaktualniæ pliku biletu zadania dla '%s'" #: src/common/lpd_jobs.c:770 src/common/lpd_jobs.c:790 #, c-format msgid "Do_queue_jobs: cannot update job ticket file for '%s'" msgstr "Do_queue_jobs: nie mo¿na uaktualniæ pliku biletu zadania dla '%s'" #: src/common/lpd_jobs.c:774 src/common/lpd_jobs.c:794 #, c-format msgid "removing job '%s' - no permissions" msgstr "usuwanie zadania '%s' - brak uprawnieñ" #: src/common/lpd_jobs.c:1063 #, c-format msgid "Do_queue_jobs: LOGIC ERROR - no identifer '%s'" msgstr "Do_queue_jobs: B£¡D LOGIKI - brak identyfikatora '%s'" #: src/common/lpd_jobs.c:1072 #, c-format msgid "Do_queue_jobs: FORWARDING LOOP - '%s'" msgstr "Do_queue_jobs: PÊTLA PRZEKAZYWANIA - '%s'" #: src/common/lpd_jobs.c:1096 #, c-format msgid "cannot update job ticket file '%s'" msgstr "nie mo¿na uaktualniæ pliku biletu zadania '%s'" #: src/common/lpd_jobs.c:1098 #, c-format msgid "Do_queue_jobs: cannot update job ticket file '%s'" msgstr "Do_queue_jobs: nie mo¿na uaktualniæ pliku biletu zadania '%s'" #: src/common/lpd_jobs.c:1147 #, c-format msgid "Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d" msgstr "Do_queue_jobs: B£¡D LOGIKI! new_dest i use_subserver == %d" #: src/common/lpd_jobs.c:1163 src/common/lpd_jobs.c:1227 msgid "sleeping, waiting for processes to exit" msgstr "oczekiwanie na zakoñczenie procesów" #: src/common/lpd_jobs.c:1204 #, c-format msgid "Do_queue_jobs: write to fd '%d' failed" msgstr "Do_queue_jobs: zapis do deskryptora '%d' nie powiód³ siê" #: src/common/lpd_jobs.c:1403 #, c-format msgid "Remote_job: %d datafiles and only allowed %d" msgstr "Remote_job: %d plików danych, a dozwolonych tylko %d" #: src/common/lpd_jobs.c:1447 #, c-format msgid "link failure while sending job '%s'" msgstr "b³±d po³±czenia podczas wysy³ania zadania '%s'" #: src/common/lpd_jobs.c:1453 #, c-format msgid "no permission to spool job '%s'" msgstr "brak uprawnieñ do skolejkowania zadania '%s'" #: src/common/lpd_jobs.c:1459 #, c-format msgid "failed to send job '%s'" msgstr "wys³anie zadania '%s' nie powiod³o siê" #: src/common/lpd_jobs.c:1627 msgid "Fork_subserver: fork failed" msgstr "Fork_subserver: fork nie powiod³o siê" #: src/common/lpd_jobs.c:1701 #, c-format msgid "subserver pid %ld exit status '%s'" msgstr "podserwer pid %ld zakoñczony ze statusem '%s'" #: src/common/lpd_jobs.c:1705 #, c-format msgid "subserver pid %ld died with signal '%s'" msgstr "podserwer pid %ld umar³ od sygna³u '%s'" #: src/common/lpd_jobs.c:1751 msgid "Wait_for_subserver: Mergesort failed" msgstr "Wait_for_subserver: Mergesort nie powiod³o siê" #: src/common/lpd_jobs.c:1762 #, c-format msgid "Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed" msgstr "" "Wait_for_subserver: B£¡D LOGIKI! oczekiwanie na pid %d nie powiod³o siê" #: src/common/lpd_jobs.c:1787 msgid "succ" msgstr "succ" #: src/common/lpd_jobs.c:1788 msgid "jsucc" msgstr "jsucc" #: src/common/lpd_jobs.c:1789 msgid "success" msgstr "success" #: src/common/lpd_jobs.c:1790 msgid "jsuccess" msgstr "jsuccess" #: src/common/lpd_jobs.c:1791 msgid "abort" msgstr "abort" #: src/common/lpd_jobs.c:1792 msgid "jabort" msgstr "jabort" #: src/common/lpd_jobs.c:1793 msgid "hold" msgstr "hold" #: src/common/lpd_jobs.c:1794 msgid "jhold" msgstr "jhold" #: src/common/lpd_jobs.c:1795 msgid "remove" msgstr "remove" #: src/common/lpd_jobs.c:1796 msgid "jremove" msgstr "jremove" #: src/common/lpd_jobs.c:1975 #, c-format msgid "Update_status: no identifier for '%s'" msgstr "Update_status: brak identyfikatora dla '%s'" #: src/common/lpd_jobs.c:2008 src/common/lpd_jobs.c:2115 #: src/common/lpd_jobs.c:2157 src/common/lpd_jobs.c:2201 #, c-format msgid "job '%s' saved" msgstr "zadanie '%s' zachowane" #: src/common/lpd_jobs.c:2013 src/common/lpd_jobs.c:2121 #: src/common/lpd_jobs.c:2163 src/common/lpd_jobs.c:2207 #, c-format msgid "could not remove job '%s'" msgstr "nie mo¿na usun±æ zadania '%s'" #: src/common/lpd_jobs.c:2015 src/common/lpd_jobs.c:2123 #: src/common/lpd_jobs.c:2165 src/common/lpd_jobs.c:2209 #, c-format msgid "job '%s' removed" msgstr "zadanie '%s' usuniête" #: src/common/lpd_jobs.c:2045 #, c-format msgid "job '%s', attempt %d, allowed %d" msgstr "zadanie '%s', próba %d, dozwolonych %d" #: src/common/lpd_jobs.c:2049 msgid "treating as successful" msgstr "traktowane jako pomy¶lne" #: src/common/lpd_jobs.c:2050 msgid "retrying job" msgstr "ponawianie próby" #: src/common/lpd_jobs.c:2051 msgid "no retry" msgstr "bez ponawiania" #: src/common/lpd_jobs.c:2052 msgid "aborting server" msgstr "przerwanie zadania" #: src/common/lpd_jobs.c:2053 msgid "removing job - status JREMOVE" msgstr "usuwanie zadania - status JREMOVE" #: src/common/lpd_jobs.c:2054 msgid "holding job" msgstr "wstrzymywanie zadania" #: src/common/lpd_jobs.c:2057 #, c-format msgid "unexpected status 0x%x" msgstr "nieoczekiwany status 0x%x" #: src/common/lpd_jobs.c:2062 #, c-format msgid "job '%s', %s" msgstr "zadanie '%s', %s" #: src/common/lpd_jobs.c:2066 #, c-format msgid "job '%s' attempt %d, trying %d times" msgstr "zadanie '%s' próba %d, próbowanie %d razy" #: src/common/lpd_jobs.c:2069 #, c-format msgid "job '%s' attempt %d, trying indefinitely" msgstr "zadanie '%s' próba %d, próbowanie bez koñca" #: src/common/lpd_jobs.c:2088 msgid "failed, no retry" msgstr "nie powiod³o siê, bez ponownych prób" #: src/common/lpd_jobs.c:2119 #, c-format msgid "removing job '%s' - JFAILNORETRY" msgstr "usuwanie zadania '%s' - JFAILNORETRY" #: src/common/lpd_jobs.c:2131 msgid "aborting operations" msgstr "przerywanie operacji" #: src/common/lpd_jobs.c:2161 #, c-format msgid "removing job '%s' - JABORT" msgstr "usuwanie zadania '%s' - JABORT" #: src/common/lpd_jobs.c:2170 msgid "stopping printing on filter JABORT exit code" msgstr "zatrzymywanie drukowania po kodzie wyj¶cia filtra JABORT" #: src/common/lpd_jobs.c:2180 msgid "removing destination due to errors" msgstr "usuwanie celu z powodu b³êdów" #: src/common/lpd_jobs.c:2191 msgid "too many errors" msgstr "za du¿o b³êdów" #: src/common/lpd_jobs.c:2205 #, c-format msgid "removing job '%s' - JREMOVE" msgstr "usuwanie zadania '%s' - JREMOVE" #: src/common/lpd_jobs.c:2334 #, c-format msgid "Service_worker: cannot open lockfile '%s'" msgstr "Service_worker: nie mo¿na otworzyæ pliku blokuj±cego '%s'" #: src/common/lpd_jobs.c:2363 #, c-format msgid "Service_worker: cannot update job ticket file for '%s'" msgstr "Service_worker: nie mo¿na uaktualniæ pliku biletu zadania dla '%s'" #: src/common/lpd_jobs.c:2371 #, c-format msgid "Service_worker: no identifier for '%s'" msgstr "Service_worker: brak identyfikatora dla '%s'" #: src/common/lpd_jobs.c:2757 #, c-format msgid "job '%s' removed- status expired" msgstr "zadanie '%s' usuniête - status wygas³" #: src/common/lpd_rcvjob.c:139 src/common/lpd_rcvjob.c:559 msgid "bad command line" msgstr "b³êdna linia polecenia" #: src/common/lpd_rcvjob.c:143 src/common/lpd_rcvjob.c:563 msgid "bad printer name" msgstr "b³êdna nazwa drukarki" #: src/common/lpd_rcvjob.c:151 #, c-format msgid "%s: cannot set up print queue" msgstr "%s: nie mo¿na ustawiæ kolejki wydruków" #: src/common/lpd_rcvjob.c:187 src/common/lpd_rcvjob.c:602 #: src/common/lpd_secure.c:188 #, c-format msgid "%s: spooling disabled" msgstr "%s: buforowanie wy³±czone" #: src/common/lpd_rcvjob.c:198 #, c-format msgid "%s: Receive_job: sending ACK 0 failed" msgstr "%s: Receive_job: wysy³anie ACK 0 nie powiod³o siê" #: src/common/lpd_rcvjob.c:210 #, c-format msgid "Receive_job: cannot open lockfile '%s'" msgstr "Receive_job: nie mo¿na otworzyæ pliku blokuj±cego '%s'" #: src/common/lpd_rcvjob.c:215 #, c-format msgid "Receive_job: cannot lock lockfile '%s'" msgstr "Receive_job: nie mo¿na zablokowaæ pliku blokuj±cego '%s'" #: src/common/lpd_rcvjob.c:254 msgid "Recovering from incorrect job submission" msgstr "Przywracanie stanu po zleceniu niepoprawnego zadania" #: src/common/lpd_rcvjob.c:268 #, c-format msgid "%s: Receive_job - bad control line '%s', len %0.0f, name '%s'" msgstr "" "%s: Receive_job - b³êdna linia kontrolna '%s', d³ugo¶æ %0.0f, nazwa '%s'" #: src/common/lpd_rcvjob.c:289 src/common/lpd_rcvjob.c:366 #: src/common/lpd_rcvjob.c:403 src/common/lpd_rcvjob.c:454 #: src/common/lpd_rcvjob.c:617 src/common/lpd_rcvjob.c:799 #: src/common/lpd_rcvjob.c:846 src/common/lpd_rcvjob.c:881 #: src/common/lpd_rcvjob.c:917 #, c-format msgid "size %0.3fK exceeds %dK" msgstr "rozmiar %0.3fK przekracza %dK" #: src/common/lpd_rcvjob.c:296 src/common/lpd_rcvjob.c:624 #: src/common/lpd_secure.c:202 #, c-format msgid "%s: insufficient file space" msgstr "%s: za ma³o miejsca na plik" #: src/common/lpd_rcvjob.c:311 src/common/lpd_rcvjob.c:676 #, c-format msgid "%s: sending ACK 0 for '%s' failed" msgstr "%s: wysy³anie ACK 0 dla '%s' nie powiod³o siê" #: src/common/lpd_rcvjob.c:345 src/common/lpd_rcvjob.c:649 #, c-format msgid "%s: transfer of '%s' from '%s' failed" msgstr "%s: przesy³anie '%s' z '%s' nie powiod³o siê" #: src/common/lpd_rcvjob.c:375 src/common/lpd_rcvjob.c:412 #: src/common/lpd_rcvjob.c:463 src/common/lpd_rcvjob.c:854 #: src/common/lpd_rcvjob.c:890 src/common/lpd_rcvjob.c:926 #: src/common/lpd_rcvjob.c:1337 src/common/lpd_rcvjob.c:1413 #, c-format msgid "Error setting up job ticket file - %s" msgstr "B³±d podczas ustanawiania pliku biletu zadania - %s" #: src/common/lpd_rcvjob.c:505 #, c-format msgid "Receive_jobs: write to fd '%d' failed" msgstr "Receive_jobs: zapis do deskryptora '%d' nie powiód³ siê" #: src/common/lpd_rcvjob.c:570 #, c-format msgid "%s: cannot set up printer" msgstr "%s: nie mo¿na ustawiæ drukarki" #: src/common/lpd_rcvjob.c:638 #, c-format msgid "%s: Receive_block_job: sending ACK 0 failed" msgstr "%s: Receive_block_job: wysy³anie ACK 0 nie powiod³o siê" #: src/common/lpd_rcvjob.c:659 #, c-format msgid "Receive_block_job: lseek failed '%s'" msgstr "Receive_block_job: lseek nie powiod³o siê: '%s'" #: src/common/lpd_rcvjob.c:706 #, c-format msgid "Receive_block_jobs: write to fd '%d' failed" msgstr "Receive_block_jobs: zapis do deskryptora '%d' nie powiód³ siê" #: src/common/lpd_rcvjob.c:772 src/common/lpd_rcvjob.c:831 #, c-format msgid "Scan_block_file: lseek failed '%s'" msgstr "Scan_block_file: lseek nie powiod³o siê: '%s'" #: src/common/lpd_rcvjob.c:787 #, c-format msgid "bad length information '%s'" msgstr "b³êdna informacja o d³ugo¶ci '%s'" #: src/common/lpd_rcvjob.c:819 #, c-format msgid "Scan_block_file: read failed '%s'" msgstr "Scan_block_file: odczyt nie powiód³ siê: '%s'" #: src/common/lpd_rcvjob.c:824 msgid "Scan_block_file: read unexecpted EOF" msgstr "Scan_block_file: nieoczekiwany EOF przy odczycie" #: src/common/lpd_rcvjob.c:1017 #, c-format msgid "%s: no permission to print" msgstr "%s: brak uprawnieñ do drukowania" #: src/common/lpd_rcvjob.c:1500 src/common/lpd_rcvjob.c:1525 #, c-format msgid "Do_incoming_control_filter: lseek failed '%s'" msgstr "Do_incoming_control_filter: lseek nie powiod³o siê: '%s'" #: src/common/lpd_rcvjob.c:1613 #, c-format msgid "Get_route: lseek failed '%s'" msgstr "Get_route: lseek nie powiod³o siê: '%s'" #: src/common/lpd_remove.c:73 msgid "missing user or printer name" msgstr "brak nazwy u¿ytkownika lub drukarki" #: src/common/lpd_remove.c:81 src/common/lpd_status.c:175 #, c-format msgid "printer '%s' has illegal character at '%s' in name" msgstr "drukarka '%s' ma nieprawid³owy znak przy '%s' w nazwie" #: src/common/lpd_remove.c:110 #, c-format msgid "Job_remove: error '%s'" msgstr "Job_remove: b³±d '%s'" #: src/common/lpd_remove.c:203 #, c-format msgid "Printer %s@%s:\n" msgstr "Drukarka %s@%s:\n" #: src/common/lpd_remove.c:232 #, c-format msgid " checking perms '%s'\n" msgstr " sprawdzanie uprawnieñ '%s'\n" #: src/common/lpd_remove.c:249 #, c-format msgid " no permissions '%s'\n" msgstr " brak uprawnieñ '%s'\n" #: src/common/lpd_remove.c:263 #, fuzzy, c-format msgid " removing incoming job '%s'\n" msgstr "usuwanie zadania '%s' - JABORT" #: src/common/lpd_remove.c:266 #, c-format msgid " dequeued '%s'\n" msgstr " usuniêto z kolejki '%s'\n" #: src/common/lpd_remove.c:275 #, c-format msgid "error: could not remove '%s'" msgstr "b³±d: nie mo¿na usun±æ '%s'" #: src/common/lpd_remove.c:384 msgid " ERROR: " msgstr " B£¡D: " #: src/common/lpd_secure.c:81 #, c-format msgid "bad command line '%s'" msgstr "b³êdna linia polecenia '%s'" #: src/common/lpd_secure.c:113 #, c-format msgid "bad printer name '%s'" msgstr "b³êdna nazwa drukarki '%s'" #: src/common/lpd_secure.c:124 #, c-format msgid "bad printer '%s'" msgstr "b³êdna drukarka '%s'" #: src/common/lpd_secure.c:166 #, c-format msgid "unsupported authentication '%s'" msgstr "nieobs³ugiwane uwierzytelnienie '%s'" #: src/common/lpd_secure.c:173 #, c-format msgid "no receive method supported for '%s'" msgstr "brak obs³ugiwanej metody otrzymywania dla '%s'" #: src/common/lpd_secure.c:195 #, c-format msgid "%s: job size %0.0f is larger than %d K" msgstr "%s: rozmiar zadania %0.0f jest wiêkszy ni¿ %d K" #: src/common/lpd_status.c:357 #, c-format msgid "%s: no permission to show status" msgstr "%s: brak uprawnieñ do pokazania stanu" #: src/common/lpd_status.c:476 #, c-format msgid " (originally %s)" msgstr " (oryginalnie %s)" #: src/common/lpd_status.c:486 msgid "" "\n" " Error: " msgstr "" "\n" " B³±d: " #: src/common/lpd_status.c:491 #, c-format msgid " - %s" msgstr " - %s" #: src/common/lpd_status.c:494 #, c-format msgid " - printer %s@%s not in printcap" msgstr " - drukarka %s@%s nie wystêpuje w printcap" #: src/common/lpd_status.c:498 #, c-format msgid " - printer %s@%s has bad printcap entry" msgstr " - drukarka %s@%s ma b³êdny wpis w printcap" #: src/common/lpd_status.c:724 #, c-format msgid " " msgstr " " #: src/common/lpd_status.c:736 #, c-format msgid " Job: %s" msgstr " Zadanie: %s" #: src/common/lpd_status.c:737 #, c-format msgid "%s status= %s" msgstr "%s stan= %s" #: src/common/lpd_status.c:740 #, c-format msgid "%s size= %0.0f" msgstr "%s rozmiar= %0.0f" #: src/common/lpd_status.c:743 #, c-format msgid "%s time= %s" msgstr "%s czas= %s" #: src/common/lpd_status.c:747 #, c-format msgid "%s error= %s" msgstr "%s b³±d= %s" #: src/common/lpd_status.c:752 #, c-format msgid "%s CONTROL=" msgstr "%s CONTROL=" #: src/common/lpd_status.c:758 #, c-format msgid "%s HOLDFILE=" msgstr "%s HOLDFILE=" #: src/common/lpd_status.c:778 #, fuzzy, c-format msgid " %d job" msgid_plural " %d jobs" msgstr[0] " %d zadañ" msgstr[1] " %d zadañ" msgstr[2] " %d zadañ" #: src/common/lpd_status.c:782 #, c-format msgid " (%d held)" msgstr " (%d wstrzymanych)" #: src/common/lpd_status.c:787 #, c-format msgid " (%d move)" msgstr " (%d przeniesionych)" #: src/common/lpd_status.c:810 #, c-format msgid " Comment: %s" msgstr " Komentarz: %s" #: src/common/lpd_status.c:821 #, c-format msgid "" "\n" " Printing: %s\n" " Aborted: %s\n" " Spooling: %s" msgstr "" "\n" " Drukowanie: %s\n" " Przerwane: %s\n" " Buforowanie: %s" #: src/common/lpd_status.c:867 #, c-format msgid "" "\n" " %s: " msgstr "" "\n" " %s: " #: src/common/lpd_status.c:875 #, c-format msgid " (%s" msgstr " (%s" #: src/common/lpd_status.c:890 #, c-format msgid "" "\n" " Redirected_to: %s" msgstr "" "\n" " Przekierowane_do: %s" #: src/common/lpd_status.c:893 #, c-format msgid " (redirect %s)" msgstr " (przekierowanie %s)" #: src/common/lpd_status.c:903 #, c-format msgid " (dest %s@%s)" msgstr " (cel %s@%s)" #: src/common/lpd_status.c:910 #, c-format msgid "" "\n" " Serving: %s" msgstr "" "\n" " Wysy³anie: %s" #: src/common/lpd_status.c:913 #, c-format msgid " (serving %s)" msgstr " (wysy³anie %s)" #: src/common/lpd_status.c:920 #, c-format msgid "" "\n" " Classes: %s" msgstr "" "\n" " Klasy: %s" #: src/common/lpd_status.c:923 #, c-format msgid " (classes %s)" msgstr " (klasy %s)" #: src/common/lpd_status.c:930 msgid "" "\n" " Hold_all: on" msgstr "" "\n" " Wstrzymanie_wszystkiego: tak" #: src/common/lpd_status.c:933 msgid " (holdall)" msgstr " (wstrzymanie wszystkiego)" #: src/common/lpd_status.c:940 msgid "" "\n" " Auto_hold: on" msgstr "" "\n" " Autowstrzymanie: tak" #: src/common/lpd_status.c:943 msgid " (autohold)" msgstr " (autowstrzymanie)" #: src/common/lpd_status.c:951 #, c-format msgid "" "\n" " Message: %s" msgstr "" "\n" " Komunikat: %s" #: src/common/lpd_status.c:954 #, c-format msgid " (message: %s)" msgstr " (komunikat: %s)" #: src/common/lpd_status.c:983 msgid " Queue: no printable jobs in queue\n" msgstr " Kolejka: brak drukowalnych zadañ w kolejce\n" #: src/common/lpd_status.c:987 #, fuzzy, c-format msgid " Queue: %d printable job\n" msgid_plural " Queue: %d printable jobs\n" msgstr[0] " Kolejka: %d drukowalnych zadañ\n" msgstr[1] " Kolejka: %d drukowalnych zadañ\n" msgstr[2] " Kolejka: %d drukowalnych zadañ\n" #: src/common/lpd_status.c:994 #, c-format msgid " Holding: %d held jobs in queue\n" msgstr " Wstrzymane: %d wstrzymanych zadañ w kolejce\n" #: src/common/lpd_status.c:1000 msgid " Server: no server active" msgstr " Serwer: brak aktywnych serwerów" #: src/common/lpd_status.c:1003 #, c-format msgid " Server: pid %d active" msgstr " Serwer: pid %d aktywny" #: src/common/lpd_status.c:1011 #, c-format msgid " Unspooler: pid %d active" msgstr " Unspooler: pid %d aktywny" #: src/common/lpd_status.c:1023 #, c-format msgid "%s SPOOLCONTROL=\n" msgstr "%s SPOOLCONTROL=\n" #: src/common/lpd_status.c:1037 msgid " Status: " msgstr " Status: " #: src/common/lpd_status.c:1041 msgid " Filter_status: " msgstr " Status_filtra: " #: src/common/lpd_dispatch.c:39 #, c-format msgid "Dispatch_input: bad request line '%s' from %s" msgstr "Displatch_input: b³êdna linia ¿±dania '%s' od %s" #: src/common/lpd_dispatch.c:177 msgid "Service_connection: getpeername failed" msgstr "Service_connection: getpeername nie powiod³o siê" #: src/common/lpd_dispatch.c:224 msgid "Service_connection: BAD LocalHost_IP value" msgstr "Service_connection: b³êdna warto¶æ LocalHost_IP" #: src/common/lpd_dispatch.c:230 #, c-format msgid "Service_connection: bad protocol family '%d'" msgstr "Service_connection: b³êdna rodzina protoko³ów '%d'" #: src/common/lpd_dispatch.c:261 msgid "no connect permissions" msgstr "brak uprawnieñ do po³±czenia" #: src/common/lpd_dispatch.c:284 #, c-format msgid "Service_connection: peek of length %d failed" msgstr "Service_connection: podgl±d o d³ugo¶ci %d nie powiód³ siê" #: src/common/lpd_dispatch.c:326 #, c-format msgid "Service_connection: cannot read request from %s in %d seconds" msgstr "Service_connection: nie mo¿na odczytaæ ¿±dania od %s w %d sekund" #: src/common/lpd_dispatch.c:330 #, c-format msgid "Service_connection: short request line '%s', from '%s'" msgstr "Service_connection: zbyt krótka linia ¿±dania '%s' od '%s'" #: src/common/lpq.c:119 #, c-format msgid "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n" msgstr "" "Sk³adnia: %s [-aAclV] [-Dpoziom] [-Pdrukarka] [-tczasoczek]\n" " -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± " "AUTH\n" " -a - wszystkie drukarki\n" " -c - wyczyszczenie ekranu przed uaktualnieniem\n" " -l - zwiêkszenie (wyd³u¿enie) szczegó³owych informacji o stanie\n" " dodatkowe flagi l dodaj± wiêcej szczegó³ów.\n" " -L - najbardziej szczegó³owe informacje o stanie\n" " -n linii - tyle linii szczegó³owych informacji o stanie\n" " -Dpoziom - poziom ¶ledzenia (debug level)\n" " -Pdrukarka - podanie drukarki\n" " -s - krótki (sumaryczny) format\n" " -tczasoczek - czas oczekiwania miêdzy uaktualnieniami\n" " -V - wypisanie informacji o wersji\n" " -v - wypisanie w postaci klucz: warto¶æ\n" #: src/common/lpq.c:245 #, c-format msgid "Printer: %s is %s@%s\n" msgstr "Drukarka: %s to %s@%s\n" #: src/common/lpq.c:252 #, c-format msgid "Printer: %s - cannot use printer, not in privileged group\n" msgstr "Drukarka: %s - nie mo¿na u¿yæ drukarki, spoza grupy uprzywilejowanej\n" #: src/common/lpq.c:369 src/common/lpq.c:374 src/common/lpq.c:384 #: src/common/lpq.c:431 src/common/lpq.c:438 msgid "Printer:" msgstr "Drukarka:" #: src/common/lpq.c:477 msgid "fork() failed" msgstr "fork() nie powiod³o siê" #: src/common/lpq.c:484 #, c-format msgid "Term_clear: waitpid(%d) failed" msgstr "Term_clear: waitpid(%d) nie powiod³o siê" #: src/common/lpq.c:510 msgid "lpq: please use the LPRng lpstat program\n" msgstr "lpq: proszê u¿yæ programu LPRng lpstat\n" #: src/common/lpstat.c:195 msgid "scheduler is running\n" msgstr "szeregowanie dzia³a\n" #: src/common/lpstat.c:199 msgid "no system default destination\n" msgstr "brak celu domy¶lnego dla systemu\n" #: src/common/lpstat.c:201 #, c-format msgid "system default destination: %s\n" msgstr "cel domy¶lny dla systemu: %s\n" #: src/common/lpstat.c:208 #, c-format msgid "system for %s: %s\n" msgstr "system dla %s: %s\n" #: src/common/lpstat.c:250 #, c-format msgid " Printer: %s - cannot use printer, not in privileged group\n" msgstr "" " Drukarka: %s - nie mo¿na u¿yæ drukarki, spoza grupy uprzywilejowanej\n" #: src/common/lpstat.c:259 #, c-format msgid " Printer: %s - direct connection to device '%s'\n" msgstr " Drukarka: %s - bezpo¶rednie po³±czenie z urz±dzeniem '%s'\n" #: src/common/lpstat.c:387 #, c-format msgid "" "%s not accepting requests since %s -\n" "\tunknown reason\n" msgstr "" "%s nie przyjmuje ¿±dañ od %s -\n" "\tprzyczyna nieznana\n" #: src/common/lpstat.c:389 #, c-format msgid "%s accepting requests since %s\n" msgstr "%s przyjmuje ¿±dania od %s\n" #: src/common/lpstat.c:397 #, c-format msgid "printer %s unknown state. disabled since %s. available\n" msgstr "drukarka %s w nieznanym stanie. Wy³±czona od %s. Dostêpna\n" #: src/common/lpstat.c:398 #, c-format msgid "printer %s unknown state. enabled since %s. available\n" msgstr "drukarka %s w nieznanym stanie. W³±czona od %s. Dostêpna\n" #: src/common/lpstat.c:404 #, c-format msgid "\tDescription: %s@%s\n" msgstr "\tOpis: %s@%s\n" #: src/common/lpr.c:157 msgid "nothing to print" msgstr "nie ma niczego do wydrukowania" #: src/common/lpr.c:162 msgid "cannot use printer - not in privileged group\n" msgstr "nie mo¿na u¿yæ drukarki - spoza uprzywilejowalnej grupy\n" #: src/common/lpr.c:168 #, c-format msgid "no remote support for %s@%s" msgstr "brak zdalnej obs³ugi dla %s@%s" #: src/common/lpr.c:179 #, c-format msgid "%d data files and maximum allowed %d" msgstr "%d plików danych, a dozwolone %d" #: src/common/lpr.c:221 src/common/lpr.c:1164 #, c-format msgid "Cannot open file '%s', %s" msgstr "Nie mo¿na otworzyæ pliku '%s': %s" #: src/common/lpr.c:232 msgid "(lpr_filter)" msgstr "(filtr_lpr)" #: src/common/lpr.c:295 src/common/lpr.c:332 #, c-format msgid "Status Information, attempt %d:\n" msgstr "Informacje o stanie, próba %d:\n" #: src/common/lpr.c:299 src/common/lpr.c:336 #, c-format msgid " of %d:\n" msgstr " z %d:\n" #: src/common/lpr.c:312 #, c-format msgid "Waiting %d seconds before retry\n" msgstr "czekanie %d sekund przed powtórzeniem\n" #: src/common/lpr.c:351 #, c-format msgid "request id is %s\n" msgstr "id ¿±dania to %s\n" #: src/common/lpr.c:354 #, c-format msgid "request id is %d\n" msgstr "id ¿±dania to %d\n" #: src/common/lpr.c:366 #, c-format msgid "Error unlinking '%s' - %s" msgstr "B³±d podczas usuwania '%s' - %s" #: src/common/lpr.c:374 #, c-format msgid "Done %d\n" msgstr "Zakoñczono %d\n" #: src/common/lpr.c:430 src/common/lpr.c:603 msgid "USER environment variable undefined" msgstr "Nie zdefiniowana zmienna ¶rodowiskowa USER" #: src/common/lpr.c:448 msgid "-ncopies -number of copies must be greater than 0\n" msgstr "-nkopii - liczba kopii musi byæ wiêksza od 0\n" #: src/common/lpr.c:452 msgid "nobanner" msgstr "beznag³ówka" #: src/common/lpr.c:455 msgid "width" msgstr "szeroko¶æ" #: src/common/lpr.c:530 #, c-format msgid "bad -F format string '%s'\n" msgstr "b³êdny ³añcuch formatuj±cy -F '%s'\n" #: src/common/lpr.c:533 #, c-format msgid "duplicate format specification -F%s\n" msgstr "powtórzona specyfikacja formatu -F%s\n" #: src/common/lpr.c:545 msgid "-Kcopies -number of copies must be greater than 0\n" msgstr "-Kkopii - liczba kopii musi byæ wiêksza od 0\n" #: src/common/lpr.c:608 msgid "Missing mail name" msgstr "Brak nazwy dla poczty" #: src/common/lpr.c:622 #, c-format msgid "duplicate format specification -%c\n" msgstr "powtórzona specyfikacja formatu -%c\n" #: src/common/lpr.c:666 #, c-format msgid "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default " "printer.\n" msgstr "" "Sk³adnia: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d drukarka[@host]]\n" " [-f nazwa-form] [-H specjalna-obs³uga]\n" " [-n liczba] [-o opcje] [-P lista-stron]\n" " [-q priorytet] [-S zestaw-znaków]\n" " [-S print-wheel] [-t tytu³]\n" " [-T content-type [-r]] [-y lista-trybów]\n" " [-Dopcje¶ledzenia] [ nazwy plików ... ]\n" " symulator lp u¿ywaj±cy LPRng, funkcjonalno¶æ mo¿e siê nieco ró¿niæ\n" " -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± " "AUTH\n" " -B - filtrowanie plików i zmniejszenie zadania do pojedynczego " "pliku\n" " przed wys³aniem\n" " -c - (tworzenie kopii przed drukowaniem - ignorowane)\n" " -d drukarka[@host] - drukarka na ho¶cie\n" " -D opcje¶ledzenia - flagi ¶ledzenia\n" " -f nazwaformatu - pierwsza litera u¿ywana jako format zadania\n" " -G - filtrowanie poszczególnych plików zadañ przed wys³aniem\n" " -H obs³uga - (przekazywane jako -Z obs³uga)\n" " -m - wys³anie poczty do $USER po zakoñczeniu zadania\n" " -n kopii - liczba kopii\n" " -o opcja rozpoznawane: nobanner, width\n" " (inne przekazywane jako opcja -Z)\n" " -P listastron - (lista stron do drukowania - ignorowana)\n" " -p - (powiadomienie po zakoñczeniu - ignorowane)\n" " -q - priorytet - 0 -> Z (najwy¿szy), 25 -> A (najni¿szy)\n" " -s - (pominiêcie komunikatów - ignorowane)\n" " -S zestaw - zestaw znaków (przekazywany jako -Z zestaw)\n" " -t tytu³ - tytu³ zadania\n" " -T tre¶æ - (przekazywane jako -Z tre¶æ)\n" " -w - (wypisanie komunikatu po zakoñczeniu - ignorowane)\n" " -X ¶cie¿ka - w³asny filtr dla plików zadañ\n" " -Y - po³±czenie i wys³anie na port TCP/IP (tryb bezpo¶redni)\n" " -y tryb - (przekazywane jako -Z tryb)\n" " -- - koniec opcji, reszta to pliki\n" " nazwa pliku '-' oznacza odczyt z STDIN\n" " Zmienne PRINTER, LPDEST, NGPRINTER, NPRINTER wybieraj± domy¶ln± drukarkê.\n" #: src/common/lpr.c:702 #, c-format msgid "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default " "printer.\n" msgstr "" "Sk³adnia: %s [-Pdrukarka[@host]] [-A] [-B] [-Cklasa] [-Fformat] [-G] [-" "Jinfo]\n" " [-(K|#)kopii] [-Q] [-Rnazwakonta] [-Ttytu³] [-Uu¿ytkownik[@host]] [-V]\n" " [-Zopcje] [-b] [-m adrespoczty] [-h] [-i wciêcie] [-l] [-w szeroko¶æ] [-" "r]\n" " [-Dopcje¶ledzenia ] [--] [ nazwy plików ... ]\n" " -A - u¿ycie uwierzytelnienia zgodnego ze zmienn± ¶rodowiskow± " "AUTH\n" " -B - filtrowanie plików i zmniejszenie zadania do pojedynczego " "pliku\n" " przed wys³aniem\n" " -C klasa - klasa zadania\n" " -D opcje¶ledzenia - flagi ¶ledzenia\n" " -F format - format zadania\n" " -b,-l - format binarny lub dok³adny\n" " c,d,f,g,l,m,p,t,v tak¿e s± opcjami formatu\n" " -G - filtrowanie poszczególnych plików zadañ przed wys³aniem\n" " -J info - informacje o nag³ówku i zadaniu\n" " -K kopii, -# kopii - liczba kopii\n" " -P drukarka[@host] - drukarka na ho¶cie\n" " -Q - umieszczenie 'nazwy kolejki' w pliku kontrolnym\n" " -Rnazwakonta - informacje do rozliczeñ\n" " -T tytu³ - tytu³ dla formatowania 'pr' (-p)\n" " -U u¿ytkownik - wymuszenie nazwy u¿ytkownika (ograniczone)\n" " -V - szczegó³owe informacje podczas kolejkowania\n" " -X ¶cie¿ka - w³asny filtr dla plików zadañ\n" " -Y - po³±czenie i wys³anie na port TCP/IP (tryb bezpo¶redni)\n" " -Z opcje - opcje do przekazania do filtra\n" " -h - bez nag³ówka ani strony nag³ówkowej\n" " -i wciêcie - obs³uga wciêæ\n" " -k - nie u¿ywanie pliku tymczasowego przy wysy³aniu do serwera\n" " -m adres - wys³anie statusu poczt± na adres\n" " -r - usuniêcie plików po skolejkowaniu\n" " -w szer - szeroko¶æ do wykorzystania\n" " -- - koniec opcji, reszta to pliki\n" " nazwa pliku '-' oznacza odczyt z STDIN\n" " Zmienne PRINTER, LPDEST, NPRINTER, NGPRINTER wybieraj± domy¶ln± drukarkê.\n" #: src/common/lpr.c:803 msgid "Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)" msgstr "" "Priorytet (pierwsza litera klasy), nie 'A' (najni¿szy) do 'Z' (najwy¿szy)" #: src/common/lpr.c:827 src/common/lpr.c:832 msgid "(STDIN)" msgstr "(STDIN)" #: src/common/lpr.c:881 msgid "-U (username) can only be used by ROOT" msgstr "-U (u¿ytkownik) mo¿e byæ podany tylko przez ROOTa" #: src/common/lpr.c:897 #, c-format msgid "Get_local_host: '%s' FQDN name not found!" msgstr "Get_local_host: nie znaleziono nazwy FQDN '%s'!" #: src/common/lpr.c:924 #, c-format msgid "Bad format specification '%c'" msgstr "B³êdne okre¶lenie formatu '%c'" #: src/common/lpr.c:931 #, c-format msgid "Sorry, can only print %d files at a time, split job up" msgstr "" "Niestety, mo¿na drukowaæ tylko %d plików jednocze¶nie, trzeba podzieliæ " "zadanie" #: src/common/lpr.c:937 #, c-format msgid "Maximum of %d copies allowed" msgstr "Dozwolone maksymalnie %d kopii" #: src/common/lpr.c:1001 msgid "authentication conficts with -k option" msgstr "uwierzytelnienie jest w konflikcie z opcj± -k" #: src/common/lpr.c:1004 msgid "send_block_format configuration option conficts with -k option" msgstr "opcja konfiguracji send_block_format jest w konflikcie z opcj± -k" #: src/common/lpr.c:1007 msgid "send_data_first configuration option conficts with -k option" msgstr "opcja konfiguracji send_data_first jest w konflikcie z opcj± -k" #: src/common/lpr.c:1010 msgid "multiple copies conficts with -k option" msgstr "wiele kopii jest w konflikcie z opcj± -k" #: src/common/lpr.c:1013 msgid "files on command line conflicts with -k option" msgstr "pliki w linii poleceñ s± w konflikcie z opcj± -k" #: src/common/lpr.c:1101 msgid "Make_temp_fd failed" msgstr "Make_temp_fd nie powiod³o siê" #: src/common/lpr.c:1103 msgid "You have closed STDIN! cannot pipe from a closed connection" msgstr "" "STDIN jest zamkniête! nie mo¿na utworzyæ potoku z zamkniêtego po³±czenia" #: src/common/lpr.c:1110 msgid "Copy_STDIN: write to temp file failed" msgstr "Copy_STDIN: zapis do pliku tymczasowego nie powiód³ siê" #: src/common/lpr.c:1115 #, c-format msgid "Copy_STDIN: stat of temp fd '%d' failed" msgstr "Copy_STDIN: stat na tymczasowym deskryptorze '%d' nie powiod³o siê" #: src/common/lpr.c:1171 #, c-format msgid "Check_files: stat of temp fd '%d' failed" msgstr "Check_files: stat na tymczasowym deskryptorze '%d' nie powiod³o siê" #: src/common/lpr.c:1215 #, c-format msgid "cannot print '%s': %s" msgstr "nie mo¿na wydrukowaæ '%s': %s" #: src/common/lpr.c:1224 msgid "not a regular file" msgstr "nie jest zwyk³ym plikiem" #: src/common/lpr.c:1229 msgid "cannot read it" msgstr "nie mo¿na tego przeczytaæ" #: src/common/lpr.c:1244 msgid "" "unprintable characters at start of file, check your LANG environment " "variable as well as the input file" msgstr "" "niedrukowalne znaki na pocz±tku pliku - nale¿y sprawdziæ zmienn± " "¶rodowiskow± LANG oraz plik wej¶ciowy" #: src/common/lpr.c:1251 #, c-format msgid "option '%c' missing argument" msgstr "przy opcji '%c' brakuje argumentu" #: src/common/lpr.c:1270 #, c-format msgid "option %c parameter `%s` is not positive integer value" msgstr "przy opcji %c parametr `%s` nie jest dodatni± liczb± ca³kowit±" #: src/common/lpr.c:1274 #, c-format msgid "option %c parameter `%s` is not integer value from 0 - %d" msgstr "przy opcji %c parametr `%s` nie jest liczb± ca³kowit± od 0 do %d" #: src/common/lprm.c:234 #, c-format msgid "Printer: %s - cannot remove jobs from device '%s'\n" msgstr "Drukarka: %s - nie mo¿na usun±æ zadañ z urz±dzenia '%s'\n" #: src/common/lprm.c:246 #, c-format msgid "Printer: %s - not in privileged group\n" msgstr "Drukarka: %s - spoza uprzywilejowanej grupy\n" #: src/common/lprm.c:354 #, c-format msgid "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n" msgstr "" " Sk³adnia: %s [-A] [-a | -Pdrukarka] [-Dpoziom] (idzad|u¿ytkownik|'all')*\n" " -a - wszystkie drukarki\n" " -A - u¿ycie uwierzytelnienia\n" " -Pdrukarka - drukarka (domy¶lna jest podana przez zmienn± PRINTER)\n" " -Uu¿ytkownik - wcielenie siê w u¿ytkownika (tylko root lub " "uprzywilejowani)\n" " -Dpoziom - poziom ¶ledzenia (debug level)\n" " -V - pokazanie informacji o wersji\n" " u¿ytkownik usuniêcie zadañ u¿ytkownika\n" " all usuniêcie wszystkich zadañ\n" " idzad usuniêcie zadania o tym identyfikatorze\n" " Przyk³ad:\n" " 'lprm -Plp 30' usuwa zadanie 30 z drukarki lp\n" " 'lprm -a' usuwa wszystkie w³asne zadania ze wszystkich drukarek\n" " 'lprm -a all' usuwa wszystkie zadania ze wszystkich drukarek\n" " Uwaga: lprm usuwa tylko zadania do których ma siê prawo usuwania\n" #: src/common/lprm.c:372 #, c-format msgid "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n" msgstr "" " Sk³adnia: %s [-A] [-Dpoziom] (idzad|u¿ytkownik|'all')* [drukarka]\n" " -A - u¿ycie uwierzytelnienia\n" " -Dpoziom - poziom ¶ledzenia (debug level)\n" " u¿ytkownik usuniêcie zadañ u¿ytkownika\n" " all usuniêcie wszystkich zadañ\n" " idzad usuniêcie zadania o tym identyfikatorze\n" " Przyk³ad:\n" " 'clean 30 lp' usuwa zadanie 30 z drukarki lp\n" " 'clean' usuwa pierwsze zadanie z domy¶lnej drukarki\n" " 'clean all' usuwa wszystkie w³asne zadania z domy¶lnej drukarki\n" " 'clean all all' usuwa wszystkie w³asne zadania ze wszystkich drukarek\n" " Uwaga: clean usuwa tylko te zadania, do których ma siê prawo usuwania\n" #: src/common/sendjob.c:169 #, c-format msgid "sleeping %d secs before retry, starting sleep" msgstr "czekanie %d sekund przed powtórzeniem, rozpoczêcie czekania" #: src/common/sendmail.c:87 #, c-format msgid "printer %s job %s" msgstr "drukarka %s zadanie %s" #: src/common/sendmail.c:93 msgid " was successful.\n" msgstr " powiod³o siê.\n" #: src/common/sendmail.c:98 msgid " failed, and retry count was exceeded.\n" msgstr " nie powiod³o siê, licznik prób wygas³.\n" #: src/common/sendmail.c:103 msgid " failed and could not be retried.\n" msgstr " nie powiod³o siê i próba nie mo¿e byæ powtórzona.\n" #: src/common/sendmail.c:108 msgid " died a horrible death.\n" msgstr " zmar³o okropn± ¶mierci±.\n" #: src/common/sendreq.c:114 #, c-format msgid "no network support for '%s' operation" msgstr "brak obs³ugi sieci dla operacji '%s'" #: src/common/getopt.c:82 msgid "--X option form illegal\n" msgstr "Niedozwolona postaæ opcji --X\n" #: src/common/getopt.c:93 #, c-format msgid "%s: Illegal option '%c'\n" msgstr "%s: Niedozwolona opcja '%c'\n" #: src/common/getopt.c:115 #, c-format msgid "%s: missing argument for '%c'\n" msgstr "%s: przy opcji '%c' brakuje argumentu\n" lprng-3.8.B/po/remove-potcdate.sin0000644000131400013140000000066011531672130014027 00000000000000# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } lprng-3.8.B/po/Makefile.am0000644000131400013140000002001711531672130012250 00000000000000# po/Makefile.am for LPRng by Bernhard R. Link in 2007 # this file is based on gettext-0.14.4' Makefile.in.in which states: # # Makefile for PO directory in any package using GNU gettext. # # Copyright (C) 1995-1997, 2000-2005 by Ulrich Drepper # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU General Public # License but which still want to provide support for the GNU gettext # functionality. # Please note that the actual code of GNU gettext is covered by the GNU # General Public License and is *not* in the public domain. LINGUAS = de fr pl vi # what is in the POTFILES.in file in gettextize-style: # i.e. all files that include N_() or _() # if a file is added to this list, touch it so this Makefile sees it. POTFILES.in = \ src/common/accounting.c\ src/common/controlword.c\ src/common/linelist.c\ src/common/lpc.c\ src/common/lpd.c\ src/common/lpd_control.c\ src/common/lpd_jobs.c\ src/common/lpd_rcvjob.c\ src/common/lpd_remove.c\ src/common/lpd_secure.c\ src/common/lpd_status.c\ src/common/lpd_dispatch.c\ src/common/lpq.c\ src/common/lpstat.c\ src/common/lpr.c\ src/common/lprm.c\ src/common/sendjob.c\ src/common/sendmail.c\ src/common/sendreq.c\ src/common/getopt.c\ src/vars.c COPYRIGHT_HOLDER = Patrick Powell at al. # This is the email address or URL to which the translators shall report # bugs in the untranslated strings # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = $(PACKAGE_BUGREPORT) DOMAIN = $(PACKAGE_NAME) XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ ####################################################################### gettextsrcdir = $(datadir)/gettext/po POTFILES = $(patsubst %,$(top_srcdir)/%,$(POTFILES.in)) POFILES = $(patsubst %,$(srcdir)/%.po,$(LINGUAS)) GMOFILES = $(patsubst %,$(srcdir)/%.gmo,$(LINGUAS)) UPDATEPOFILES = $(patsubst %,%.po-update,$(LINGUAS)) DUMMYPOFILES = $(patsubst %,%.nop,$(LINGUAS)) MSGMERGE_UPDATE = @MSGMERGE@ --update # This is kind of a regression the the gettextize Makefile.in.in: # no update-po is run before dist, you have to do so manually # (on the other hand, call it a feature, because this way one can # run make dist more easily) EXTRA_DIST = $(DOMAIN).pot stamp-po remove-potcdate.sin # automake does not like patsubst in EXTRA_DIST, so copy manually: dist-hook: $(POFILES) $(GMOFILES) cp -p $(POFILES) $(GMOFILES) $(distdir)/ %.mo: %.po @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ %.gmo: %.po @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo %.sed: %.sin sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: stamp-po all-no: # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because # we don't want to bother translators with empty POT files). We assume that # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. # In this case, stamp-po is a nop (i.e. a phony target). # stamp-po is a timestamp denoting the last time at which the GMOFILES have # been loosely updated. Its purpose is that when a developer or translator # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, # "make" will update the $(DOMAIN).pot and the $(GMOFILES), but subsequent # invocations of "make" will do nothing. This timestamp would not be necessary # if updating the $(GMOFILES) would always touch them; however, the rule for # $(POFILES) has been designed to not touch files that don't need to be # changed. stamp-po: $(srcdir)/$(DOMAIN).pot test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) @test ! -f $(srcdir)/$(DOMAIN).pot || { \ echo "touch stamp-po" && \ echo timestamp > stamp-poT && \ mv stamp-poT stamp-po; \ } # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. $(DOMAIN).pot-update: $(POTFILES) remove-potcdate.sed $(XGETTEXT) --default-domain=$(DOMAIN) --directory="$(top_srcdir)" \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' \ $(POTFILES.in) test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } # This rule has no dependencies: we don't need to update $(DOMAIN).pot at # every "make" invocation, only create it when it is missing. # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update # This target rebuilds a PO file if $(DOMAIN).pot has changed. # Note that a PO file is not touched if it doesn't need to be changed. $(POFILES): $(srcdir)/$(DOMAIN).pot @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ if test -f "$(srcdir)/$${lang}.po"; then \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \ else \ $(MAKE) $${lang}.po-create; \ fi install-data-local: install-data-local-@USE_NLS@ install-data-local-no: all install-data-local-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) for lang in $(LINGUAS) ; do \ cat=$$lang.gmo \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: for lang in $(LINGUAS) ; do \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo ; \ done MOSTLYCLEANFILES = remove-potcdate.sed stamp-poT core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po DISTCLEANFILES = *.mo MAINTAINERCLEANFILES = Makefile.in stamp-po $(GMOFILES) update-po: Makefile $(MAKE) $(DOMAIN).pot-update $(MAKE) $(UPDATEPOFILES) $(MAKE) $(GMOFILES) # General rule for creating PO files. %.po-create: %.nop @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ exit 1 # General rule for updating PO files. %.po-update: %.nop @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): lprng-3.8.B/po/fr.gmo0000644000131400013140000006341511531672374011352 00000000000000Þ•üüQÜ !( 8 FP _)m— «¹Ðáø ý   %0? N\'b Š « ¸ÅÎ ß# -G ^h ‚ Œ–"¯'Òú® Ïá$ù  *7 I V d+p=œ%Ú=W&sš² Íî!#%9 _€ ˆ2•&È2ï" ( / M S Z 't %œ  È Ñ Ú â )ç (!:!C!J!d!j!)†!°!µ!½!Ô!Ù!Þ!þ!""" "."3"7"K"h" z"„"Ÿ"¹"Â"Ò":Û"#B,#o#x#}#…#$Œ#,±#Þ#å#ë#ò#"÷#!$$<$,a$&Ž$)µ$ß$ý$ %68%o%‡%Œ%%¼%#¿%$ã%;&D& J&V&j&z&~&J“&Þ&ù& ' '9'U'f'w''£'-²' à'î'0(5(O(f(…(Ž(£(#Á($å( ))&)C)X)])u)†)•) ¨)¶)Æ)%Ú)* * * *(*/*$5*Z*k* z* ‡*¨*°*¶* ¿*#Ê*(î*+*+D+Z+*m+˜+ µ+¿+ß+$ÿ+$,@,I,R,e,y,9Š,6Ä,û,--*-2X- ‹-–-"-À-"Ü-ÿ-./. A.-N.'|.¤.¬.,´.'á." /,/1/9/P/gg/Ï/Ý ï/Í9Ó9Uî9D;K; \; j;u; …;.“;Â; Ö;&ä;# </<K<P< g<u<Š<š<©< ¸<Æ<6Ì<"= &=3= D=N=4_= ”=9¡=Û=ù= >>3> H>S>%o>2•> È>ˆÖ>J_A ªD¸D-ÕD E EE .E ¯LîLõLûLM$M#,M%PM6vM(­M9ÖMN0N"LN\oNÌNæNëN ÿN O)#O&MOEtOºOÀOÏOéOøOüOVP!qP“P®P"ÎP$ñPQ/QHQfQ€Q>QÏQâQ9úQ4RTR*rRR¥R·R&×R'þR&S+S;SXSoS tS•S «SµSÊS ÚSæS,öS#T(T9TJTYT`T)fTT¤T·T#ÈTìTôTúT U,U.W4€WµWÔW9íW;'XcXlX/sX%£X-ÉX÷XY(Y;Y:NY*‰Y´Y¼Y1ÃY,õY("ZKZPZXZoZiƒZ#íZÔ [æfîfÝ_§Ëc÷ñ³óFm ›4E@ú邉‡©ªpP:ƒ "—žô¹ãZŠw®Ê0i N”7Hyzºëa«–G!/LBâ‘í\¥áA?ò…ÛÉ.µ£`· ¼k,¡Ú ì ×Ö¨<~ðu‹¿æSTÍõŸåqI}CvèÂ%“ŒX5»Õü­=îQä>±2-^1•˜ï°Ç¤]([t€ˆdg’)¶ùÌ&Ò„sÄjß;$ÆlÔ¦¾MŽK+Ã{œeȬÎnö¸f8WØU꽚ÑJûOhÁ¯ÐÙ3Ïb#V'Y9²ÞÜà*|†RçÀ¢øDr6 ™oxÓÅ´ %s: Auto_hold: on Classes: %s Error: Hold_all: on Message: %s Printing: %s Aborted: %s Spooling: %s Redirected_to: %s Serving: %s checking perms '%s' dequeued '%s' no permissions '%s' (%s (autohold) (classes %s) (dest %s@%s) (holdall) (message: %s) (redirect %s) (serving %s) - %s - printer %s@%s has bad printcap entry - printer %s@%s not in printcap Comment: %s ERROR: Filter_status: Holding: %d held jobs in queue Job: %s Queue: no printable jobs in queue Server: no server active Server: pid %d active Status: Unspooler: pid %d active autohold class=%s died a horrible death. failed and could not be retried. failed, and retry count was exceeded. holdall usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer] -A - use authentication -Ddebuglevel - debug level user removes user jobs all removes all jobs jobid removes job number jobid Example: 'clean 30 lp' removes job 30 on printer lp 'clean' removes first job on default printer 'clean all' removes all your jobs on default printer 'clean all all' removes all your jobs on all printers Note: clean removes only jobs for which you have removal permission usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')* -a - all printers -A - use authentication -Pprinter - printer (default PRINTER environment variable) -Uuser - impersonate this user (root or privileged user only) -Ddebuglevel - debug level -V - show version information user removes user jobs all removes all jobs jobid removes job number jobid Example: 'lprm -Plp 30' removes job 30 on printer lp 'lprm -a' removes all your jobs on all printers 'lprm -a all' removes all jobs on all printers Note: lprm removes only jobs for which you have removal permission was successful. # Printcap Information %d data files and maximum allowed %d%s CONTROL=%s HOLDFILE=%s SPOOLCONTROL= %s error= %s%s status= %s%s time= %s%s: Receive_block_job: sending ACK 0 failed%s: Receive_job - bad control line '%s', len %0.0f, name '%s'%s: Receive_job: sending ACK 0 failed%s: cannot set hold file '%s' %s: cannot set up print queue%s: cannot set up printer%s: insufficient file space%s: job size %0.0f is larger than %d K%s: no permission '%s' %s: no permission to print%s: no permission to show status%s: selected '%s' %s: sending ACK 0 for '%s' failed%s: spooling disabled%s: transfer of '%s' from '%s' failed%s: unknown control request '%s'(STDIN)(lpr_filter)-Kcopies -number of copies must be greater than 0 -U (username) can only be used by ROOT-ncopies -number of copies must be greater than 0 ABORTACTIVEBad format specification '%c'CLASSCLIENTCannot open file '%s', %sCopy_STDIN: stat of temp fd '%d' failedCopy_STDIN: write to temp file failedDEBUGDEFAULTQDEFAULTSDISABLEDOWNDo_queue_control: write to fd '%d' failedDo_queue_jobs: cannot open lockfile '%s'Done %d ENABLEError unlinking '%s' - %sFLUSHFork_subserver: fork failedGet_local_host: '%s' FQDN name not found!HOLDHOLDALLJob_remove: error '%s'KILLLANGLANG environment variable '%s' LPDLPQLPRMLocale information directory '%s' MOVEMSGMake_temp_fd failedMaximum of %d copies allowedMissing mail nameNOHOLDALLNo LPD lockfile specified!No translation available PRINTCAPPrinter %s@%s: Printer:Printer: %s - cannot use printer, not in privileged group Printer: %s is %s@%s Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)REDIRECTREDORELEASEREREADReceive_block_job: lseek failed '%s'Remote_job: %d datafiles and only allowed %dSERVERSTARTSTATUSSTOPScan_block_file: lseek failed '%s'Scan_block_file: read failed '%s'Scan_block_file: read unexecpted EOFService_connection: bad protocol family '%d'Service_connection: getpeername failedService_worker: cannot open lockfile '%s'Setup_log: dup2(%d,%d) failedSetup_log: open %s failedSetup_log: open /dev/null failedSorry, can only print %d files at a time, split job upStart_all: pipe failed!TOPQTRANSLATION TESTTerm_clear: waitpid(%d) failedUPUSER environment variable undefinedWait_for_subserver: Mergesort failedYou have closed STDIN! cannot pipe from a closed connectionabortaborted jobaborting operationsaborting serverallall classes printed authentication requested (-A option) and AUTH environment variable not setbad -F format string '%s' bad command linebad command line '%s'bad control command '%s'bad length information '%s'bad printer '%s'bad printer namebad printer name '%s'cannot print '%s': %scannot read itcannot use printer - not in privileged group class updatedclasses printed '%s' connection to accounting server '%s' failed '%s'could not remove job '%s'debugging override offdebugging override set to '%s'disableddisabled and stoppeddoaction: waitpid(%ld) failedduplicate format specification -%c duplicate format specification -F%s enabledenabled and startederror: could not remove '%s'execvp failed - '%s'exitfailed to send job '%s'failed, no retryflushed statusfork failed - '%s'fork() failedforwarding off forwarding to '%s' gettext translation information '%s' holdholdall offholdall onholding jobjabortjholdjob '%s' attempt %d, trying %d timesjob '%s' removedjob '%s' savedjob '%s', %sjob '%s', attempt %d, allowed %djremovejsuccjsuccesskilled joblink failure while sending job '%s'lpd: Lpd_request pipe EOF! cannot happenlpd: fork() failedlpd: main() dofork failedlpd: pipe call failedlpd: select error!lpq: please use the LPRng lpstat program missing user or printer namemove doneno permission to control serverno permission to spool job '%s'no receive method supported for '%s'no remote support for %s@%sno retrynobannernot a regular filenot implemented yetnothing to printoption %c parameter `%s` is not integer value from 0 - %doption %c parameter `%s` is not positive integer valueoption '%c' missing argumentprinter %s job %sprinter '%s' has illegal char at '%s' in nameprinter '%s' has illegal character at '%s' in nameredirectedremoveremoving destination due to errorsremoving job '%s' - JREMOVEremoving job '%s' - no permissionsremoving job - status JREMOVErequest id is %d request id is %s retrying jobsleeping %d secs before retry, starting sleepsleeping, waiting for processes to exitstartedstoppedstopping printing on filter JABORT exit codesubserver pid %ld died with signal '%s'subserver pid %ld exit status '%s'succsuccesstreating as successfulunexpected status 0x%xunprintable characters at start of file, check your LANG environment variable as well as the input fileunsupported authentication '%s'usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command] with no command, reads from STDIN -a - alias for -Pall -Ddebuglevel - debug level -Pprinter - printer -Pprinter@host - printer on lpd server on host -Shost - connect to lpd server on host -Uuser - identify command as coming from user -V - increase information verbosity commands: active (printer[@host]) - check for active server abort (printer[@host] | all) - stop server class printer[@host] (class | off) - show/set class printing disable (printer[@host] | all) - disable queueing debug (printer[@host] | all) debugparms - set debug level for printer down (printer[@host] | all) - disable printing and queueing enable (printer[@host] | all) - enable queueing flush (printer[@host] | all) - flush cached status hold (printer[@host] | all) (name[@host] | job | all)* - hold job holdall (printer[@host] | all) - hold all jobs on kill (printer[@host] | all) - stop and restart server lpd (printer[@host]) - get LPD PID lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke LPRM msg printer message text - set status message move printer (user|jobid)* target - move jobs to new queue noholdall (printer[@host] | all) - hold all jobs off printcap (printer[@host] | all) - report printcap values quit - exit LPC redirect (printer[@host] | all) (printer@host | off )* - redirect jobs redo (printer[@host] | all) (name[@host] | job | all)* - reprint jobs release (printer[@host] | all) (name[@host] | job | all)* - release jobs reread - LPD reread database information start (printer[@host] | all) - start printing status (printer[@host] | all) - status of printers stop (printer[@host] | all) - stop printing topq (printer[@host] | all) (name[@host] | job | all)* - reorder jobs up (printer[@host] | all) - enable printing and queueing diagnostic: defaultq - show default queue for LPD server defaults - show default configuration values lang - show current i18n (iNTERNATIONALIZATIONn) support client (printer | all) - client config and printcap information server (printer | all) - server config and printcap widthwrong number arguments, %dProject-Id-Version: LPRng 3.8.28 Report-Msgid-Bugs-To: lprng-devel@lists.sf.net POT-Creation-Date: 2011-02-03 19:40+0100 PO-Revision-Date: 2000-08-21 18:06-0700 Last-Translator: Patrick Powell Language-Team: fr MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8-bit %s: Auto_hold: oui Classes: %s Erreur: Hold_all: oui Message: %s Impression: %s Avortement: %s Spoulage: %s Redirected_to: %s Servant: %s vérification des autorisations '%s' enlevé de la file d'attente '%s' pas d'autorisations '%s' (%s (retenue automatique) (classes %s) (destination %s@%s) (tous retenus) (message: %s) (redirigé %s) (servant %s) - %s - printer %s@%s a une entrée incorrecte dans printcap - printer %s@%s pas dans printcap Commentaire: %s ERREUR: Filter_status: Holding: %d travaux retenus dans la file d'attente Travail: %s Queue: pas de travail imprimable dans la file d'attente Server: pas de serveur actif Server: pid %d actif Status: Unspooler: pid %d actif retenue automatique classe=%s mort d'une mort horrible. a échoué et ne peut être re-essayé. a échoué, et le nombre de re-essais est dépassé. retenir tous usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer] -A - utiliser l'authentification -Ddebuglevel - debug level user enlève les travaux utilisateur all enlève tous les travaux jobid enlève le travail numéro jobid Exemple: 'clean 30 lp' enlève le travail 30 de l'imprimante lp 'clean' enlève le premier travail de l'imprimante par défaut 'clean all' enlève tous les travaux de l'imprimante par défaut 'clean all all' enlève tous les travaux de toutes les imprimantes Remarque: lprm n'enlève que les travaux pour lesquels vous avez l'autorisation d'enlèvement usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')* -a - toutes les imprimantes -A - utiliser l'authentification -Pprinter - printer (valeur par défaut variable PRINTER) -Uuser - prendre la personnalité de ce user (seulement root ou utilisateur privilégié) -Ddebuglevel - debug level -V - montrer les informations de version user enlève les travaux utilisateur all enlève tous les travaux jobid enlève le travail numéro jobid Example: Exemple: 'lprm -Plp 30' enlever le trvail 30 de l'imprimante lp 'lprm -a' enlever tous vos travaux de toutes les imprimantes 'lprm -a all' enlever tous les travaux de toutes les imprimantes Remarque: lprm n'enlève que les travaux pour lesquels vous avez l'autorisation d'enlèvement est réussi. # Information pour Printcap %d fichiers de données et maximum autorisé %d%s CONTROL=%s HOLDFILE=%s SPOOLCONTROL= %s erreur= %s%s état= %s%s heure= %s%s: Receive_block_job: envoi ACK 0 a échoué%s: Receive_job - mauvaise ligne de commande '%s', len %0.0f, name '%s'%s: Receive_job: envoi de ACK 0 a échoué%s: ne peut positionner le fichier retenu '%s' %s: ne peut initialiser la file d'impression%s: ne peut initialiser l'imprimante%s: espace de fichier insuffisant%s: taille du travail %0.0f plus grande que %d K%s: pas l'autorisation '%s' %s: pas d'autorisation pour imprimer%s: pas d'autorisation pour montrer l'état%s: selectionné '%s' %s: envoi de ACK 0 pour '%s' a échoué%s: spoulage désarmé%s: transfert de '%s' depuis '%s' a échoué%s: demande de contrôle inconnue '%s'(STDIN)(lpr_filter)-Kcopies - nombre de copies doit être supérieur à 0 -U (username) ne peut être utilisé que par ROOT-ncopies - nombre de copies doit être supérieur à 0 ABORTACTIVEMauvaise spécification de format '%c'CLASSCLIENTNe peut ouvrir le fichier '%s', %sCopy_STDIN: atteindre les données temporaire '%d' a échouéCopy_STDIN: écriture vers le fichier temporaire a échouéDEBUGDEFAULTQDEFAULTSDISABLEDOWNDo_queue_control: écriture sur '%d' a échouéDo_queue_jobs: ne peut ouvrir fichier de blocage '%s'Fait %d ENABLEErreur en déliant '%s' - %sFLUSHFork_subserver: fork a échouéGet_local_host: '%s' nom FQDN non trouvé!HOLDHOLDALLJob_remove: erreur '%s'KILLLANGvariable d'environnement LANG '%s' LPDLPQLPRMRépertoire information de localisation '%s' MOVEMSGMake_temp_fd a échoué%d copies maximum autoriséesManque nom de boîte à lettreNOHOLDALLPas de fichier de blocage LPD spécifié!Pas de traduction disponible PRINTCAPImprimante %s@%s: Printer:Printer: %s - ne peut utiliser l'imprimante, pas dans un groupe privilégié Printer: %s est %s@%s Priorité (première lettre de Class) pas 'A' (le plus bas) à 'Z' (le plus haut)REDIRECTREDORELEASEREREADReceive_block_job: lseek a échoué '%s'Remote_job: %d seuls les fichiers de données aont autorisés %dSERVERSTARTSTATUSSTOPScan_block_file: lseek a échoué '%s'Scan_block_file: read a échoué '%s'Scan_block_file: read EOF intempestifService_connection: mauvaise famille '%d' de protocoleService_connection: getpeername a échouéService_worker: ne peut ouvrir le fichier de blocage '%s'Setup_log: dup2(%d,%d) a échouéSetup_log: open %s a échouéSetup_log: open /dev/null a échouéDésolé, seulement %d fichiers peuvent être imprimés à la fois, revoir la division du travailStart_all: pipe a échoué!TOPQFR TRANSLATION TESTTerm_clear: waitpid(%d) a échouéUPvariable d'environnement USER non définieWait_for_subserver: Mergesort a échouéVous avez fermé STDIN! ne peut faire pipe depuis une connexion ferméeaborttravail avortéavortement des opérationsserveur avortéalltoutes les classes imprimées authentification demandée (option -A) et variable d'environnement AUTH non positionnéemauvaise chîne de format -F '%s' mauvaise ligne de commandemauvaise ligne de commande '%s'mauvaise commande de contrôle '%s'mauvaise longueur d'information '%s'mauvaise imprimante '%s'mauvais nom d'imprimantemauvais nom d'imprimante '%s'ne peut imprimer '%s': %sne peut le lirene peut utiliser l'imprimante - pas dans le groupe privilégié classe mise à jourclasses imprimées '%s' la connexion au serveur de comtabilité '%s' a échoué '%s'ne peut enlever le travail '%s'niveau de debug surchargé nonniveau de debug surchargé positonné à '%s'désarmédésarmé et arrétédoaction: waitpid(%ld) a échouéspécification de format dupliquée -%c spécification de format dupliquée -F%s arméarmé et démarréerreur: ne peut enlever '%s'execvp a échoué - '%s'exitéchec de l'envoi du travail '%s'échec, pas de réessaiétat vidéfork a échoué - '%s'fork() a échouérenvoi non renvoyé à '%s' information de traduction pour gettext '%s' holdretenir tous nonretenir tous ouitravail retenujabortjholdtravail '%s' tentative %d, essayé %d foistravail '%s' enlevétravail '%s' sauvétravail '%s', %stravail '%s', essai %d, autorisé %djremovejsuccjsuccesstravail tuééchec du lien lors de l'envoi du travail'%s'lpd: Lpd_request pipe EOF! ne doit pas arriverlpd: fork() a échouélpd: main() dofork a échouélpd: pipe call a échouélpd: select erreur!lpq: veuillez utiliser le programme LPRng lpstat manque le nom d'utilisateur ou d'imprimantedéplacé faitpas d'autorisation pour contrôler le serveurpas d'autorisation pour spoulé le travail '%s'pas de méthode de réception supportée pour '%s'pas de support distant pour %s@%spas de reessaipas de bannièrepas un fichier régulierpas encore implémentérien à imprimeroption %c paramètre `%s` n'est pas une valeur entière dans 0 - %doption %c paramètre `%s` n'est pas un entier positifoption '%c' manque un argumentimprimante %s travail %sl'imprimante '%s' a un caractère illégal '%s' dans le noml'imprimante '%s' a un caractère illégal a '%s' dans le nomredirigéremoveélimination de la destination due à des erreursélimination du travail '%s' - JREMOVEenlever le travail '%s' - pas d'autorisationstravail enlevé - état JREMOVEid demandé est %d id demandé est %s reessai du travailmise en veille %d secondes avant re-essai, debut de veillesleeping, attente de l'arrêt des processusdémarréarrétéarrêt du filtre d'impression, code d'arrêt JABORTsous-serveur pid %ld tué avec le signal '%s'sous-serveur pid %ld état de sortie '%s'succsuccesstraité comme un succèsétat inattendu 0x%xcractères non-imprimables au début du fichier, vérifier votre variable LANG ainsi que le fichier d'entréeauthentification non supportée '%s'usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command] sans commande, lecture depuis STDIN -a - alias pour -Pall -Ddebuglevel - niveau de debug -Pprinter - specifie l'imprimante -P printer[@host] - imprimante sur le hôte -Shost - connexion au serveur lpd sur l'hôte -Uuser - identifie la commande comme venant de l'utilisateur -V - accroissement du nombre de messages explicatifs commandes: active (printer[@host]) - test pour un serveur actif abort (printer[@host] | all) - arrêt du serveur class printer[@host] (class | off) - montrer/positionner la classe d'impression disable (printer[@host] | all) - interdire la mise en file d'attente debug (printer[@host] | all) debugparms - positionner le niveau de debug pour l'imprimante down (printer[@host] | all) - interdire l'impression et la mise en file d'attente enable (printer[@host] | all) - autoriser la mise en file d'attente flush (printer[@host] | all) - vider les status du cache hold (printer[@host] | all) (name[@host] | job | all)* - retenir le travail holdall (printer[@host] | all) - retenir tous les travaux kill (printer[@host] | all) - arreter et redémarrer le serveur lpd (printer[@host]) - obtenir le PID de LPD lpq (printer[@host] | all) (name[@host] | job | all)* - invoquer LPQ lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoquer LPRM msg printer message text - positionner le message de status move printer (user|jobid)* target - déplacer les travaux vers une nouvelle file d'attente noholdall (printer[@host] | all) - ne plus retenir les travaux printcap (printer[@host] | all) - rapporter les valeur de printcap quit - sortie de LPC redirect (printer[@host] | all) (printer@host | off )* - rediriger les travaux redo (printer[@host] | all) (name[@host] | job | all)* - refaire le travail release (printer[@host] | all) (name[@host] | job | all)* - relacher le travail reread (printer[@host]) - LPD relire la base de données d'information start (printer[@host] | all) - démarrer l'impression status (printer[@host] | all) - état des imprimantes stop (printer[@host] | all) - arrêt de l'impression topq (printer[@host] | all) (name[@host] | job | all)* - relancer le travail up (printer[@host] | all) - autoriser l'impression et la mise en file d'attente defaultq - montrer la file d'attente par défaut du serveur LPD defaults - montrer les valeurs par défaut de la configuration lang - montrer le support courant de i18n (iNTERNATIONALISATIONn) client (printer | all) - information sur la configuration client et printcap server (printer | all) - information sur la configuration du serveur et printcap largeurmauvais nombre d'arguments, %dlprng-3.8.B/po/Makefile.in0000644000131400013140000004260411531672272012276 00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # po/Makefile.am for LPRng by Bernhard R. Link in 2007 # this file is based on gettext-0.14.4' Makefile.in.in which states: # # Makefile for PO directory in any package using GNU gettext. # # Copyright (C) 1995-1997, 2000-2005 by Ulrich Drepper # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU General Public # License but which still want to provide support for the GNU gettext # functionality. # Please note that the actual code of GNU gettext is covered by the GNU # General Public License and is *not* in the public domain. VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = po DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHGRP = @CHGRP@ CHOWN = @CHOWN@ CLEAR = @CLEAR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_LIBS = @DL_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FILTER_LD_PATH = @FILTER_LD_PATH@ FILTER_PATH = @FILTER_PATH@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ INCLUDELPDCONFLOCAL = @INCLUDELPDCONFLOCAL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_MAN = @INSTALL_MAN@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KERBEROS = @KERBEROS@ KRB5CONFIG = @KRB5CONFIG@ KRB_LIBS = @KRB_LIBS@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCKFILE = @LOCKFILE@ LPD_CONF_PATH = @LPD_CONF_PATH@ LPD_LISTEN_PORT = @LPD_LISTEN_PORT@ LPD_PERMS_PATH = @LPD_PERMS_PATH@ LPD_PRINTCAP_PATH = @LPD_PRINTCAP_PATH@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NOREMOTE = @NOREMOTE@ OBJEXT = @OBJEXT@ OPENSSL = @OPENSSL@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PLUGINUSER_LDFLAGS = @PLUGINUSER_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PRINTCAP_PATH = @PRINTCAP_PATH@ PRIV_PORTS = @PRIV_PORTS@ PRUTIL = @PRUTIL@ SD_DEFAULT = @SD_DEFAULT@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSL_CA_FILE = @SSL_CA_FILE@ SSL_CA_KEY = @SSL_CA_KEY@ SSL_CERTS_DIR = @SSL_CERTS_DIR@ SSL_CRL_FILE = @SSL_CRL_FILE@ SSL_LDADD = @SSL_LDADD@ SSL_SERVER_CERT = @SSL_SERVER_CERT@ SSL_SERVER_PASSWORD_FILE = @SSL_SERVER_PASSWORD_FILE@ STRIP = @STRIP@ UNIXSOCKETPATH = @UNIXSOCKETPATH@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ filterdir = @filterdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lpdbindir = @lpdbindir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ LINGUAS = de fr pl vi # what is in the POTFILES.in file in gettextize-style: # i.e. all files that include N_() or _() # if a file is added to this list, touch it so this Makefile sees it. POTFILES.in = \ src/common/accounting.c\ src/common/controlword.c\ src/common/linelist.c\ src/common/lpc.c\ src/common/lpd.c\ src/common/lpd_control.c\ src/common/lpd_jobs.c\ src/common/lpd_rcvjob.c\ src/common/lpd_remove.c\ src/common/lpd_secure.c\ src/common/lpd_status.c\ src/common/lpd_dispatch.c\ src/common/lpq.c\ src/common/lpstat.c\ src/common/lpr.c\ src/common/lprm.c\ src/common/sendjob.c\ src/common/sendmail.c\ src/common/sendreq.c\ src/common/getopt.c\ src/vars.c COPYRIGHT_HOLDER = Patrick Powell at al. # This is the email address or URL to which the translators shall report # bugs in the untranslated strings # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = $(PACKAGE_BUGREPORT) DOMAIN = $(PACKAGE_NAME) XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ ####################################################################### gettextsrcdir = $(datadir)/gettext/po POTFILES = $(patsubst %,$(top_srcdir)/%,$(POTFILES.in)) POFILES = $(patsubst %,$(srcdir)/%.po,$(LINGUAS)) GMOFILES = $(patsubst %,$(srcdir)/%.gmo,$(LINGUAS)) UPDATEPOFILES = $(patsubst %,%.po-update,$(LINGUAS)) DUMMYPOFILES = $(patsubst %,%.nop,$(LINGUAS)) MSGMERGE_UPDATE = @MSGMERGE@ --update # This is kind of a regression the the gettextize Makefile.in.in: # no update-po is run before dist, you have to do so manually # (on the other hand, call it a feature, because this way one can # run make dist more easily) EXTRA_DIST = $(DOMAIN).pot stamp-po remove-potcdate.sin MOSTLYCLEANFILES = remove-potcdate.sed stamp-poT core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po DISTCLEANFILES = *.mo MAINTAINERCLEANFILES = Makefile.in stamp-po $(GMOFILES) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign po/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign po/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-data-local install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-local .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic dist-hook \ distclean distclean-generic distdir dvi dvi-am html html-am \ info info-am install install-am install-data install-data-am \ install-data-local install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-local # automake does not like patsubst in EXTRA_DIST, so copy manually: dist-hook: $(POFILES) $(GMOFILES) cp -p $(POFILES) $(GMOFILES) $(distdir)/ %.mo: %.po @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ %.gmo: %.po @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo %.sed: %.sin sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: stamp-po all-no: # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because # we don't want to bother translators with empty POT files). We assume that # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. # In this case, stamp-po is a nop (i.e. a phony target). # stamp-po is a timestamp denoting the last time at which the GMOFILES have # been loosely updated. Its purpose is that when a developer or translator # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, # "make" will update the $(DOMAIN).pot and the $(GMOFILES), but subsequent # invocations of "make" will do nothing. This timestamp would not be necessary # if updating the $(GMOFILES) would always touch them; however, the rule for # $(POFILES) has been designed to not touch files that don't need to be # changed. stamp-po: $(srcdir)/$(DOMAIN).pot test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) @test ! -f $(srcdir)/$(DOMAIN).pot || { \ echo "touch stamp-po" && \ echo timestamp > stamp-poT && \ mv stamp-poT stamp-po; \ } # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. $(DOMAIN).pot-update: $(POTFILES) remove-potcdate.sed $(XGETTEXT) --default-domain=$(DOMAIN) --directory="$(top_srcdir)" \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' \ $(POTFILES.in) test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } # This rule has no dependencies: we don't need to update $(DOMAIN).pot at # every "make" invocation, only create it when it is missing. # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update # This target rebuilds a PO file if $(DOMAIN).pot has changed. # Note that a PO file is not touched if it doesn't need to be changed. $(POFILES): $(srcdir)/$(DOMAIN).pot @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ if test -f "$(srcdir)/$${lang}.po"; then \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) && $(MSGMERGE_UPDATE) $${lang}.po $(DOMAIN).pot; \ else \ $(MAKE) $${lang}.po-create; \ fi install-data-local: install-data-local-@USE_NLS@ install-data-local-no: all install-data-local-yes: all $(mkinstalldirs) $(DESTDIR)$(datadir) for lang in $(LINGUAS) ; do \ cat=$$lang.gmo \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkinstalldirs) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ done uninstall-local: uninstall-local-@USE_NLS@ uninstall-local-no: uninstall-local-yes: for lang in $(LINGUAS) ; do \ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo ; \ done update-po: Makefile $(MAKE) $(DOMAIN).pot-update $(MAKE) $(UPDATEPOFILES) $(MAKE) $(GMOFILES) # General rule for creating PO files. %.po-create: %.nop @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ exit 1 # General rule for updating PO files. %.po-update: %.nop @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if $(MSGMERGE) $$lang.po $(DOMAIN).pot -o $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lprng-3.8.B/po/vi.po0000644000131400013140000017512611531672130011206 00000000000000# Vietnamese translation for LPRNG. # Copyright © 2008 Free Software Foundation, Inc. # This file is distributed under the same license as the lprng package. # Clytie Siddall , 2007-2008. # #: src/common/lpc.c:270 src/common/lpc.c:435 src/common/lpq.c:547 msgid "" msgstr "" "Project-Id-Version: lprng 3.8.A\n" "Report-Msgid-Bugs-To: lprng-devel@lists.sf.net\n" "POT-Creation-Date: 2011-02-03 19:40+0100\n" "PO-Revision-Date: 2008-07-15 23:31+0930\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: LocFactoryEditor 1.7b3\n" #: src/common/accounting.c:134 #, c-format msgid "connection to accounting server '%s' failed '%s'" msgstr "kết nối đến máy phục vụ kế toán « %s » bị lá»—i « %s »" #: src/common/controlword.c:16 msgid "ABORT" msgstr "HỦY_BỎ" #: src/common/controlword.c:17 msgid "ACTIVE" msgstr "HOẠT_ÄỘNG" #: src/common/controlword.c:18 msgid "CLASS" msgstr "HẠNG" #: src/common/controlword.c:19 msgid "CLIENT" msgstr "KHÃCH" #: src/common/controlword.c:20 msgid "DEBUG" msgstr "Gá»  Lá»–I" #: src/common/controlword.c:21 msgid "DEFAULTQ" msgstr "HÀNG ÄỢI MẶC ÄỊNH" #: src/common/controlword.c:22 msgid "DISABLE" msgstr "TẮT" #: src/common/controlword.c:23 msgid "DOWN" msgstr "XUá»NG" #: src/common/controlword.c:24 msgid "ENABLE" msgstr "BẬT" #: src/common/controlword.c:25 msgid "HOLD" msgstr "GIá»® LẠI" #: src/common/controlword.c:26 msgid "HOLDALL" msgstr "GIá»® LẠI TẤT CẢ" #: src/common/controlword.c:27 msgid "KILL" msgstr "GIẾT" #: src/common/controlword.c:28 msgid "LPD" msgstr "LPD" #: src/common/controlword.c:29 msgid "LPQ" msgstr "LPQ" #: src/common/controlword.c:30 msgid "LPRM" msgstr "LPRM" #: src/common/controlword.c:31 msgid "MOVE" msgstr "CHUYỂN" #: src/common/controlword.c:32 msgid "MSG" msgstr "THÔNG ÄIỆP" #: src/common/controlword.c:33 msgid "NOHOLDALL" msgstr "KHÔNG GIá»® LẠI TẤT CẢ" #: src/common/controlword.c:34 msgid "PRINTCAP" msgstr "PRINTCAP" #: src/common/controlword.c:35 msgid "REDIRECT" msgstr "CHUYỂN HƯỚNG" #: src/common/controlword.c:36 msgid "REDO" msgstr "LÀM LẠI" #: src/common/controlword.c:37 msgid "RELEASE" msgstr "PHÃT HÀNH" #: src/common/controlword.c:38 msgid "REREAD" msgstr "ÄỌC LẠI" #: src/common/controlword.c:39 msgid "START" msgstr "CHẠY" #: src/common/controlword.c:40 msgid "STATUS" msgstr "TRẠNG THÃI" #: src/common/controlword.c:41 msgid "STOP" msgstr "DỪNG" #: src/common/controlword.c:42 msgid "TOPQ" msgstr "HÀNG ÄỢI ÄẦU" #: src/common/controlword.c:43 msgid "UP" msgstr "LÊN" #: src/common/controlword.c:44 msgid "SERVER" msgstr "TRÃŒNH PHỤC VỤ" #: src/common/controlword.c:45 msgid "DEFAULTS" msgstr "MẶC ÄỊNH" #: src/common/controlword.c:46 msgid "FLUSH" msgstr "XOà SẠCH" #: src/common/controlword.c:47 msgid "LANG" msgstr "NGÔN NGá»®" #: src/common/controlword.c:48 msgid "PPD" msgstr "PPD" #: src/common/lpc.c:129 src/common/lpq.c:181 src/common/lpstat.c:147 #: src/common/lpr.c:91 src/common/lprm.c:146 msgid "" "authentication requested (-A option) and AUTH environment variable not set" msgstr "" "yêu cầu xác thá»±c (tùy chá»n -A) nhưng chưa đặt biến môi trưá»ng xác thá»±c AUTH" #: src/common/lpc.c:198 msgid "exit" msgstr "thoát" #: src/common/lpc.c:242 src/common/lpq.c:237 #, c-format msgid "Printer: %s - cannot get status from device '%s'\n" msgstr "Máy in: %s — không thể lấy trạng thái từ thiết bị « %s »\n" #: src/common/lpc.c:249 src/common/lpq.c:259 src/common/lprm.c:253 #, c-format msgid "Printer: %s - direct connection to device '%s'\n" msgstr "Máy in: %s — kết nối trá»±c tiếp tá»›i thiết bị « %s »\n" #: src/common/lpc.c:267 #, c-format msgid "Locale information directory '%s'\n" msgstr "Thư mục thông tin miá»n địa phương « %s »\n" #: src/common/lpc.c:269 src/common/lpc.c:434 src/common/lpq.c:546 #, c-format msgid "LANG environment variable '%s'\n" msgstr "Biến môi trưá»ng ngôn ngữ LANG « %s »\n" #: src/common/lpc.c:272 src/common/lpc.c:437 src/common/lpq.c:549 #, c-format msgid "gettext translation information '%s'\n" msgstr "Thông tin dịch gettext « %s »\n" #: src/common/lpc.c:274 src/common/lpc.c:439 src/common/lpq.c:551 msgid "No translation available\n" msgstr "Không có sẵn bản dịch\n" #: src/common/lpc.c:276 msgid "TRANSLATION TEST" msgstr "THỬ BẢN DỊCH" #: src/common/lpc.c:306 src/common/lpc.c:317 src/common/lpc.c:335 msgid "all" msgstr "tất cả" #: src/common/lpc.c:312 src/common/lpc.c:321 msgid "# Printcap Information\n" msgstr "# Thông tin Printcap\n" #: src/common/lpc.c:350 #, c-format msgid "execvp failed - '%s'" msgstr "lá»—i execvp - '%s'" #: src/common/lpc.c:353 #, c-format msgid "fork failed - '%s'" msgstr "lá»—i tạo tiến trình con - '%s'" #: src/common/lpc.c:361 #, c-format msgid "doaction: waitpid(%ld) failed" msgstr "doaction: waitpid(%ld) bị lá»—i" #: src/common/lpc.c:452 #, c-format msgid "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke " "LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect " "jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint " "jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release " "jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder " "jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) " "support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n" msgstr "" "cách sá»­ dụng: %s [-a][-Dcấp_gỡ_lá»—i][-Pmáy_in][-Smáy][-Utên_ngưá»i_dùng][-V] " "[lệnh]\n" " không có lệnh thì Ä‘á»c từ thiết bị nhập chuẩn STDIN\n" " -a \t\t— bí danh cho « -Pall »\n" " -Dcấp_gỡ_lá»—i \t— cấp gỡ lá»—i\n" " -Pmáy_in \t\t— máy in\n" " -Pmáy_in@máy\t— máy in trên trình phục vụ lpd trên máy này\n" " -Smáy\t\t\t— kết nối tá»›i trình phục vụ lpd chạy trên máy này\n" " -Ungưá»i_dùng\t— nhận ra lệnh như đã đến từ ngưá»i dùng này\n" " -V \t\t— tăng cấp chi tiết\n" "\n" " lệnh:\n" "[all\t\ttất cả\n" "class\thạng\n" "host\t\tmáy\n" "job\t\tcông việc\n" "jobid\tmã nhận diện công việc\n" "off\t\ttắt]\n" "\n" " active (máy_in[@máy])\t\t— kiểm tra có trình phục vụ Ä‘ang chạy không\n" "\t(_hoạt động_)\n" " abort (máy_in[@máy] | all) \t— dừng chạy trình phục vụ\n" "\t(_há»§y bá»_)\n" " class máy_in[@máy] (class | off)\t— hiện/đặt cách in hạng\n" "\t(_hạng_)\n" " disable (máy_in[@máy] | all) \t— tắt khả năng dùng hàng đợi\n" "\t(_tắt_)\n" " debug (máy_in[@máy] | all) các_tham_số_gỡ_lá»—i\n" "\t\t\tđặt cấp gỡ lá»—i cho máy in\n" "\t(_gỡ lá»—i_)\n" " down (máy_in[@máy] | all)\ttắt khả năng in và dùng hàng đợi\n" "\t(_xuống_)\n" " enable (máy_in[@máy] | all)\t— bật khả năng dùng hàng đợi\n" "\t(_bật_)\n" " flush (máy_in[@máy] | all)\t— xoá sạch trạng thái đã nhá»› tạm\n" "\t(_xoá sạch_)\n" " hold (máy_in[@máy] | all) (tên[@máy] | job | all)*\n" "\t\t\tgiữ lại công việc\n" "\t(_giữ lại_)\n" " holdall (máy_in[@máy] | all)\t— giữ lại má»i công việc đã bật\n" "\t(_giữ lại tất cả_)\n" " kill (máy_in[@máy] | all) \t\t— dừng chạy rồi khởi chạy lại trình phục " "vụ\n" "\t(_giết_)\n" " lpd (máy_in[@máy])\t\t\t— lấy PID cá»§a LPD\n" " lpq (máy_in[@máy] | all) (tên[@máy] | job | all)*\n" "\t\t\tgá»i LPQ\n" " lprm (máy_in[@máy] | all) (tên[@máy]|host|job| all)*\n" "\t\t\tgá»i LPRM\n" " msg Ä‘oạn_thông_Ä‘iệp_máy_in\n" "\t\t\tđặt thông Ä‘iệp trạng thái\n" "\t(_thông Ä‘iệp [viết tắt]_)\n" " move máy_in (ngưá»i_dùng|jobid)* đích\n" "\t\t\tdi chuyển các công việc vào hàng đợi má»›i\n" "\t(_di chuyển_)\n" " noholdall (máy_in[@máy] | all)\t— giữ lại má»i công việc bị tắt\n" "\t(_không giữ lại tất cả_)\n" " printcap (máy_in[@máy] | all)\t— thông báo các giá trị printcap\n" " quit \t\t— thoát khá»i LPC\n" "\t(_thoát_)\n" " redirect (máy_in[@máy] | all) (máy_in@máy | off )*\n" "\t\t\tchuyển hướng công việc\n" "\t(_chuyển tiếp_)\n" " redo (máy_in[@máy] | all) (tên[@máy] | job | all)*\n" "\t\t\tin lại công việc\n" "\t(_làm lại_)\n" " release (máy_in[@máy] | all) (tên[@máy] | job | all)*\n" "\t\t\tphát hành công việc\n" "\t(_phát hành_)\n" " reread \t\t— LPD Ä‘á»c lại thông tin cÆ¡ sở dữ " "liệu\n" "\t(_Ä‘á»c lại_)\n" " start (máy_in[@máy] | all)\t\t— bắt đầu in\n" "\t(_bắt đầu_)\n" " status (máy_in[@máy] | all)\t— trạng thái cá»§a máy in\n" "\t(_trạng thái_)\n" " stop (máy_in[@máy] | all)\t— dừng in\n" "\t(_dừng_)\n" " topq (máy_in[@máy] | all) (tên[@máy] | job | all)*\n" "\t\t\tthay đổi thứ tá»± các công việc\n" "\t(_thứ tá»± lại_)\n" " up (máy_in[@máy] | all) \t— bật khả năng in và dùng hàng đợi\n" "\n" " chẩn Ä‘oán:\n" " defaultq \t— hiện hàng đợi mặc định cho trình phục vụ " "LPD\n" "\t\t(_hàng đợi mặc định [viết tắt_)\n" " defaults \t— hiện các giá trị cấu hình mặc định\n" "\t\t(_các mặc định_)\n" " lang \t— hiện cấp há»— trợ quốc tế hoá hiện thá»i\n" "\t\t(_ngôn ngữ [viết tắt]_)\n" " client (máy_in | all) \t— thông tin vá» cấu hình trình khách và " "printcap\n" "\t\t(_khách_)\n" " server (máy_in | all) — thông tin vá» cấu hình trình phục vụ và " "printcap\n" "\t\t(_máy/trình phục vụ_)\n" #: src/common/lpd.c:178 msgid "No LPD lockfile specified!" msgstr "Chưa xác định tập tin khoá LPD." #: src/common/lpd.c:189 src/common/lpd.c:202 #, c-format msgid "Another print spooler active, possibly lpd process '%ld'" msgstr "Bá»™ cuá»™n vào ống khác Ä‘ang chạy, có thể tiến trình lpd « %ld »" #: src/common/lpd.c:194 #, c-format msgid "cannot open or lock lockfile - %s" msgstr "không thể mở hay khoá tập tin khoá — %s" #: src/common/lpd.c:267 msgid "lpd: main() dofork failed" msgstr "lpd: main() dofork bị lá»—i" #: src/common/lpd.c:312 src/common/lpd.c:323 msgid "lpd: pipe call failed" msgstr "lpd: lá»—i gá»i ống dẫn" #: src/common/lpd.c:330 msgid "lpd: cannot start initial logger process" msgstr "lpd: không thể khởi chạy tiến trình ghi lưu đầu tiên" #: src/common/lpd.c:683 msgid "lpd: select error!" msgstr "lpd: lá»—i chá»n." #: src/common/lpd.c:710 msgid "lpd: Lpd_request pipe EOF! cannot happen" msgstr "" "lpd: gặp kết thúc tập tin khi gá»­i yêu cầu Lpd_request qua ống dẫn: không thể " "xảy ra." #: src/common/lpd.c:735 src/common/lpd.c:738 msgid "Setup_log: open /dev/null failed" msgstr "Setup_log: lá»—i mở « /dev/null »" #: src/common/lpd.c:745 src/common/lpd.c:749 #, c-format msgid "Setup_log: dup2(%d,%d) failed" msgstr "Setup_log: dup2(%d,%d) bị lá»—i" #: src/common/lpd.c:754 #, c-format msgid "Setup_log: open %s failed" msgstr "Setup_log: lá»—i mở %s" #: src/common/lpd.c:792 msgid "lpd: Cannot truncate lock file" msgstr "lpd: không thể cắt ngắn tập tin khoá" #: src/common/lpd.c:810 #, c-format msgid "lpd: Cannot open lock file '%s'" msgstr "lpd: không thể mở tập tin khoá « %s »" #: src/common/lpd.c:912 #, c-format msgid "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" msgstr "" "cách sá»­ dụng: %s [-FV][-D cấp_gỡ_lá»—i][-L bản_ghi][-P đưá»ng_dẫn][-p cổng][-R " "CX]\n" "[CX\t\tcổng đích TCP/IP LPD từ xa\n" "\n" " Tùy chá»n\n" " -D cấp_gỡ_lá»—i\t— đắt cấp gỡ lá»—i và các cá»\n" " -F \t\t\t— chạy trong cảnh gần, ghi lưu vào STDERR\n" " -L bản_ghi\t\t— phụ thêm thông tin ghi lưu vào tập tin bản ghi này\n" " -V \t\t— hiện thông tin phiên bản\n" " -p cổng\t\t\t— cổng lắng nghe TCP/IP:\n" "\t\t\tthêm cỠ« off » (tắt) thì tắt cổng nghê TCP/IP (lpd_listen_port)\n" " -P đưá»ng_dẫn\t— đưá»ng dẫn ổ cắm UNIX:\n" "\t\t\tthêm cỠ« off » (tắt) thì tắt ổ cắm lắng nghe UNIX (unix_socket_path)\n" " -R cổng\t\t\t— cổng trình phục vụ LPD từ xa (lpd_port)\n" #: src/common/lpd.c:1001 msgid "lpd: fork() failed" msgstr "lpd: fork() bị lá»—i" #: src/common/lpd.c:1012 msgid "lpd: accept on listening socket failed" msgstr "lpd: lá»—i chấp nhận trên ổ cắm lắng nghe" #: src/common/lpd.c:1031 msgid "Start_all: pipe failed!" msgstr "Start_all: lá»—i ống dẫn." #: src/common/lpd_control.c:87 #, c-format msgid "bad control command '%s'" msgstr "lệnh Ä‘iá»u khiển sai « %s »" #: src/common/lpd_control.c:102 #, c-format msgid "printer '%s' has illegal char at '%s' in name" msgstr "máy in « %s » có ký tá»± cấm ở « %s » trong tên" #: src/common/lpd_control.c:114 #, c-format msgid "%s: unknown control request '%s'" msgstr "%s: yêu cầu Ä‘iá»u khiển không rõ « %s »" #: src/common/lpd_control.c:195 msgid "Use: move printer (user|jobid)* target" msgstr "" "Hãy dùng: move máy_in (ND|MC)* đích\n" "\n" "[ND\t\tngưá»i dùng\n" "MC\t\tmã nhận diện công việc]" #: src/common/lpd_control.c:206 msgid "no permission to control server" msgstr "không có quyển Ä‘iá»u khiển trình phục vụ" #: src/common/lpd_control.c:460 msgid "not implemented yet" msgstr "chưa được thá»±c hiện" #: src/common/lpd_control.c:486 #, c-format msgid "server process PID %ld exited\n" msgstr "tiến trình phục vụ PID %ld đã thoát\n" #: src/common/lpd_control.c:489 #, c-format msgid "kill server process PID %ld with %s\n" msgstr "buá»™c kết thúc tiến trình phục vụ PID %ld bằng %s\n" #: src/common/lpd_control.c:497 msgid "enabled and started" msgstr "đã bật và khởi chạy" #: src/common/lpd_control.c:498 msgid "disabled and stopped" msgstr "bị tắt và dừng chạy" #: src/common/lpd_control.c:499 msgid "stopped" msgstr "bị dừng chạy" #: src/common/lpd_control.c:501 msgid "started" msgstr "đã khởi chạy" #: src/common/lpd_control.c:502 msgid "disabled" msgstr "tắt" #: src/common/lpd_control.c:503 msgid "enabled" msgstr "bật" #: src/common/lpd_control.c:504 msgid "redirected" msgstr "bị chuyển hướng" #: src/common/lpd_control.c:505 msgid "holdall on" msgstr "giữ lại tất cả đã bật" #: src/common/lpd_control.c:506 msgid "holdall off" msgstr "giữ lại tất cả bị tắt" #: src/common/lpd_control.c:507 msgid "move done" msgstr "đã di chuyển" #: src/common/lpd_control.c:508 msgid "class updated" msgstr "hạng đã được cập nhật" #: src/common/lpd_control.c:509 msgid "killed job" msgstr "công việc bị giết" #: src/common/lpd_control.c:510 msgid "aborted job" msgstr "công việc bị há»§y bá»" #: src/common/lpd_control.c:511 msgid "flushed status" msgstr "trạng thái bị xoá sạch" #: src/common/lpd_control.c:531 #, c-format msgid "" "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n" msgstr "" "CẢNH BÃO : trình phục vụ cán cân trá»ng tải chính có thể\n" "đã thoát trước khi nó có thể nhận thông tin vá» công việc má»›i.\n" "Hãy dùng lệnh « lpc start %s » để khởi chạy lại trình phục vụ.\n" #: src/common/lpd_control.c:565 #, c-format msgid "Do_queue_control: write to fd '%d' failed" msgstr "Do_queue_control: lá»—i ghi vào fd '%d'" #: src/common/lpd_control.c:654 #, c-format msgid "%s: no permission '%s'\n" msgstr "%s: không có quyá»n hạn « %s »\n" #: src/common/lpd_control.c:738 #, c-format msgid "%s: selected '%s'\n" msgstr "%s: đã chá»n « %s »\n" #: src/common/lpd_control.c:748 #, c-format msgid "%s: cannot set hold file '%s'\n" msgstr "%s: không thể đặt tập tin giữ lại %s\n" #: src/common/lpd_control.c:855 msgid " holdall" msgstr " giữ lại tất cả" #: src/common/lpd_control.c:859 #, c-format msgid " class=%s" msgstr " hạng=%s" #: src/common/lpd_control.c:863 msgid " autohold" msgstr " tá»± động giữ lại" #: src/common/lpd_control.c:935 src/common/lpd_control.c:990 #: src/common/lpd_control.c:1045 #, c-format msgid "wrong number arguments, %d" msgstr "số đối số không đúng, %d" #: src/common/lpd_control.c:941 #, c-format msgid "forwarding to '%s'\n" msgstr "Ä‘ang chuyển tiếp tá»›i « %s »\n" #: src/common/lpd_control.c:943 msgid "forwarding off\n" msgstr "chuyển tiếp bị tắt\n" #: src/common/lpd_control.c:997 #, c-format msgid "classes printed '%s'\n" msgstr "hạng đã in « %s »\n" #: src/common/lpd_control.c:1000 msgid "all classes printed\n" msgstr "má»i hạng đã in\n" #: src/common/lpd_control.c:1051 #, c-format msgid "debugging override set to '%s'" msgstr "quyá»n cao hÆ¡n gỡ lá»—i được đăt thành « %s »" #: src/common/lpd_control.c:1053 msgid "debugging override off" msgstr "quyá»n cao hÆ¡n gỡ lá»—i bị tắt" #: src/common/lpd_jobs.c:435 #, c-format msgid "Do_queue_jobs: cannot open lockfile '%s'" msgstr "Do_queue_jobs: không thể mở tập tin khoá « %s »" #: src/common/lpd_jobs.c:767 src/common/lpd_jobs.c:787 #: src/common/lpd_jobs.c:2360 #, c-format msgid "cannot update job ticket file for '%s'" msgstr "không thể cập nhật tập tin vé công việc cho « %s »" #: src/common/lpd_jobs.c:770 src/common/lpd_jobs.c:790 #, c-format msgid "Do_queue_jobs: cannot update job ticket file for '%s'" msgstr "Do_queue_jobs: không thể cập nhật tập tin vé công việc cho « %s »" #: src/common/lpd_jobs.c:774 src/common/lpd_jobs.c:794 #, c-format msgid "removing job '%s' - no permissions" msgstr "Ä‘ang gỡ bá» công việc « %s » — không có quyá»n" #: src/common/lpd_jobs.c:1063 #, c-format msgid "Do_queue_jobs: LOGIC ERROR - no identifer '%s'" msgstr "Do_queue_jobs: Lá»–I HỢP Là — không có bá»™ nhận diện cho « %s »" #: src/common/lpd_jobs.c:1072 #, c-format msgid "Do_queue_jobs: FORWARDING LOOP - '%s'" msgstr "Do_queue_jobs: VÃ’NG LẶP CHUYỂN TIẾP — « %s »" #: src/common/lpd_jobs.c:1096 #, c-format msgid "cannot update job ticket file '%s'" msgstr "không thể cập nhật tập tin vé công việc « %s »" #: src/common/lpd_jobs.c:1098 #, c-format msgid "Do_queue_jobs: cannot update job ticket file '%s'" msgstr "Do_queue_jobs: không thể cập nhật tập tin vé công việc « %s »" #: src/common/lpd_jobs.c:1147 #, c-format msgid "Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d" msgstr "Do_queue_jobs: Lá»–I HỢP LÃ. new_dest và use_subserver == %d" #: src/common/lpd_jobs.c:1163 src/common/lpd_jobs.c:1227 msgid "sleeping, waiting for processes to exit" msgstr "Ä‘ang ngá»§, đợi các tiến trình thoát" #: src/common/lpd_jobs.c:1204 #, c-format msgid "Do_queue_jobs: write to fd '%d' failed" msgstr "Do_queue_jobs: lá»—i ghi vào fd « %d »" #: src/common/lpd_jobs.c:1403 #, c-format msgid "Remote_job: %d datafiles and only allowed %d" msgstr "Remote_job: có %d tập tin dữ liệu còn chỉ cho phép %d" #: src/common/lpd_jobs.c:1447 #, c-format msgid "link failure while sending job '%s'" msgstr "lá»—i liên kết trong khi gá»­i công việc « %s »" #: src/common/lpd_jobs.c:1453 #, c-format msgid "no permission to spool job '%s'" msgstr "không có quyá»n để cuá»™n công việc « %s » vào ống" #: src/common/lpd_jobs.c:1459 #, c-format msgid "failed to send job '%s'" msgstr "lá»—i gá»­i công việc « %s »" #: src/common/lpd_jobs.c:1627 msgid "Fork_subserver: fork failed" msgstr "Fork_subserver: fork bị lá»—i" #: src/common/lpd_jobs.c:1701 #, c-format msgid "subserver pid %ld exit status '%s'" msgstr "trình phục vụ phụ PID %ld trạng thái thoát « %s »" #: src/common/lpd_jobs.c:1705 #, c-format msgid "subserver pid %ld died with signal '%s'" msgstr "trình phục vụ phụ PID %ld đã chết vá»›i tín hiệu « %s »" #: src/common/lpd_jobs.c:1751 msgid "Wait_for_subserver: Mergesort failed" msgstr "Wait_for_subserver: Mergesort bị lá»—i" #: src/common/lpd_jobs.c:1762 #, c-format msgid "Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed" msgstr "Wait_for_subserver: Lá»–I HỢP LÃ. Lá»—i đợi PID %d" #: src/common/lpd_jobs.c:1787 msgid "succ" msgstr "tcông" #: src/common/lpd_jobs.c:1788 msgid "jsucc" msgstr "cvtcông" #: src/common/lpd_jobs.c:1789 msgid "success" msgstr "thành công" #: src/common/lpd_jobs.c:1790 msgid "jsuccess" msgstr "công việc thành công" #: src/common/lpd_jobs.c:1791 msgid "abort" msgstr "há»§y bá»" #: src/common/lpd_jobs.c:1792 msgid "jabort" msgstr "há»§y bá» công việc" #: src/common/lpd_jobs.c:1793 msgid "hold" msgstr "giữ lại" #: src/common/lpd_jobs.c:1794 msgid "jhold" msgstr "giữ lại công việc" #: src/common/lpd_jobs.c:1795 msgid "remove" msgstr "gỡ bá»" #: src/common/lpd_jobs.c:1796 msgid "jremove" msgstr "gỡ bá» công việc" #: src/common/lpd_jobs.c:1975 #, c-format msgid "Update_status: no identifier for '%s'" msgstr "Update_status: không có bá»™ nhận diện cho « %s »" #: src/common/lpd_jobs.c:2008 src/common/lpd_jobs.c:2115 #: src/common/lpd_jobs.c:2157 src/common/lpd_jobs.c:2201 #, c-format msgid "job '%s' saved" msgstr "công việc « %s » đã được lưu" #: src/common/lpd_jobs.c:2013 src/common/lpd_jobs.c:2121 #: src/common/lpd_jobs.c:2163 src/common/lpd_jobs.c:2207 #, c-format msgid "could not remove job '%s'" msgstr "không thể gỡ bá» công việc « %s »" #: src/common/lpd_jobs.c:2015 src/common/lpd_jobs.c:2123 #: src/common/lpd_jobs.c:2165 src/common/lpd_jobs.c:2209 #, c-format msgid "job '%s' removed" msgstr "công việc « %s » bị gỡ bá»" #: src/common/lpd_jobs.c:2045 #, c-format msgid "job '%s', attempt %d, allowed %d" msgstr "công việc « %s », lần thá»­ %d, cho phép %d" #: src/common/lpd_jobs.c:2049 msgid "treating as successful" msgstr "Ä‘ang xá»­ lý như thành công." #: src/common/lpd_jobs.c:2050 msgid "retrying job" msgstr "Ä‘ang thá»­ lại công việc" #: src/common/lpd_jobs.c:2051 msgid "no retry" msgstr "không thá»­ lại" #: src/common/lpd_jobs.c:2052 msgid "aborting server" msgstr "Ä‘ang há»§y bá» trình phục vụ" #: src/common/lpd_jobs.c:2053 msgid "removing job - status JREMOVE" msgstr "Ä‘ang gỡ bá» công việc — trạng thái JREMOVE" #: src/common/lpd_jobs.c:2054 msgid "holding job" msgstr "Ä‘ang giữ lại công việc" #: src/common/lpd_jobs.c:2057 #, c-format msgid "unexpected status 0x%x" msgstr "trạng thái bất thưá»ng 0x%x" #: src/common/lpd_jobs.c:2062 #, c-format msgid "job '%s', %s" msgstr "công việc « %s », %s" #: src/common/lpd_jobs.c:2066 #, c-format msgid "job '%s' attempt %d, trying %d times" msgstr "công việc « %s », lần thá»­ %d, sẽ thá»­ %d lần" #: src/common/lpd_jobs.c:2069 #, c-format msgid "job '%s' attempt %d, trying indefinitely" msgstr "công việc « %s », lần thá»­ %d, sẽ thá»­ vô hạn" #: src/common/lpd_jobs.c:2088 msgid "failed, no retry" msgstr "không thành công, không thá»­ lại" #: src/common/lpd_jobs.c:2119 #, c-format msgid "removing job '%s' - JFAILNORETRY" msgstr "Ä‘ang gỡ bá» công việc « %s » — JFAILNORETRY" #: src/common/lpd_jobs.c:2131 msgid "aborting operations" msgstr "Ä‘ang há»§y bá» các thao tác" #: src/common/lpd_jobs.c:2161 #, c-format msgid "removing job '%s' - JABORT" msgstr "Ä‘ang gỡ bá» công việc « %s » — JABORT" #: src/common/lpd_jobs.c:2170 msgid "stopping printing on filter JABORT exit code" msgstr "đã dừng in do lá»c mã thoát JABORT" #: src/common/lpd_jobs.c:2180 msgid "removing destination due to errors" msgstr "Ä‘ang gỡ bỠđích do lá»—i" #: src/common/lpd_jobs.c:2191 msgid "too many errors" msgstr "quá nhiá»u lá»—i" #: src/common/lpd_jobs.c:2205 #, c-format msgid "removing job '%s' - JREMOVE" msgstr "Ä‘ang gỡ bá» công việc « %s » — JREMOVE" #: src/common/lpd_jobs.c:2334 #, c-format msgid "Service_worker: cannot open lockfile '%s'" msgstr "Service_worker: không thể mở tập tin khoá « %s »" #: src/common/lpd_jobs.c:2363 #, c-format msgid "Service_worker: cannot update job ticket file for '%s'" msgstr "Service_worker: không thể cập nhật tập tin vé công việc cho « %s »" #: src/common/lpd_jobs.c:2371 #, c-format msgid "Service_worker: no identifier for '%s'" msgstr "Service_worker: không có bá»™ nhận diện cho « %s »" #: src/common/lpd_jobs.c:2757 #, c-format msgid "job '%s' removed- status expired" msgstr "công việc « %s » bị gỡ bỠ— trạng thái đã hết hạn" #: src/common/lpd_rcvjob.c:139 src/common/lpd_rcvjob.c:559 msgid "bad command line" msgstr "dòng lệnh sai" #: src/common/lpd_rcvjob.c:143 src/common/lpd_rcvjob.c:563 msgid "bad printer name" msgstr "tên máy in sai" #: src/common/lpd_rcvjob.c:151 #, c-format msgid "%s: cannot set up print queue" msgstr "%s: không thể thiết lập hàng đợi in" #: src/common/lpd_rcvjob.c:187 src/common/lpd_rcvjob.c:602 #: src/common/lpd_secure.c:188 #, c-format msgid "%s: spooling disabled" msgstr "%s: khả năng cuá»™n vào ống bị tắt" #: src/common/lpd_rcvjob.c:198 #, c-format msgid "%s: Receive_job: sending ACK 0 failed" msgstr "%s: Receive_job: lá»—i gá»­i ACK 0" #: src/common/lpd_rcvjob.c:210 #, c-format msgid "Receive_job: cannot open lockfile '%s'" msgstr "Receive_job: không thể mở tập tin khoá « %s »" #: src/common/lpd_rcvjob.c:215 #, c-format msgid "Receive_job: cannot lock lockfile '%s'" msgstr "Receive_job: không thể khoá tập tin khoá « %s »" #: src/common/lpd_rcvjob.c:254 msgid "Recovering from incorrect job submission" msgstr "Äang phục hồi sau khi gá»­i sai công việc" #: src/common/lpd_rcvjob.c:268 #, c-format msgid "%s: Receive_job - bad control line '%s', len %0.0f, name '%s'" msgstr "%s: Receive_job — dòng Ä‘iá»u khiển sai « %s », độ dài %0.0f, tên « %s »" #: src/common/lpd_rcvjob.c:289 src/common/lpd_rcvjob.c:366 #: src/common/lpd_rcvjob.c:403 src/common/lpd_rcvjob.c:454 #: src/common/lpd_rcvjob.c:617 src/common/lpd_rcvjob.c:799 #: src/common/lpd_rcvjob.c:846 src/common/lpd_rcvjob.c:881 #: src/common/lpd_rcvjob.c:917 #, c-format msgid "size %0.3fK exceeds %dK" msgstr "kích cỡ %0.3fK lá»›n hÆ¡n %dK" #: src/common/lpd_rcvjob.c:296 src/common/lpd_rcvjob.c:624 #: src/common/lpd_secure.c:202 #, c-format msgid "%s: insufficient file space" msgstr "%s: không đủ chá»— tập tin" #: src/common/lpd_rcvjob.c:311 src/common/lpd_rcvjob.c:676 #, c-format msgid "%s: sending ACK 0 for '%s' failed" msgstr "%s: lá»—i gá»­i ACK 0 cho « %s »" #: src/common/lpd_rcvjob.c:345 src/common/lpd_rcvjob.c:649 #, c-format msgid "%s: transfer of '%s' from '%s' failed" msgstr "%s: lá»—i truyá»n « %s » từ « %s »" #: src/common/lpd_rcvjob.c:375 src/common/lpd_rcvjob.c:412 #: src/common/lpd_rcvjob.c:463 src/common/lpd_rcvjob.c:854 #: src/common/lpd_rcvjob.c:890 src/common/lpd_rcvjob.c:926 #: src/common/lpd_rcvjob.c:1337 src/common/lpd_rcvjob.c:1413 #, c-format msgid "Error setting up job ticket file - %s" msgstr "Gặp lá»—i khi thiết lập tập tin vé công việc — %s" #: src/common/lpd_rcvjob.c:505 #, c-format msgid "Receive_jobs: write to fd '%d' failed" msgstr "Receive_jobs: lá»—i ghi vào fd « %d »" #: src/common/lpd_rcvjob.c:570 #, c-format msgid "%s: cannot set up printer" msgstr "%s: không thể thiết lập máy in" #: src/common/lpd_rcvjob.c:638 #, c-format msgid "%s: Receive_block_job: sending ACK 0 failed" msgstr "%s: Receive_block_job: lá»—i gá»­i ACK 0" #: src/common/lpd_rcvjob.c:659 #, c-format msgid "Receive_block_job: lseek failed '%s'" msgstr "Receive_block_job: lseek bị lá»—i « %s »" #: src/common/lpd_rcvjob.c:706 #, c-format msgid "Receive_block_jobs: write to fd '%d' failed" msgstr "Receive_block_jobs: lá»—i ghi vào fd « %d »" #: src/common/lpd_rcvjob.c:772 src/common/lpd_rcvjob.c:831 #, c-format msgid "Scan_block_file: lseek failed '%s'" msgstr "Scan_block_file: lseek bị lá»—i « %s »" #: src/common/lpd_rcvjob.c:787 #, c-format msgid "bad length information '%s'" msgstr "thông tin độ dài sai « %s »" #: src/common/lpd_rcvjob.c:819 #, c-format msgid "Scan_block_file: read failed '%s'" msgstr "Scan_block_file: lá»—i Ä‘á»c « %s »" #: src/common/lpd_rcvjob.c:824 msgid "Scan_block_file: read unexecpted EOF" msgstr "Scan_block_file: Ä‘á»c kết thúc tập tin không ngoài lệ" #: src/common/lpd_rcvjob.c:1017 #, c-format msgid "%s: no permission to print" msgstr "%s: không có quyá»n in" #: src/common/lpd_rcvjob.c:1500 src/common/lpd_rcvjob.c:1525 #, c-format msgid "Do_incoming_control_filter: lseek failed '%s'" msgstr "Do_incoming_control_filter: lseek bị lá»—i « %s »" #: src/common/lpd_rcvjob.c:1613 #, c-format msgid "Get_route: lseek failed '%s'" msgstr "Get_route: lseek bị lá»—i « %s »" #: src/common/lpd_remove.c:73 msgid "missing user or printer name" msgstr "thiếu ngưá»i dùng hay tên máy in" #: src/common/lpd_remove.c:81 src/common/lpd_status.c:175 #, c-format msgid "printer '%s' has illegal character at '%s' in name" msgstr "máy in « %s » có tên chứa ký tá»± cấm ở « %s »" #: src/common/lpd_remove.c:110 #, c-format msgid "Job_remove: error '%s'" msgstr "Job_remove: lá»—i « %s »" #: src/common/lpd_remove.c:203 #, c-format msgid "Printer %s@%s:\n" msgstr "Máy in %s@%s:\n" #: src/common/lpd_remove.c:232 #, c-format msgid " checking perms '%s'\n" msgstr " Ä‘ang kiểm tra quyá»n hạn « %s »\n" #: src/common/lpd_remove.c:249 #, c-format msgid " no permissions '%s'\n" msgstr " không có quyá»n « %s »\n" #: src/common/lpd_remove.c:263 #, fuzzy, c-format msgid " removing incoming job '%s'\n" msgstr "Ä‘ang gỡ bá» công việc « %s » — JABORT" #: src/common/lpd_remove.c:266 #, c-format msgid " dequeued '%s'\n" msgstr " đã gỡ bỠ« %s » khá»i hàng đợi\n" #: src/common/lpd_remove.c:275 #, c-format msgid "error: could not remove '%s'" msgstr "lá»—i: không thể gỡ bỠ« %s »" #: src/common/lpd_remove.c:384 msgid " ERROR: " msgstr " Lá»–I: " #: src/common/lpd_secure.c:81 #, c-format msgid "bad command line '%s'" msgstr "dòng lệnh sai « %s »" #: src/common/lpd_secure.c:113 #, c-format msgid "bad printer name '%s'" msgstr "tên máy in sai « %s »" #: src/common/lpd_secure.c:124 #, c-format msgid "bad printer '%s'" msgstr "máy in sai « %s »" #: src/common/lpd_secure.c:166 #, c-format msgid "unsupported authentication '%s'" msgstr "xác thá»±c không được há»— trợ « %s »" #: src/common/lpd_secure.c:173 #, c-format msgid "no receive method supported for '%s'" msgstr "không có phương pháp nhận được há»— trợ cho « %s »" #: src/common/lpd_secure.c:195 #, c-format msgid "%s: job size %0.0f is larger than %d K" msgstr "%s: kích cỡ công việc %0.0f lá»›n hÆ¡n %d K" #: src/common/lpd_status.c:357 #, c-format msgid "%s: no permission to show status" msgstr "%s: không có quyá»n hiển thị trạng thái" #: src/common/lpd_status.c:476 #, c-format msgid " (originally %s)" msgstr " (gốc %s)" #: src/common/lpd_status.c:486 msgid "" "\n" " Error: " msgstr "" "\n" " Lá»—i: " #: src/common/lpd_status.c:491 #, c-format msgid " - %s" msgstr " - %s" #: src/common/lpd_status.c:494 #, c-format msgid " - printer %s@%s not in printcap" msgstr " - máy in %s@%s không phải trong printcap" #: src/common/lpd_status.c:498 #, c-format msgid " - printer %s@%s has bad printcap entry" msgstr " - máy in %s@%s có mục nhập printcap sai" #: src/common/lpd_status.c:724 #, c-format msgid " " msgstr " " #: src/common/lpd_status.c:736 #, c-format msgid " Job: %s" msgstr " Công việc: %s" #: src/common/lpd_status.c:737 #, c-format msgid "%s status= %s" msgstr "%s trạng thái= %s" #: src/common/lpd_status.c:740 #, c-format msgid "%s size= %0.0f" msgstr "%s kích cỡ= %0.0f" #: src/common/lpd_status.c:743 #, c-format msgid "%s time= %s" msgstr "%s giá»= %s" #: src/common/lpd_status.c:747 #, c-format msgid "%s error= %s" msgstr "%s lá»—i= %s" #: src/common/lpd_status.c:752 #, c-format msgid "%s CONTROL=" msgstr "%s ÄIỀU_KHIỂN=" #: src/common/lpd_status.c:758 #, c-format msgid "%s HOLDFILE=" msgstr "%s TẬP_TIN_GIá»®_LẠI=" #: src/common/lpd_status.c:778 #, fuzzy, c-format msgid " %d job" msgid_plural " %d jobs" msgstr[0] " %d công việc" #: src/common/lpd_status.c:782 #, c-format msgid " (%d held)" msgstr " (%d đã giữ lại)" #: src/common/lpd_status.c:787 #, c-format msgid " (%d move)" msgstr " (%d di chuyển)" #: src/common/lpd_status.c:810 #, c-format msgid " Comment: %s" msgstr " Ghi chú : %s" #: src/common/lpd_status.c:821 #, c-format msgid "" "\n" " Printing: %s\n" " Aborted: %s\n" " Spooling: %s" msgstr "" "\n" " Äang in: %s\n" " Äã há»§y bá» : %s\n" " Äang cuá»™n vào ống: %s" # Variable: don't translate / Biến: đừng dịch #: src/common/lpd_status.c:867 #, c-format msgid "" "\n" " %s: " msgstr "" "\n" " %s: " #: src/common/lpd_status.c:875 #, c-format msgid " (%s" msgstr " (%s" #: src/common/lpd_status.c:890 #, c-format msgid "" "\n" " Redirected_to: %s" msgstr "" "\n" " Äã_chuyển_hướng_đến: %s" #: src/common/lpd_status.c:893 #, c-format msgid " (redirect %s)" msgstr " (chuyển hướng %s)" #: src/common/lpd_status.c:903 #, c-format msgid " (dest %s@%s)" msgstr " (đích %s@%s)" #: src/common/lpd_status.c:910 #, c-format msgid "" "\n" " Serving: %s" msgstr "" "\n" " Äang phục vụ : %s" #: src/common/lpd_status.c:913 #, c-format msgid " (serving %s)" msgstr " (Ä‘ang phục vụ %s)" #: src/common/lpd_status.c:920 #, c-format msgid "" "\n" " Classes: %s" msgstr "" "\n" " Hạng: %s" #: src/common/lpd_status.c:923 #, c-format msgid " (classes %s)" msgstr " (hạng %s)" #: src/common/lpd_status.c:930 msgid "" "\n" " Hold_all: on" msgstr "" "\n" " Hold_all: bật" #: src/common/lpd_status.c:933 msgid " (holdall)" msgstr " (giữ lại tất cả)" #: src/common/lpd_status.c:940 msgid "" "\n" " Auto_hold: on" msgstr "" "\n" " Auto_hold: on" #: src/common/lpd_status.c:943 msgid " (autohold)" msgstr " (tá»± động giữ lại)" #: src/common/lpd_status.c:951 #, c-format msgid "" "\n" " Message: %s" msgstr "" "\n" " Thông Ä‘iệp: %s" #: src/common/lpd_status.c:954 #, c-format msgid " (message: %s)" msgstr " (thông Ä‘iệp: %s)" #: src/common/lpd_status.c:983 msgid " Queue: no printable jobs in queue\n" msgstr " Hàng đợi: không có công việc có thể in\n" #: src/common/lpd_status.c:987 #, fuzzy, c-format msgid " Queue: %d printable job\n" msgid_plural " Queue: %d printable jobs\n" msgstr[0] " Hàng đợi: %d công việc có thể in\n" #: src/common/lpd_status.c:994 #, c-format msgid " Holding: %d held jobs in queue\n" msgstr " Giữ lại: %d công việc đã giữ lại trong hàng đợi\n" #: src/common/lpd_status.c:1000 msgid " Server: no server active" msgstr " Phục vụ : không có trình phục vụ chạy" #: src/common/lpd_status.c:1003 #, c-format msgid " Server: pid %d active" msgstr " Phục vụ : PID %d Ä‘ang chạy" #: src/common/lpd_status.c:1011 #, c-format msgid " Unspooler: pid %d active" msgstr " Bá»™ bá» cuá»™n: PID %d Ä‘ang chạy" #: src/common/lpd_status.c:1023 #, c-format msgid "%s SPOOLCONTROL=\n" msgstr "%s ÄIỀU KHIỂN á»NG CHỈ=\n" #: src/common/lpd_status.c:1037 msgid " Status: " msgstr " Trạng thái: " #: src/common/lpd_status.c:1041 msgid " Filter_status: " msgstr " Trạng_thái_lá»c: " #: src/common/lpd_dispatch.c:39 #, c-format msgid "Dispatch_input: bad request line '%s' from %s" msgstr "Dispatch_input: dòng yêu cầu sai « %s » từ « %s »" #: src/common/lpd_dispatch.c:177 msgid "Service_connection: getpeername failed" msgstr "Service_connection: getpeername (lấy tên ngang hàng) bị lá»—i" #: src/common/lpd_dispatch.c:224 msgid "Service_connection: BAD LocalHost_IP value" msgstr "Service_connection: giá trị LocalHost_IP SAI" #: src/common/lpd_dispatch.c:230 #, c-format msgid "Service_connection: bad protocol family '%d'" msgstr "Service_connection: há» giao thức sai « %d »" #: src/common/lpd_dispatch.c:261 msgid "no connect permissions" msgstr "không có quyá»n kết nối" #: src/common/lpd_dispatch.c:284 #, c-format msgid "Service_connection: peek of length %d failed" msgstr "Service_connection: hé nhìn có độ dài %d bị lá»—i" #: src/common/lpd_dispatch.c:326 #, c-format msgid "Service_connection: cannot read request from %s in %d seconds" msgstr "Service_connection: không thể Ä‘á»c yêu cầu từ %s trong %d giây" #: src/common/lpd_dispatch.c:330 #, c-format msgid "Service_connection: short request line '%s', from '%s'" msgstr "Service_connection: dòng yêu cầu ngắn « %s », từ « %s »" #: src/common/lpq.c:119 #, c-format msgid "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n" msgstr "" "cách sá»­ dụng: %s [-aAclV] [-Dcấp_gỡ_lá»—i] [-Pmáy_in [-tthá»i_gian_ngá»§]\n" "\n" " -A\t\t— dùng sá»± xác thá»±c xác định bởi biến môi trưá»ng AUTH\n" " -a\t\t— má»i máy in\n" " -c\t\t— xoá màn hình trước khi cập nhật\n" " -l\t\t— tăng độ dài cá»§a thông tin trạng thái chi tiết,\n" "\t\t\tcác cỠ« l » thêm nữa sẽ thêm chi tiết.\n" " -L\t\t— thông tin trạng thái có chi tiết tối Ä‘a\n" " -n Sá»\t— tổng Sá» dòng thông tin trạng thái chi tiết\n" " -Dcấp_gỡ_lá»—i\t— cấp gỡ lá»—i\n" " -Pmáy_in\t\t— xác định máy in\n" " -s\t\t— định dạng tóm tắt ngắn\n" " -tthá»i_gian_ngá»§\t— thá»i gian cần ngá»§ giữa hai lần cập nhật\n" " -V\t\t— in ra thông tin phiên bản\n" " -v\t\t— in ra theo định dạng « khoá: giá trị »\n" #: src/common/lpq.c:245 #, c-format msgid "Printer: %s is %s@%s\n" msgstr "Máy in: %s là %s@%s\n" #: src/common/lpq.c:252 #, c-format msgid "Printer: %s - cannot use printer, not in privileged group\n" msgstr "" "Máy in: %s — không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n\n" #: src/common/lpq.c:369 src/common/lpq.c:374 src/common/lpq.c:384 #: src/common/lpq.c:431 src/common/lpq.c:438 msgid "Printer:" msgstr "Máy in:" #: src/common/lpq.c:477 msgid "fork() failed" msgstr "fork() (tạo tiến trình con) không thành công." #: src/common/lpq.c:484 #, c-format msgid "Term_clear: waitpid(%d) failed" msgstr "Term_clear: waitpid(%d) bị lá»—i" #: src/common/lpq.c:510 msgid "lpq: please use the LPRng lpstat program\n" msgstr "lpq: hãy dùng chưng trình thống kê lpstat LPRng\n" #: src/common/lpstat.c:195 msgid "scheduler is running\n" msgstr "bá»™ lập lịch biểu Ä‘ang chạy\n" #: src/common/lpstat.c:199 msgid "no system default destination\n" msgstr "không có đích mặc định trên hệ thống\n" #: src/common/lpstat.c:201 #, c-format msgid "system default destination: %s\n" msgstr "đích mặc định trên hệ thống: %s\n" #: src/common/lpstat.c:208 #, c-format msgid "system for %s: %s\n" msgstr "hệ thống cho %s: %s\n" #: src/common/lpstat.c:250 #, c-format msgid " Printer: %s - cannot use printer, not in privileged group\n" msgstr "" " Máy in: %s — không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n\n" #: src/common/lpstat.c:259 #, c-format msgid " Printer: %s - direct connection to device '%s'\n" msgstr " Máy in: %s — kết nối trá»±c tiếp tá»›i thiết bị « %s »\n" #: src/common/lpstat.c:387 #, c-format msgid "" "%s not accepting requests since %s -\n" "\tunknown reason\n" msgstr "" "%s không chấp nhận yêu cầu kể từ %s -\n" "\tkhông biết sao\n" #: src/common/lpstat.c:389 #, c-format msgid "%s accepting requests since %s\n" msgstr "%s chấp nhận yêu cầu kể từ %s\n" #: src/common/lpstat.c:397 #, c-format msgid "printer %s unknown state. disabled since %s. available\n" msgstr "máy in %s tình trạng không rõ. tắt từ %s. sẵn sàng\n" #: src/common/lpstat.c:398 #, c-format msgid "printer %s unknown state. enabled since %s. available\n" msgstr "máy in %s tình trạng không rõ. bật từ %s. sẵn sàng\n" #: src/common/lpstat.c:404 #, c-format msgid "\tDescription: %s@%s\n" msgstr "\tMô tả: %s@%s\n" #: src/common/lpr.c:157 msgid "nothing to print" msgstr "không có gì để in" #: src/common/lpr.c:162 msgid "cannot use printer - not in privileged group\n" msgstr "không thể sá»­ dụng máy in vì không phải trong nhóm có quyá»n\n" #: src/common/lpr.c:168 #, c-format msgid "no remote support for %s@%s" msgstr "không có há»— trợ từ xa cho %s@%s" #: src/common/lpr.c:179 #, c-format msgid "%d data files and maximum allowed %d" msgstr "có %d tập tin dữ liệu còn cho phép số tối Ä‘a %d" #: src/common/lpr.c:221 src/common/lpr.c:1164 #, c-format msgid "Cannot open file '%s', %s" msgstr "Không thể mở tập tin « %s », %s" #: src/common/lpr.c:232 msgid "(lpr_filter)" msgstr "(lá»c_lpr)" #: src/common/lpr.c:295 src/common/lpr.c:332 #, c-format msgid "Status Information, attempt %d:\n" msgstr "Thông tin trạng thái, lần thá»­ %d:\n" #: src/common/lpr.c:299 src/common/lpr.c:336 #, c-format msgid " of %d:\n" msgstr " trên %d:\n" #: src/common/lpr.c:312 #, c-format msgid "Waiting %d seconds before retry\n" msgstr "Äang đợi %d giây trước khi thá»­ lại\n" #: src/common/lpr.c:351 #, c-format msgid "request id is %s\n" msgstr "mã nhận diện yêu cầu là %s\n" #: src/common/lpr.c:354 #, c-format msgid "request id is %d\n" msgstr "mã nhận diện yêu cầu là %d\n" #: src/common/lpr.c:366 #, c-format msgid "Error unlinking '%s' - %s" msgstr "Gặp lá»—i khi há»§y liên kết « %s » — %s" #: src/common/lpr.c:374 #, c-format msgid "Done %d\n" msgstr "Hoàn tất %d\n" #: src/common/lpr.c:430 src/common/lpr.c:603 msgid "USER environment variable undefined" msgstr "chưa xác định biến môi trưá»ng ngưá»i dùng USER" #: src/common/lpr.c:448 msgid "-ncopies -number of copies must be greater than 0\n" msgstr "-ncopies — tổng số bản sao phải ≥0\n" #: src/common/lpr.c:452 msgid "nobanner" msgstr "không băng cá»" #: src/common/lpr.c:455 msgid "width" msgstr "độ rá»™ng" #: src/common/lpr.c:530 #, c-format msgid "bad -F format string '%s'\n" msgstr "gặp chuá»—i định dạng -F sai %s\n" #: src/common/lpr.c:533 #, c-format msgid "duplicate format specification -F%s\n" msgstr "đặc tả định dạng trùng -F%s\n" #: src/common/lpr.c:545 msgid "-Kcopies -number of copies must be greater than 0\n" msgstr "-Kcopies — tổng số bản sao phải ≥0\n" #: src/common/lpr.c:608 msgid "Missing mail name" msgstr "Thiếu tên thư" #: src/common/lpr.c:622 #, c-format msgid "duplicate format specification -%c\n" msgstr "đặc tả định dạng trùng — %c\n" #: src/common/lpr.c:666 #, c-format msgid "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default " "printer.\n" msgstr "" "Cách sá»­ dụng: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d máy_in@[máy]]\n" " [-f tên_dạng] [-H quản_lý_đặc_biệt]\n" " [-n số] [-o tùy_chá»n] [-P danh_sách_trang]\n" " [-q cấp_ưu_tiên] [-S bá»™_ký_tá»±]\n" " [-S bánh_xe_in] [-t tá»±a]\n" " [-T kiểu_ná»™i_dung [-r]] [-y danh_sách_chế_độ]\n" " [-Dtùy_chá»n_gỡ_lá»—i ] [ các_tên_tập_tin ... ]\n" "\n" " Mô phá»ng lp dùng LPRng, chức năng có thể khác biệt má»™t ít\n" "\n" " -A\t\t\t— dùng sá»± xác thá»±c ghi rõ bởi biến môi trưá»ng AUTH\n" " -B\t\t\t— lá»c các tập tin và giảm công việc thành tập tin riêng lẻ\n" "\t\t\t\ttrước khi gá»­i\n" " -c\t\t\t— (tạo bản sao trước khi in — bị bá» qua)\n" " -d máy_in[@máy]\t\t— máy in trên máy\n" " -D cá»_gỡ_lá»—i\t\t\t— các cá» gỡ lá»—i\n" " -f tên_dạng\t\t— chữ đầu dùng làm định dạng công việc\n" " -G\t\t\t— lá»c tập tin công việc riêng trước khi gá»­i\n" " -H quản_lý\t— (được gá»­i như « -Z quản_lý »\n" " -m\t\t\t— thư được gá»­i cho ngưá»i dùng $USER khi in xong\n" " -n Sá»\t\t— tổng số bản sao\n" " -o tùy_chá»n\t— nhận ra nobanner (không băng cá») và width (độ rá»™ng),\n" " (các tùy chá»n khác được gá»­i như « -Z tùy chá»n »)\n" " -P danh_sách_trang\t— (in danh sách trang — bị bá» qua)\n" " -p\t\t\t— (thông báo khi in xong — bị bá» qua)\n" " -q\t\t\t— độ ưu tiên: 0 -> Z (cao nhất), 25 -> A (thấp nhất)\n" " -s\t\t\t— (thu hồi các thông Ä‘iệp — bị bá» qua)\n" " -S bá»™_ký_tá»±\t— (được gá»­i như « -Z bá»™_ký_tá»± »)\n" " -t tá»±a\t\t— tá»±a cá»§a công việc\n" " -T ná»™i_dung\t— (được gá»­i như « -Z ná»™i_dung »)\n" " -w\t\t\t— (ghi thông Ä‘iệp khi in xong — bị bá» qua)\n" " -X đưá»ng_dẫn\t— bá»™ lá»c tá»± ghi ra cho các tập tin công việc\n" " -Y\t\t\t— kết nối và gá»­i tá»›i cổng TCP/IP (chế độ trá»±c tiếp)\n" " -y chế_độ\t— (được gá»­i như « -Z chế_độ »)\n" " --\t\t\t— kết thúc các tùy chá»n, các tập tin theo sau\n" " tên tập tin « - » thì Ä‘á»c từ thiết bị nhâp chuẩn STDIN\n" " Các biến môi trưá»ng PRINTER, LPDEST, NGPRINTER, NPRINTER đặt máy in mặc " "định.\n" #: src/common/lpr.c:702 #, c-format msgid "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default " "printer.\n" msgstr "" "Usage: %s [-Pmáy_in[@máy]] [-A] [-B] [-Chạng] [-Fđịnh_dạng] [-G] [-" "Jthông_tin]\n" " [-(K|#)số_bản_sao] [-Q] [-Rtên_tài_khoản] [-Ttá»±a] [-Ungưá»i_dùng[@máy]] " "[-V]\n" " [-Ztùy_chá»n] [-b] [-m địa_chỉ_thư] [-h] [-i thụt_lá»] [-l] [-w rá»™ng ] [-" "r]\n" " [-Dtùy_chá»n_gỡ_lá»—i ] [--] [ tên_tập_tin ... ]\n" "\n" " -A\t\t\t— dùng sá»± xác thá»±c ghi rõ bởi biến môi trưá»ng AUTH\n" " -B\t\t\t— lá»c các tập tin và giảm công việc thành tập tin riêng lẻ\n" "\t\t\t\ttrước khi gá»­i\n" " -C class - job class\n" " -D tùy_chá»n_gỡ_lá»—i\t— các cá» gỡ lá»—i\n" " -F định_dạng\t\t\t— định dạng công việc\n" " -b,-l\t\t— định dạng nhị phân hay nghÄ©a chữ\n" " c,d,f,g,l,m,p,t,v cÅ©ng là tùy chá»n định dạng\n" " -G\t\t\t— lá»c tập tin công việc riêng trước khi gá»­i\n" " -J thông_tin\t— thông tin vá» băng cá» và công việc\n" " -K Sá»\t\t— tổng số bản sao\n" " -P máy_in[@máy]\t\t— máy in trên máy\n" " -Q\t\t\t— chèn « queuename » (tên hàng đợi) vào tập tin Ä‘iá»u khiển\n" " -Rtên_tài_khoản\t\t— thông tin kế toán\n" " -T tá»±a\t\t— tá»±a đỠcho định dạng « pr » (-p)\n" " -U tên_ngưá»i_dùng\t— có quyá»n cao hÆ¡n tên ngưá»i dùng (bị hạn chế)\n" " -V\t\t\t— xuất thông tin chi tiết trong khi cuá»™n vào ống\n" " -X đưá»ng_dẫn\t\t— bá»™ lá»c tá»± ghi rõ cho tập tin công việc\n" " -Y\t\t\t— kết nối và gá»­i tá»›i cổng TCP/IP (chế độ trá»±c tiếp)\n" " -Z tùy_chá»n\t— các tùy chá»n cần gá»­i cho bá»™ lá»c\n" " -h\t\t\t— không có phần đầu hay trang băng cá»\n" " -i thụt_lá»\t— sá»± thụt lá»\n" " -k\t\t\t— không dùng tập tin tạm thá»i khi gá»­i cho trình phục vụ\n" " -m địa_chỉ_thư\t\t— gá»­i thư chứa trạng thái cuối cùng cho địa chỉ này\n" " -r\t\t\t— gỡ bá» các tập tin sau khi cuá»™n vào ống\n" " -w rá»™ng\t\t— độ rá»™ng cần dùng\n" " --\t\t\t— kết thúc các tùy chá»n, các tập tin theo sau\n" " tên tập tin « - » thì Ä‘á»c từ thiết bị nhâp chuẩn STDIN\n" " Các biến môi trưá»ng PRINTER, LPDEST, NGPRINTER, NPRINTER đặt máy in mặc " "định.\n" #: src/common/lpr.c:803 msgid "Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)" msgstr "" "Äá»™ ưu tiên (chữ đầu cá»§a Hạng) không phải « A » (thấp nhất) đến « Z » (cao nhất)" #: src/common/lpr.c:827 src/common/lpr.c:832 msgid "(STDIN)" msgstr "(STDIN)" #: src/common/lpr.c:881 msgid "-U (username) can only be used by ROOT" msgstr "-U (tên ngưá»i dùng) chỉ có thể được dùng bởi ngưá»i chá»§ (root)" #: src/common/lpr.c:897 #, c-format msgid "Get_local_host: '%s' FQDN name not found!" msgstr "" "Get_local_host: không tìm thấy tên miá»n có khả năng đầy đủ (FQDN) « %s »." #: src/common/lpr.c:924 #, c-format msgid "Bad format specification '%c'" msgstr "Äặc tả định dạng sai « %c »" #: src/common/lpr.c:931 #, c-format msgid "Sorry, can only print %d files at a time, split job up" msgstr "Tiếc là chỉ có thể in ra %d tập tin đồng thá»i nên chia công việc ra" #: src/common/lpr.c:937 #, c-format msgid "Maximum of %d copies allowed" msgstr "Cho phép %d bản sao tối Ä‘a" #: src/common/lpr.c:1001 msgid "authentication conficts with -k option" msgstr "xác thá»±c xung đột vá»›i tùy chá»n « -k »" #: src/common/lpr.c:1004 msgid "send_block_format configuration option conficts with -k option" msgstr "" "tùy chá»n cấu hình « send_block_format » (gá»­i định dạng khối) cung đột vá»›i tùy " "chá»n « -k »" #: src/common/lpr.c:1007 msgid "send_data_first configuration option conficts with -k option" msgstr "" "tùy chá»n cấu hình « send_data_first » (gá»­i dữ liệu trước) cung đột vá»›i tùy " "chá»n « -k »" #: src/common/lpr.c:1010 msgid "multiple copies conficts with -k option" msgstr "nhiá»u bản sao xung đột vá»›i tùy chá»n « -k »" #: src/common/lpr.c:1013 msgid "files on command line conflicts with -k option" msgstr "tập tin trên dòng lệnh xung đột vá»›i tùy chá»n « -k »" #: src/common/lpr.c:1101 msgid "Make_temp_fd failed" msgstr "Make_temp_fd bị lá»—i" #: src/common/lpr.c:1103 msgid "You have closed STDIN! cannot pipe from a closed connection" msgstr "" "Bạn đã đóng thiết bị nhập chuẩn STDIN. Không thể gá»­i dữ liệu cho ống dẫn từ " "sá»± kết nối bị đóng" #: src/common/lpr.c:1110 msgid "Copy_STDIN: write to temp file failed" msgstr "Copy_STDIN: lá»—i ghi vào tập tin tạm thá»i" #: src/common/lpr.c:1115 #, c-format msgid "Copy_STDIN: stat of temp fd '%d' failed" msgstr "Copy_STDIN: lá»—i lấy các thông tin vá» fd tạm thá»i « %d »" #: src/common/lpr.c:1171 #, c-format msgid "Check_files: stat of temp fd '%d' failed" msgstr "Check_files: lá»—i lấy các thông tin vá» fd tạm thá»i « %d »" #: src/common/lpr.c:1215 #, c-format msgid "cannot print '%s': %s" msgstr "không thể in « %s »: %s" #: src/common/lpr.c:1224 msgid "not a regular file" msgstr "không phải tập tin chuẩn" #: src/common/lpr.c:1229 msgid "cannot read it" msgstr "không thể Ä‘á»c nó" #: src/common/lpr.c:1244 msgid "" "unprintable characters at start of file, check your LANG environment " "variable as well as the input file" msgstr "" "gặp ký tá»± không thể in ở đầu tập tin: hãy kiểm tra lại biến môi trưá»ng ngôn " "ngữ LANG, cÅ©ng như tập tin nhập vào" #: src/common/lpr.c:1251 #, c-format msgid "option '%c' missing argument" msgstr "tùy chá»n « %c » thiếu đối số" #: src/common/lpr.c:1270 #, c-format msgid "option %c parameter `%s` is not positive integer value" msgstr "tùy chá»n %c tham số « %s » không phải giá trị số nguyên dương" #: src/common/lpr.c:1274 #, c-format msgid "option %c parameter `%s` is not integer value from 0 - %d" msgstr "tùy chá»n %c tham số « %s » không phải giá trị số nguyên từ 0 - %d" #: src/common/lprm.c:234 #, c-format msgid "Printer: %s - cannot remove jobs from device '%s'\n" msgstr "Máy in: %s — không thể gỡ bá» công việc khá»i thiết bị « %s »\n" #: src/common/lprm.c:246 #, c-format msgid "Printer: %s - not in privileged group\n" msgstr "Máy in: %s — không phải trong nhóm có quyá»n\n" #: src/common/lprm.c:354 #, c-format msgid "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n" msgstr "" " cách sá»­ dụng: %s [-A] [-a | -Pmáy_in] [-Dcấp_gỡ_lá»—i] (jobid|user|'all')*\n" "\n" " -a\t\t— má»i máy in\n" " -A \t\t— dùng sá»± xác thá»±c\n" " -Pmáy_in\t— máy in (biến môi trưá»ng PRINTER mặc định)\n" " -Ungưá»i_dùng\t— nhận diện là ngưá»i dùng này (chỉ ngưá»i chá»§\n" "\t\t\t\t\thay ngưá»i dùng có quyá»n đặc biệt) -Dcấp_gỡ_lá»—i\t— cấp gỡ lá»—i\n" " -V\t\t— hiển thị thông tin phiên bản\n" " user\t— gỡ bá» các công việc cá»§a ngưá»i dùng\n" " all\t\t— gỡ bá» má»i công việc\n" " jobid\t— gỡ bá» công việc có mã nhận diện này\n" "\n" " Thí dụ :\n" " 'lprm -Plp 30' gỡ bá» công việc 30 trên máy in lp\n" " 'lprm -a' gỡ bá» má»i công việc cá»§a bạn trên má»i máy in\n" " 'lprm -a all' gỡ bá» má»i công việc trên má»i máy in\n" "\n" "Ghi chú : lprm gỡ bá» chỉ những công việc cho đó bạn có quyá»n gỡ bá».\n" #: src/common/lprm.c:372 #, c-format msgid "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n" msgstr "" " usage: %s [-A] [-Dcấp_gỡ_lá»—i] (jobid|user|'all')* [máy_in]\n" "\n" " -A \t\t— dùng sá»± xác thá»±c\n" " -Dcấp_gỡ_lá»—i\t— cấp gỡ lá»—i\n" " user\t— gỡ bá» các công việc cá»§a ngưá»i dùng\n" " all\t\t— gỡ bá» má»i công việc\n" " jobid\t— gỡ bá» công việc có mã nhận diện này\n" "\n" " Thí dụ :\n" " 'clean 30 lp' gỡ bá» công việc 30 trên máy in lp\n" " 'clean' gỡ bá» công việc thứ nhất trên máy in mặc định\n" " 'clean all' gỡ bá» má»i công việc cá»§a bạn trên máy in mặc định\n" " 'clean all all' gỡ bá» má»i công việc cá»§a bạn trên má»i máy in\n" "\n" "Ghi chú : clean gỡ bá» chỉ những công việc cho đó bạn có quyá»n gỡ bá».\n" #: src/common/sendjob.c:169 #, c-format msgid "sleeping %d secs before retry, starting sleep" msgstr "ngá»§ trong %d giây trước khi thá»­ lại, Ä‘ang bắt đầu ngá»§" #: src/common/sendmail.c:87 #, c-format msgid "printer %s job %s" msgstr "máy in %s công việc %s" #: src/common/sendmail.c:93 msgid " was successful.\n" msgstr " thành công.\n" #: src/common/sendmail.c:98 msgid " failed, and retry count was exceeded.\n" msgstr " bị lá»—i, cÅ©n vượt quá số đếm lần thá»­ lại.\n" #: src/common/sendmail.c:103 msgid " failed and could not be retried.\n" msgstr " bị lá»—i và không thể thá»­ lại.\n" #: src/common/sendmail.c:108 msgid " died a horrible death.\n" msgstr " chết khá»§ng khiếp.\n" #: src/common/sendreq.c:114 #, c-format msgid "no network support for '%s' operation" msgstr "không có khả năng há»— trợ mạng cho thao tác « %s »" #: src/common/getopt.c:82 msgid "--X option form illegal\n" msgstr "Tùy chá»n --X có dạng cấm\n" #: src/common/getopt.c:93 #, c-format msgid "%s: Illegal option '%c'\n" msgstr "%s: tùy chá»n cấm « %c »\n" #: src/common/getopt.c:115 #, c-format msgid "%s: missing argument for '%c'\n" msgstr "%s: thiếu đối số cho « %c »\n" lprng-3.8.B/po/de.gmo0000644000131400013140000010065711531672374011333 00000000000000Þ•×Ô%Œ !6 F T^ m){¥ ¹<Ç2P a o}Œ ¬'º â  *0K4|#±Õï *"C'fŽ— ®½l~$–» Ûè ÷ *Hb&~¥ÄÜ ÷+%Ag2€&³2Ú 8Sqw~˜ž§¯´½)Äîóû7;?"Dglp Ÿ©ÃÓ1Ü2:A/|&¬ÓBé,, 6Y ± # Cæ *'&,-$S- x-;™- Õ-á-õ-. .&.JE..«.¼.Ò.î.ÿ./&/5"I5l5 ‡5¨5"Ä5ç5 6>6<Q6Ž6­6-Å6'ó67#7,+7'X7"€7£7³7Ê7gá7I8ñi8¤[:Ý =ÞFäF“ÿF“H©H ºH ÈHÓHãH,ôH!I7IEGII§I¼IÐI áI ïIýIJ"J3J2CJ"vJ™J ¨J²JÁJ/ÜJE K&RKyK”KªK ÃKÎK$åK+ L 6L BL|ML ÊNØQëQ%R)R GRUR dR rR~R#›R)¿RéR+ÿR$+SPSjS"„S§S¹S1ÓS0T!6T$XT!}TŸT¥T"¬TÏTêTðT"÷TU U)U1U 6UCU)JUtUyUU™UžU·U»U¿UÄUÞUãUçUV V V=VMV5VV6ŒVCÃV.W%6W\WSsW)ÇW2ñW$XDXUXípX‰^_&èe,f IÕu}Wwxž [¢'a”ÆmJXBRŸ7´T†$| Description: %s@%s Auto_hold: on Classes: %s Error: Hold_all: on Message: %s Printing: %s Aborted: %s Spooling: %s Redirected_to: %s Serving: %s Printer: %s - cannot use printer, not in privileged group checking perms '%s' no permissions '%s' removing incoming job '%s' %d job %d jobs (classes %s) (dest %s@%s) (message: %s) (originally %s) (redirect %s) (serving %s) - printer %s@%s has bad printcap entry - printer %s@%s not in printcap Comment: %s ERROR: Filter_status: Holding: %d held jobs in queue Printer: %s - direct connection to device '%s' Queue: %d printable job Queue: %d printable jobs Queue: no printable jobs in queue Server: no server active Server: pid %d active Unspooler: pid %d active class=%s died a horrible death. failed and could not be retried. failed, and retry count was exceeded. holdall of %d: usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer] -A - use authentication -Ddebuglevel - debug level user removes user jobs all removes all jobs jobid removes job number jobid Example: 'clean 30 lp' removes job 30 on printer lp 'clean' removes first job on default printer 'clean all' removes all your jobs on default printer 'clean all all' removes all your jobs on all printers Note: clean removes only jobs for which you have removal permission usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')* -a - all printers -A - use authentication -Pprinter - printer (default PRINTER environment variable) -Uuser - impersonate this user (root or privileged user only) -Ddebuglevel - debug level -V - show version information user removes user jobs all removes all jobs jobid removes job number jobid Example: 'lprm -Plp 30' removes job 30 on printer lp 'lprm -a' removes all your jobs on all printers 'lprm -a all' removes all jobs on all printers Note: lprm removes only jobs for which you have removal permission was successful. # Printcap Information %d data files and maximum allowed %d%s accepting requests since %s %s error= %s%s size= %0.0f%s status= %s%s time= %s%s: Illegal option '%c' %s: cannot set up print queue%s: cannot set up printer%s: insufficient file space%s: job size %0.0f is larger than %d K%s: missing argument for '%c' %s: no permission '%s' %s: no permission to print%s: no permission to show status%s: selected '%s' %s: spooling disabled%s: transfer of '%s' from '%s' failed--X option form illegal -Kcopies -number of copies must be greater than 0 -U (username) can only be used by ROOT-ncopies -number of copies must be greater than 0 ABORTACTIVEAnother print spooler active, possibly lpd process '%ld'Bad format specification '%c'CLASSCLIENTCannot open file '%s', %sDEBUGDEFAULTQDISABLEDOWNDone %d ENABLEGet_local_host: '%s' FQDN name not found!HOLDHOLDALLJob_remove: error '%s'KILLLANG environment variable '%s' LPDLPQLPRMLocale information directory '%s' MOVEMSGMaximum of %d copies allowedMissing mail nameNOHOLDALLNo translation available Printer %s@%s: Printer:Printer: %s - cannot get status from device '%s' Printer: %s - cannot remove jobs from device '%s' Printer: %s - cannot use printer, not in privileged group Printer: %s - direct connection to device '%s' Printer: %s - not in privileged group Printer: %s is %s@%s Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)Remote_job: %d datafiles and only allowed %dSorry, can only print %d files at a time, split job upStatus Information, attempt %d: TRANSLATION TESTUSER environment variable undefinedUsage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]] [-f form-name] [-H special-handling] [-n number] [-o options] [-P page-list] [-q priority-level] [-S character-set] [-S print-wheel] [-t title] [-T content-type [-r]] [-y mode-list] [-Ddebugopt ] [ filenames ... ] lp simulator using LPRng, functionality may differ slightly -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -c - (make copy before printing - ignored) -d printer[@host] - printer on host -D debugflags - debugging flags -f formname - first letter used as job format -G - filter individual job files before sending -H handling - (passed as -Z handling) -m - mail sent to $USER on completion -n copies - number of copies -o option nobanner, width recognized (others passed as -Z option) -P pagelist - (print page list - ignored) -p - (notification on completion - ignored) -q - priority - 0 -> Z (highest), 25 -> A (lowest) -s - (suppress messages - ignored) -S charset - (passed as -Z charset) -t title - job title -T content - (passed as -Z content) -w - (write message on completion - ignored) -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -y mode - (passed as -Z mode) -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default printer. Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo] [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V] [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r] [-Ddebugopt ] [--] [ filenames ... ] -A - use authentication specified by AUTH environment variable -B - filter files and reduce job to single file before sending -C class - job class -D debugopt - debugging flags -F format - job format -b,-l - binary or literal format c,d,f,g,l,m,p,t,v are also format options -G - filter individual job files before sending -J info - banner and job information -K copies, -# copies - number of copies -P printer[@host] - printer on host -Q - put 'queuename' in control file -Raccntname - accounting information -T title - title for 'pr' (-p) formatting -U username - override user name (restricted) -V - Verbose information during spooling -X path - user specified filter for job files -Y - connect and send to TCP/IP port (direct mode) -Z options - options to pass to filter -h - no header or banner page -i indent - indentation -k - do not use tempfile when sending to server -m mailaddr - mail final status to mailaddr -r - remove files after spooling -w width - width to use -- - end of options, files follow filename '-' reads from STDIN PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default printer. Use: move printer (user|jobid)* targetWait_for_subserver: Mergesort failedWaiting %d seconds before retry You have closed STDIN! cannot pipe from a closed connectionaborted jobaborting operationsaborting serverallall classes printed authentication conficts with -k optionauthentication requested (-A option) and AUTH environment variable not setbad -F format string '%s' bad command linebad command line '%s'bad length information '%s'bad printer '%s'bad printer namebad printer name '%s'cannot print '%s': %scannot read itcannot update job ticket file '%s'cannot use printer - not in privileged group class updatedclasses printed '%s' connection to accounting server '%s' failed '%s'could not remove job '%s'disableddisabled and stoppeddoaction: waitpid(%ld) failedduplicate format specification -%c duplicate format specification -F%s enabledenabled and startederror: could not remove '%s'execvp failed - '%s'exitfailed to send job '%s'failed, no retryfiles on command line conflicts with -k optionflushed statusforwarding off forwarding to '%s' gettext translation information '%s' holdall offholdall onholding jobjob '%s' attempt %d, trying %d timesjob '%s' attempt %d, trying indefinitelyjob '%s' removedjob '%s' removed- status expiredjob '%s' savedjob '%s', attempt %d, allowed %dkill server process PID %ld with %s killed joblink failure while sending job '%s'lpq: please use the LPRng lpstat program missing user or printer namemove donemultiple copies conficts with -k optionno connect permissionsno network support for '%s' operationno permission to control serverno permission to spool job '%s'no receive method supported for '%s'no remote support for %s@%sno retrynobannernot a regular filenot implemented yetnothing to printoption %c parameter `%s` is not integer value from 0 - %doption %c parameter `%s` is not positive integer valueoption '%c' missing argumentprinter %s job %sprinter '%s' has illegal char at '%s' in nameprinter '%s' has illegal character at '%s' in nameredirectedremoving destination due to errorsremoving job '%s' - JABORTremoving job '%s' - JFAILNORETRYremoving job '%s' - JREMOVEremoving job '%s' - no permissionsremoving job - status JREMOVEretrying jobsend_block_format configuration option conficts with -k optionsend_data_first configuration option conficts with -k optionserver process PID %ld exited size %0.3fK exceeds %dKsleeping %d secs before retry, starting sleepsleeping, waiting for processes to exitstartedstoppedstopping printing on filter JABORT exit codesubserver pid %ld died with signal '%s'subserver pid %ld exit status '%s'too many errorstreating as successfulunexpected status 0x%xunprintable characters at start of file, check your LANG environment variable as well as the input fileunsupported authentication '%s'usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP destination port] Options -D dbg - set debug level and flags -F - run in foreground, log to STDERR -L logfile - append log information to logfile -V - show version info -p port - TCP/IP listen port, 'off' disables TCP/IP listening port (lpd_listen_port) -P path - UNIX socket path, 'off' disables UNIX listening socket (unix_socket_path) -R port - remote LPD server port (lpd_port) usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime] -A - use authentication specified by AUTH environment variable -a - all printers -c - clear screen before update -l - increase (lengthen) detailed status information additional l flags add more detail. -L - maximum detailed status information -n linecount - linecount lines of detailed status information -Ddebuglevel - debug level -Pprinter - specify printer -s - short (summary) format -tsleeptime - sleeptime between updates -V - print version information -v - print in key: value format usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command] with no command, reads from STDIN -a - alias for -Pall -Ddebuglevel - debug level -Pprinter - printer -Pprinter@host - printer on lpd server on host -Shost - connect to lpd server on host -Uuser - identify command as coming from user -V - increase information verbosity commands: active (printer[@host]) - check for active server abort (printer[@host] | all) - stop server class printer[@host] (class | off) - show/set class printing disable (printer[@host] | all) - disable queueing debug (printer[@host] | all) debugparms - set debug level for printer down (printer[@host] | all) - disable printing and queueing enable (printer[@host] | all) - enable queueing flush (printer[@host] | all) - flush cached status hold (printer[@host] | all) (name[@host] | job | all)* - hold job holdall (printer[@host] | all) - hold all jobs on kill (printer[@host] | all) - stop and restart server lpd (printer[@host]) - get LPD PID lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke LPRM msg printer message text - set status message move printer (user|jobid)* target - move jobs to new queue noholdall (printer[@host] | all) - hold all jobs off printcap (printer[@host] | all) - report printcap values quit - exit LPC redirect (printer[@host] | all) (printer@host | off )* - redirect jobs redo (printer[@host] | all) (name[@host] | job | all)* - reprint jobs release (printer[@host] | all) (name[@host] | job | all)* - release jobs reread - LPD reread database information start (printer[@host] | all) - start printing status (printer[@host] | all) - status of printers stop (printer[@host] | all) - stop printing topq (printer[@host] | all) (name[@host] | job | all)* - reorder jobs up (printer[@host] | all) - enable printing and queueing diagnostic: defaultq - show default queue for LPD server defaults - show default configuration values lang - show current i18n (iNTERNATIONALIZATIONn) support client (printer | all) - client config and printcap information server (printer | all) - server config and printcap widthwrong number arguments, %dProject-Id-Version: LPRng 3.8.28 Report-Msgid-Bugs-To: lprng-devel@lists.sf.net POT-Creation-Date: 2011-02-03 19:40+0100 PO-Revision-Date: $Id: de.po,v 1.3 2004/09/24 20:19:55 papowell Exp $ Last-Translator: Walter Harms Language-Team:de MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8-bit Plural-Forms: nplurals=2; plural=(n!=1); Beschreibung: %s@%s Auto_hold: ein Klassen: %s Fehler: Hold_all: ein Mitteilung: %s Drucken: %s Abgebrochen: %s Spooling: %s Umgeleitet nach: %s in Arbeit: %s Drucker: %s - Nutzung unzulässig, nicht in der zugelassenen Gruppe Eingangskontrolle '%s' Nicht Erlaubt '%s' Entferne Job '%s' %d Job %d Jobs (Klassen %s) (Ziel %s@%s) (Mitteilung: %s) (ursprünglich %s) (Umgeleitet %s) (bearbeite %s) - Drucker %s@%s hat fehlerhafter printcap Eintrag - Drucker %s@%s nicht in printcap Kommentar: %s FEHLER: Filterstatus: Halt: halte %d Jobs vor Drucker: %s - Direktverbindung zum Gerät '%s' Warteschlange: %d druckbarer Job Warteschlange: %d druckbare Jobs Warteschlange: keine druckbaren Jobs Server: kein Server aktiv Server: PID %d aktiv Unspooler: PID %d aktiv Klasse=%s qualvoll verstorben. Fehlschlag, kein weiterer Versuch. Fehlschlag, und bereits zuviele Versuche. alles Halt von %d:· Verwendung: %s [-A] [-Ddebuglevel] (JOBID|USER|'all')* [DRUCKER] -A - benutze die durch die Umgebungsvariable AUTH angegebenene Authentifikation -Ddebuglevel - debug level USER lösche Jobs von Benutzer USER all lösche alle Jobs JOBID lösche Job mit Nummer JOBID Beispiele: 'clean 30 lp' lösche Job 30 für Drucker lp 'clean' lösche den ersten Job für den Standarddrucker 'clean all' lösche alle Jobs für den Standarddrucker 'clean all all' lösche alle Jobs für alle Drucker Hinweis: Man kann nur Jobs löschen wenn man das Recht dazu hat. Verwendung: %s [-A] [-a | -Pdrucker] [-Ddebuglevel] (JOBID|USER|'all')* -a - alle Drucker -A - benutze die durch die Umgebungsvariable AUTH angegebenene Authentifikation -Pprinter - Druckerangabe (standard Drucker durch $PRINTER festgelegt) -U USER - ausgeben als USER (nur als root möglich) -Ddebuglevel - debug level -V - Versionsinformation ausgeben USER lösche Jobs von Benutzer USER all lösche alle Jobs JOBID lösche Job mit Nummer JOBID Beispiele: 'lprm -Plp 30' lösche Job 30 für Drucker lp 'lprm -a' alle Jobs für alle Drucker löschen 'lprm -a all' alle Jobs für alle Drucker löschen Hinweis: Man kann nur Jobs löschen wenn man das Recht dazu hat. war erfolgreich. # Printcap Information %d Datenfiles und %d maximal zulässig%s nimmt Aufträge an seit %s %s Fehler= %s%s Größe=%0.0f%s Status= %s%s Zeit= %s%s: unbekannte Option '%c'. Kann Warteschlange %s nicht starten%s: Drucker kann nicht initialiert werden%s: zu wenig Speicher%s: Jobgröße von %0.3fK ist größer als %d K%s: Option '%c' fehlt ein Argument. %s: keine Erlaubnis '%s' %s: kein Druckgenehmigung%s: Keine Rechte für Statusanzeige%s: gewählt '%s' %s: spooling abgeschaltet%s: Übertragung von '%s' nach '%s' fehlgeschlagenOptionen der Form --X werden nicht unterstützt. -K NR - NR muß größer als 0 sein -U (username) kann nur ROOT benutzen-n NR - NR muß größer als 0 sein ABORTAKTIVEEin anderer LPD ist da, PID ='%ld'Falsche Formatangaben '%c'CLASSCLIENTKann Datei '%s' nicht öffnen; '%s'DEBUGDEFAULTQDISABLEDOWNErledigt %d ENABLEGet_local_host: '%s' FQDN nicht gefunden!HOLDHOLDALLJob_remove: Fehler '%s'ENDEVariable LANG ist: '%s' LPDLPQLPRMLokales Verzeichnis '%s' MOVEMSGMaximal %d Kopien möglichFehlender Email NameNOHOLDALLkeine Übersetzung vorhanden Drucker %s@%s: Drucker:Drucker: %s - keine Statusinformation von Gerät '%s' Drucker: %s - kann Job bei Gerät '%s' nicht entfernen Drucker: %s - Nutzung unzulässig, nicht in der zugelassenen Gruppe Drucker: %s - Direktverbindung zum Gerät '%s' Drucker: %s - keine zulässige Gruppe Drucker: %s ist %s@%s Priotität (erster Buchstabe der Klasse) aber nicht 'A' (Kleinste) bis 'Z' (Höchste)Remote_job: %d Datafiles, Erlaubt sind %dEs sind nur %d Files möglich, Job besser aufteilenStatusinformation, Versuch %d: TRANSLATION TESTVariable $USER undefiniertUsage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d drucker@[host]] [-f FORMAT] [-H special-handling] [-n NR] [-o Optionen] [-P Seitenzahlen] [-q Priorität] [-S Zeichensatz] [-t Titel] [-T content-type [-r]] [-y mode-list] [-Ddebugopt ] [ DATEINAMEN ... ] lp Simulation durch LPRng (Leichte Unterschiede nicht ausgeschlossen) -A - benutze die durch die Umgebungsvariable AUTH angegebenene Authentifikationsmethode -B - Filter Files und reduziere Job auf ein File vor dem Senden -c - (Kopieren vor dem Drucken - ignoriert) -d Drucker[@HOST] - Drucke auf Drucker von HOST -D debugflags - debugging flags -f FORMAT - Erster Buchstabe bestimmt Job Format -G - filter einzelne Jobs vor dem Senden -H Option - (Weitergeleitet als -Z Option) -m - Schicke Abschlußbericht als Email an $USER -n NR - Anzahl von Kopien -o option - 'nobanner' und 'width' Optionen werden erkannt, alles andere wird als -Z option weitergeleitet -P pagelist - (Drucke Seitenliste - ignoriert) -p - (Meldung am Ende - ignoriert) -q - Priorität - 0 -> Z (Höchste), 25 -> A (Kleinste) -s - (unterdrücke Ausgaben - ignoriert) -S charset - (Weitergeleitet als -Z charset) -t title - Jobtitel -T content - (Weitergeleitet als -Z content) -w - (Schicke Nachricht bei Beendigung - ignoriert) -X path - nutze benutzerspezifizierten Filter für die Jobs -Y - direktes Verbinden und Senden an TCP/IP Port -y mode - (Weitergeleitet als -Z mode) -- - Ende aller Optionen, nur noch DATEINAMEN folgen Dateiname '-' bedeutet: Lese von STDIN Die Variablen PRINTER, LPDEST, NPRINTER, NGPRINTER bestimmen den standard Drucker Verwendung: %s [-Pdrucker[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo] [-(K|#)kopien] [-Q] [-Raccount] [-Ttitel] [-Uuser[@host]] [-V] [-Zoptions] [-b] [-m mailaddr] [-h] [-i einrück] [-l] [-w breite] [-r] [-Ddebugopt ] [--] [ DATEINAMEN ... ] -A - benutze die durch die Umgebungsvariable AUTH angegebenene Authentifikationsmethode -B - Filter Files und reduziere Job auf ein File vor dem Senden -C Klasse - Job Klasse -D debugopt - debugging flags -F format - Job Format -b,-l - binäry oder direktes Format c,d,f,g,l,m,p,t,v sind auch Formatangaben -G - filtere einzelne Jobs vor dem Senden -J info - banner und Job Angaben -K NR, -# NR - Anzahl der Kopien -P Drucker[@HOST] - Drucke auf Drucker von HOST -Q - Name der Warteschlage im Controlfile speichern -Raccntname - Angaben zur Abrechnung -T title - Titel für Formatierung mit 'pr' (-p) -U USER - ausgeben als USER (nur als root möglich) -V - Zeige Information während der Verarbeitung -X path - nutze benutzerspezifizierten Filter für die Jobs -Y - direktes Verbinden und Senden an TCP/IP Port -Z options - Optionen für den Filter -h - Kein Titelblatt oder Banner -i indent - Einrücken -k - keine temporären Files erstellen beim Senden -m EMAIL - sende Abschlußbericht an EMAIL -r - lösche Dateien nach dem Spooling -w breite - Nutzbare Breite -- - Ende aller Optionen, nur noch DATEINAMEN folgen Dateiname '-' bedeutet: Lese von STDIN Die Variablen PRINTER, LPDEST, NPRINTER, NGPRINTER bestimmen den standard Drucker Use: move printer (user|jobid)* targetWait_for_subserver: Mergesort fehlgeschlagenNeuer Versuch nach %d Sekunden STDIN ist geschlossen! Pipe kann daher nicht gelesen werdenJob abgebrochenAktion abgebrochenServer beendenallAlle Klassen angegeben Authentication widerspricht der Option -kAuthentifizierung verlangt (Option -A) aber keine Umgebungsvariable AUTH-F -F Formatangabe fehlerhaft: '%s' Commandozeile fehlerhaftCommandozeile fehlerhaft '%s'Falsche Längenangaben '%s'Falscher Drucker '%s'Druckername falschDruckername falsch '%s''%s' kann nicht drucken werden: %skann es nicht lesenKann Job-Datei '%s' nicht öffnenNutzung unzulässig, nicht in der zugelassenen Gruppe Klasse ergänztKlassen angegeben: '%s' Verbinden zum Abrechnen auf Server '%s' unmöglich '%s'Job '%s' nicht entferntabgeschaltetabgeschaltet und gestopptdoaction: waitpid(%ld) fehlgeschlagenDoppelte Formatangabe -%c Doppelte Formatangaben -F%s eingeschalteteingeschaltet und gestartetUPS: '%s' wurde nicht entferntexecvp fehlgeschlagen - '%s'exitJob '%s' nicht verschicktFehlschlag, kein weiteren VersucheFiles auf der Kommandozeile widersprechen der Option -kStatusspeicher geleertWeiterleitung aus Weiterleitung an:'%s' gettext: Übersetzungen '%s' Alles WeitermachenAlles Halthalte Jobjob '%s' Versuch %d , Versuche %d maljob '%s' Versuche %d, Versuch weiterjob '%s' entferntJob '%s' entfernt- Status abgelaufenJob '%s' gespeichertjob '%s', %d Versuche,%d möglichErledige Serverprocess PID %ld mit %s Job getötetVersandfehler bei Job '%s'lpq: Bitte lpstat von LPRng benutzen Kein Nutzer oder Druckername angegebenVerschobenAnzahl der Kopien widerspricht der Option -kVerbindungsaufnahme nicht erlaubt Keine Netzwerkunterstützung für Aktion '%s'kein Recht auf ServerkontrolleKein Recht Job '%s' zu spoolenKein Empfang unterstützt für '%s'Kein Zugriff auf %s@%sKeine WiedervorlageKein Bannerkeine richtige DateiNicht EingebautNichts zu tunOption %c Parameter `%s` ist keine ganze Zahl zwischen 0 und %dOption %c Parameter `%s` ist keine positive ganze ZahlOption '%c' fehlt das ArgumentDrucker '%s' Job '%s'Drucker '%s' hat ein unzulässiges Zeichen im Namen an Position '%s'Drucker '%s' hat ein unzulässiges Zeichen im Namen an Position '%s'umgelenktEntferne Ziel wg. FehlernEntferne Job '%s' - JABORTEntferne Job '%s' - JFAILNORETRYEntferne Job '%s' - JREMOVEKein Recht Job '%s' zu löschenentferne Job - status JREMOVEWiedervorlagesend_block_format Einstellungen widersprechen der Option -ksend_data_first Einstellung widerspricht der Option -kServerprozess PID %ld beendet Größe %0.3fK überschreitet %dKWarte %d Sekunden vor neuem Versuch, warte ...Warte bis Prozess endetgestartetgestopptkein Druck (auf Filter) exit code JABORTUnterserver pid %ld beendet mit Signal '%s'Unterserver PID %ld exit status '%s'zu viele Fehlerwird als Erfolg beurteiltunerwarteter Status 0x%xNichtdurckfähige Buchstaben am Anfang des File, $LANG und das File überprüfenAuthentifizierung nicht unterstüzt '%s'Verwendung: %s [-FV][-D dbg][-L log][-P path][-p port][-R port] Optionen -D dbg - setze debug level und flags -F - im Vordergrund laufen, Protokoll nach STDERR -L logfile - Protokoll an logfile anhängen -V - Versionsangaben -p PORT - Lauschen auf TCP/IP Port PORT, 'off' schaltet Lauschen ab (lpd_listen_port) -P PATH - Lauschen auf UNIX Socket PATH, 'off' schaltet Lauschen ab (unix_socket_path) -R PORT - zu kontaktierender TCP/IP Port bei entfernten LPD-Servern (lpd_port) Verwendung: %s [-aAclV] [-Ddebuglevel] [-Pdrucker] [-t SECS] -A - benutze die durch die Umgebungsvariable AUTH angegebenene Authentifikation -a - alle Drucker -c - Bildschirm löschen vor Neuausgabe -l - zeige detaillierte Statusinformation zusätzliche l Flags zeigen noch mehr Details -L - wirklich alle Statusinformation -n NR - NR Zeilen an Statusinformation -Pprinter - Druckerangabe -s - Kurzfassung -t SECS - Ausgabe nach SECS Sekunden wiederholen -V - Versionsinformation anzeigen -v - im Ausgabeformat Schlüssel: Wert Verwendung: %s [-a][-Ddebuglevel][-Pdrucker][-Shost][-Uname][-V] [befehl] Befehle werden von STDIN gelesen, falls keiner angegeben wurde. -a - alias für -Pall -Ddebuglevel - debug level -Pprinter - Druckername -Pprinter@HOST - Drucker des lpd-Servers auf HOST nutzen -SHOST - Verbinden zum lpd-Server auf HOST -U USER - ausgeben als USER (nur als root möglich) -V - Gesprächiger werden Befehle: active (printer[@host]) - suche nach aktiven Servern abort (printer[@host] | all) - Server anhalten class printer[@host] (class | off) - Setzen/Anzeigen von Druckerklassen disable (printer[@host] | all) - Warteschlange abschalten debug (printer[@host] | all) debugparms - setze debug level down (printer[@host] | all) - Drucken und Warteschlange abschalten enable (printer[@host] | all) - Warteschlange einschalten flush (printer[@host] | all) - Statusspeicher leeren hold (printer[@host] | all) (name[@host] | job | all)* - Job zurückhalten holdall (printer[@host] | all) - alle Jobs zurückhalten kill (printer[@host] | all) - Server anhalten und neu starten lpd (printer[@host]) - PID von LPD ermitteln lpq (printer[@host] | all) (name[@host] | job | all)* - LPQ aufrufen lprm (printer[@host] | all) (name[@host]|host|job| all)* - LPRM aufrufen msg printer message text - Statustext setzen move printer (user|jobid)* target - Jobs in eine andere Warteschlange verschieben noholdall (printer[@host] | all) - Alle Jobs weitermachen printcap (printer[@host] | all) - printcap Daten ausgeben quit - LPC beenden redirect (printer[@host] | all) (printer@host | off )* - Jobs umleiten redo (printer[@host] | all) (name[@host] | job | all)* - Job wiederholen release (printer[@host] | all) (name[@host] | job | all)* - Jobs freigeben reread - Konfiguration neu lesen start (printer[@host] | all) - Drucken einschalten status (printer[@host] | all) - Status des Druckers ausgeben stop (printer[@host] | all) - Drucken ausschalten topq (printer[@host] | all) (name[@host] | job | all)* - Neuorganisation der Jobs up (printer[@host] | all) - Drucken und Warteschlange einschalten Diagnostisches: defaultq - Zeige standard Warteschlange defaults - Zeige standard Einstellungen lang - Zeige aktuelle Spracheinstellungen client (printer | all) - Klient Einstellung und printcap server (printer | all) - Server Einstellung und printcap BreiteFalsche Anzahl von Angaben %dlprng-3.8.B/po/LPRng.pot0000644000131400013140000011303711531672130011727 00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Patrick Powell at al. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #: src/common/lpc.c:270 src/common/lpc.c:435 src/common/lpq.c:547 #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: lprng-devel@lists.sf.net\n" "POT-Creation-Date: 2011-02-03 19:40+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: src/common/accounting.c:134 #, c-format msgid "connection to accounting server '%s' failed '%s'" msgstr "" #: src/common/controlword.c:16 msgid "ABORT" msgstr "" #: src/common/controlword.c:17 msgid "ACTIVE" msgstr "" #: src/common/controlword.c:18 msgid "CLASS" msgstr "" #: src/common/controlword.c:19 msgid "CLIENT" msgstr "" #: src/common/controlword.c:20 msgid "DEBUG" msgstr "" #: src/common/controlword.c:21 msgid "DEFAULTQ" msgstr "" #: src/common/controlword.c:22 msgid "DISABLE" msgstr "" #: src/common/controlword.c:23 msgid "DOWN" msgstr "" #: src/common/controlword.c:24 msgid "ENABLE" msgstr "" #: src/common/controlword.c:25 msgid "HOLD" msgstr "" #: src/common/controlword.c:26 msgid "HOLDALL" msgstr "" #: src/common/controlword.c:27 msgid "KILL" msgstr "" #: src/common/controlword.c:28 msgid "LPD" msgstr "" #: src/common/controlword.c:29 msgid "LPQ" msgstr "" #: src/common/controlword.c:30 msgid "LPRM" msgstr "" #: src/common/controlword.c:31 msgid "MOVE" msgstr "" #: src/common/controlword.c:32 msgid "MSG" msgstr "" #: src/common/controlword.c:33 msgid "NOHOLDALL" msgstr "" #: src/common/controlword.c:34 msgid "PRINTCAP" msgstr "" #: src/common/controlword.c:35 msgid "REDIRECT" msgstr "" #: src/common/controlword.c:36 msgid "REDO" msgstr "" #: src/common/controlword.c:37 msgid "RELEASE" msgstr "" #: src/common/controlword.c:38 msgid "REREAD" msgstr "" #: src/common/controlword.c:39 msgid "START" msgstr "" #: src/common/controlword.c:40 msgid "STATUS" msgstr "" #: src/common/controlword.c:41 msgid "STOP" msgstr "" #: src/common/controlword.c:42 msgid "TOPQ" msgstr "" #: src/common/controlword.c:43 msgid "UP" msgstr "" #: src/common/controlword.c:44 msgid "SERVER" msgstr "" #: src/common/controlword.c:45 msgid "DEFAULTS" msgstr "" #: src/common/controlword.c:46 msgid "FLUSH" msgstr "" #: src/common/controlword.c:47 msgid "LANG" msgstr "" #: src/common/controlword.c:48 msgid "PPD" msgstr "" #: src/common/lpc.c:129 src/common/lpq.c:181 src/common/lpstat.c:147 #: src/common/lpr.c:91 src/common/lprm.c:146 msgid "" "authentication requested (-A option) and AUTH environment variable not set" msgstr "" #: src/common/lpc.c:198 msgid "exit" msgstr "" #: src/common/lpc.c:242 src/common/lpq.c:237 #, c-format msgid "Printer: %s - cannot get status from device '%s'\n" msgstr "" #: src/common/lpc.c:249 src/common/lpq.c:259 src/common/lprm.c:253 #, c-format msgid "Printer: %s - direct connection to device '%s'\n" msgstr "" #: src/common/lpc.c:267 #, c-format msgid "Locale information directory '%s'\n" msgstr "" #: src/common/lpc.c:269 src/common/lpc.c:434 src/common/lpq.c:546 #, c-format msgid "LANG environment variable '%s'\n" msgstr "" #: src/common/lpc.c:272 src/common/lpc.c:437 src/common/lpq.c:549 #, c-format msgid "gettext translation information '%s'\n" msgstr "" #: src/common/lpc.c:274 src/common/lpc.c:439 src/common/lpq.c:551 msgid "No translation available\n" msgstr "" #: src/common/lpc.c:276 msgid "TRANSLATION TEST" msgstr "" #: src/common/lpc.c:306 src/common/lpc.c:317 src/common/lpc.c:335 msgid "all" msgstr "" #: src/common/lpc.c:312 src/common/lpc.c:321 msgid "# Printcap Information\n" msgstr "" #: src/common/lpc.c:350 #, c-format msgid "execvp failed - '%s'" msgstr "" #: src/common/lpc.c:353 #, c-format msgid "fork failed - '%s'" msgstr "" #: src/common/lpc.c:361 #, c-format msgid "doaction: waitpid(%ld) failed" msgstr "" #: src/common/lpc.c:452 #, c-format msgid "" "usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke " "LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect " "jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint " "jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release " "jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder " "jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) " "support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n" msgstr "" #: src/common/lpd.c:178 msgid "No LPD lockfile specified!" msgstr "" #: src/common/lpd.c:189 src/common/lpd.c:202 #, c-format msgid "Another print spooler active, possibly lpd process '%ld'" msgstr "" #: src/common/lpd.c:194 #, c-format msgid "cannot open or lock lockfile - %s" msgstr "" #: src/common/lpd.c:267 msgid "lpd: main() dofork failed" msgstr "" #: src/common/lpd.c:312 src/common/lpd.c:323 msgid "lpd: pipe call failed" msgstr "" #: src/common/lpd.c:330 msgid "lpd: cannot start initial logger process" msgstr "" #: src/common/lpd.c:683 msgid "lpd: select error!" msgstr "" #: src/common/lpd.c:710 msgid "lpd: Lpd_request pipe EOF! cannot happen" msgstr "" #: src/common/lpd.c:735 src/common/lpd.c:738 msgid "Setup_log: open /dev/null failed" msgstr "" #: src/common/lpd.c:745 src/common/lpd.c:749 #, c-format msgid "Setup_log: dup2(%d,%d) failed" msgstr "" #: src/common/lpd.c:754 #, c-format msgid "Setup_log: open %s failed" msgstr "" #: src/common/lpd.c:792 msgid "lpd: Cannot truncate lock file" msgstr "" #: src/common/lpd.c:810 #, c-format msgid "lpd: Cannot open lock file '%s'" msgstr "" #: src/common/lpd.c:912 #, c-format msgid "" "usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP " "destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port " "(lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket " "(unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n" msgstr "" #: src/common/lpd.c:1001 msgid "lpd: fork() failed" msgstr "" #: src/common/lpd.c:1012 msgid "lpd: accept on listening socket failed" msgstr "" #: src/common/lpd.c:1031 msgid "Start_all: pipe failed!" msgstr "" #: src/common/lpd_control.c:87 #, c-format msgid "bad control command '%s'" msgstr "" #: src/common/lpd_control.c:102 #, c-format msgid "printer '%s' has illegal char at '%s' in name" msgstr "" #: src/common/lpd_control.c:114 #, c-format msgid "%s: unknown control request '%s'" msgstr "" #: src/common/lpd_control.c:195 msgid "Use: move printer (user|jobid)* target" msgstr "" #: src/common/lpd_control.c:206 msgid "no permission to control server" msgstr "" #: src/common/lpd_control.c:460 msgid "not implemented yet" msgstr "" #: src/common/lpd_control.c:486 #, c-format msgid "server process PID %ld exited\n" msgstr "" #: src/common/lpd_control.c:489 #, c-format msgid "kill server process PID %ld with %s\n" msgstr "" #: src/common/lpd_control.c:497 msgid "enabled and started" msgstr "" #: src/common/lpd_control.c:498 msgid "disabled and stopped" msgstr "" #: src/common/lpd_control.c:499 msgid "stopped" msgstr "" #: src/common/lpd_control.c:501 msgid "started" msgstr "" #: src/common/lpd_control.c:502 msgid "disabled" msgstr "" #: src/common/lpd_control.c:503 msgid "enabled" msgstr "" #: src/common/lpd_control.c:504 msgid "redirected" msgstr "" #: src/common/lpd_control.c:505 msgid "holdall on" msgstr "" #: src/common/lpd_control.c:506 msgid "holdall off" msgstr "" #: src/common/lpd_control.c:507 msgid "move done" msgstr "" #: src/common/lpd_control.c:508 msgid "class updated" msgstr "" #: src/common/lpd_control.c:509 msgid "killed job" msgstr "" #: src/common/lpd_control.c:510 msgid "aborted job" msgstr "" #: src/common/lpd_control.c:511 msgid "flushed status" msgstr "" #: src/common/lpd_control.c:531 #, c-format msgid "" "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n" msgstr "" #: src/common/lpd_control.c:565 #, c-format msgid "Do_queue_control: write to fd '%d' failed" msgstr "" #: src/common/lpd_control.c:654 #, c-format msgid "%s: no permission '%s'\n" msgstr "" #: src/common/lpd_control.c:738 #, c-format msgid "%s: selected '%s'\n" msgstr "" #: src/common/lpd_control.c:748 #, c-format msgid "%s: cannot set hold file '%s'\n" msgstr "" #: src/common/lpd_control.c:855 msgid " holdall" msgstr "" #: src/common/lpd_control.c:859 #, c-format msgid " class=%s" msgstr "" #: src/common/lpd_control.c:863 msgid " autohold" msgstr "" #: src/common/lpd_control.c:935 src/common/lpd_control.c:990 #: src/common/lpd_control.c:1045 #, c-format msgid "wrong number arguments, %d" msgstr "" #: src/common/lpd_control.c:941 #, c-format msgid "forwarding to '%s'\n" msgstr "" #: src/common/lpd_control.c:943 msgid "forwarding off\n" msgstr "" #: src/common/lpd_control.c:997 #, c-format msgid "classes printed '%s'\n" msgstr "" #: src/common/lpd_control.c:1000 msgid "all classes printed\n" msgstr "" #: src/common/lpd_control.c:1051 #, c-format msgid "debugging override set to '%s'" msgstr "" #: src/common/lpd_control.c:1053 msgid "debugging override off" msgstr "" #: src/common/lpd_jobs.c:435 #, c-format msgid "Do_queue_jobs: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_jobs.c:767 src/common/lpd_jobs.c:787 #: src/common/lpd_jobs.c:2360 #, c-format msgid "cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:770 src/common/lpd_jobs.c:790 #, c-format msgid "Do_queue_jobs: cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:774 src/common/lpd_jobs.c:794 #, c-format msgid "removing job '%s' - no permissions" msgstr "" #: src/common/lpd_jobs.c:1063 #, c-format msgid "Do_queue_jobs: LOGIC ERROR - no identifer '%s'" msgstr "" #: src/common/lpd_jobs.c:1072 #, c-format msgid "Do_queue_jobs: FORWARDING LOOP - '%s'" msgstr "" #: src/common/lpd_jobs.c:1096 #, c-format msgid "cannot update job ticket file '%s'" msgstr "" #: src/common/lpd_jobs.c:1098 #, c-format msgid "Do_queue_jobs: cannot update job ticket file '%s'" msgstr "" #: src/common/lpd_jobs.c:1147 #, c-format msgid "Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d" msgstr "" #: src/common/lpd_jobs.c:1163 src/common/lpd_jobs.c:1227 msgid "sleeping, waiting for processes to exit" msgstr "" #: src/common/lpd_jobs.c:1204 #, c-format msgid "Do_queue_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_jobs.c:1403 #, c-format msgid "Remote_job: %d datafiles and only allowed %d" msgstr "" #: src/common/lpd_jobs.c:1447 #, c-format msgid "link failure while sending job '%s'" msgstr "" #: src/common/lpd_jobs.c:1453 #, c-format msgid "no permission to spool job '%s'" msgstr "" #: src/common/lpd_jobs.c:1459 #, c-format msgid "failed to send job '%s'" msgstr "" #: src/common/lpd_jobs.c:1627 msgid "Fork_subserver: fork failed" msgstr "" #: src/common/lpd_jobs.c:1701 #, c-format msgid "subserver pid %ld exit status '%s'" msgstr "" #: src/common/lpd_jobs.c:1705 #, c-format msgid "subserver pid %ld died with signal '%s'" msgstr "" #: src/common/lpd_jobs.c:1751 msgid "Wait_for_subserver: Mergesort failed" msgstr "" #: src/common/lpd_jobs.c:1762 #, c-format msgid "Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed" msgstr "" #: src/common/lpd_jobs.c:1787 msgid "succ" msgstr "" #: src/common/lpd_jobs.c:1788 msgid "jsucc" msgstr "" #: src/common/lpd_jobs.c:1789 msgid "success" msgstr "" #: src/common/lpd_jobs.c:1790 msgid "jsuccess" msgstr "" #: src/common/lpd_jobs.c:1791 msgid "abort" msgstr "" #: src/common/lpd_jobs.c:1792 msgid "jabort" msgstr "" #: src/common/lpd_jobs.c:1793 msgid "hold" msgstr "" #: src/common/lpd_jobs.c:1794 msgid "jhold" msgstr "" #: src/common/lpd_jobs.c:1795 msgid "remove" msgstr "" #: src/common/lpd_jobs.c:1796 msgid "jremove" msgstr "" #: src/common/lpd_jobs.c:1975 #, c-format msgid "Update_status: no identifier for '%s'" msgstr "" #: src/common/lpd_jobs.c:2008 src/common/lpd_jobs.c:2115 #: src/common/lpd_jobs.c:2157 src/common/lpd_jobs.c:2201 #, c-format msgid "job '%s' saved" msgstr "" #: src/common/lpd_jobs.c:2013 src/common/lpd_jobs.c:2121 #: src/common/lpd_jobs.c:2163 src/common/lpd_jobs.c:2207 #, c-format msgid "could not remove job '%s'" msgstr "" #: src/common/lpd_jobs.c:2015 src/common/lpd_jobs.c:2123 #: src/common/lpd_jobs.c:2165 src/common/lpd_jobs.c:2209 #, c-format msgid "job '%s' removed" msgstr "" #: src/common/lpd_jobs.c:2045 #, c-format msgid "job '%s', attempt %d, allowed %d" msgstr "" #: src/common/lpd_jobs.c:2049 msgid "treating as successful" msgstr "" #: src/common/lpd_jobs.c:2050 msgid "retrying job" msgstr "" #: src/common/lpd_jobs.c:2051 msgid "no retry" msgstr "" #: src/common/lpd_jobs.c:2052 msgid "aborting server" msgstr "" #: src/common/lpd_jobs.c:2053 msgid "removing job - status JREMOVE" msgstr "" #: src/common/lpd_jobs.c:2054 msgid "holding job" msgstr "" #: src/common/lpd_jobs.c:2057 #, c-format msgid "unexpected status 0x%x" msgstr "" #: src/common/lpd_jobs.c:2062 #, c-format msgid "job '%s', %s" msgstr "" #: src/common/lpd_jobs.c:2066 #, c-format msgid "job '%s' attempt %d, trying %d times" msgstr "" #: src/common/lpd_jobs.c:2069 #, c-format msgid "job '%s' attempt %d, trying indefinitely" msgstr "" #: src/common/lpd_jobs.c:2088 msgid "failed, no retry" msgstr "" #: src/common/lpd_jobs.c:2119 #, c-format msgid "removing job '%s' - JFAILNORETRY" msgstr "" #: src/common/lpd_jobs.c:2131 msgid "aborting operations" msgstr "" #: src/common/lpd_jobs.c:2161 #, c-format msgid "removing job '%s' - JABORT" msgstr "" #: src/common/lpd_jobs.c:2170 msgid "stopping printing on filter JABORT exit code" msgstr "" #: src/common/lpd_jobs.c:2180 msgid "removing destination due to errors" msgstr "" #: src/common/lpd_jobs.c:2191 msgid "too many errors" msgstr "" #: src/common/lpd_jobs.c:2205 #, c-format msgid "removing job '%s' - JREMOVE" msgstr "" #: src/common/lpd_jobs.c:2334 #, c-format msgid "Service_worker: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_jobs.c:2363 #, c-format msgid "Service_worker: cannot update job ticket file for '%s'" msgstr "" #: src/common/lpd_jobs.c:2371 #, c-format msgid "Service_worker: no identifier for '%s'" msgstr "" #: src/common/lpd_jobs.c:2757 #, c-format msgid "job '%s' removed- status expired" msgstr "" #: src/common/lpd_rcvjob.c:139 src/common/lpd_rcvjob.c:559 msgid "bad command line" msgstr "" #: src/common/lpd_rcvjob.c:143 src/common/lpd_rcvjob.c:563 msgid "bad printer name" msgstr "" #: src/common/lpd_rcvjob.c:151 #, c-format msgid "%s: cannot set up print queue" msgstr "" #: src/common/lpd_rcvjob.c:187 src/common/lpd_rcvjob.c:602 #: src/common/lpd_secure.c:188 #, c-format msgid "%s: spooling disabled" msgstr "" #: src/common/lpd_rcvjob.c:198 #, c-format msgid "%s: Receive_job: sending ACK 0 failed" msgstr "" #: src/common/lpd_rcvjob.c:210 #, c-format msgid "Receive_job: cannot open lockfile '%s'" msgstr "" #: src/common/lpd_rcvjob.c:215 #, c-format msgid "Receive_job: cannot lock lockfile '%s'" msgstr "" #: src/common/lpd_rcvjob.c:254 msgid "Recovering from incorrect job submission" msgstr "" #: src/common/lpd_rcvjob.c:268 #, c-format msgid "%s: Receive_job - bad control line '%s', len %0.0f, name '%s'" msgstr "" #: src/common/lpd_rcvjob.c:289 src/common/lpd_rcvjob.c:366 #: src/common/lpd_rcvjob.c:403 src/common/lpd_rcvjob.c:454 #: src/common/lpd_rcvjob.c:617 src/common/lpd_rcvjob.c:799 #: src/common/lpd_rcvjob.c:846 src/common/lpd_rcvjob.c:881 #: src/common/lpd_rcvjob.c:917 #, c-format msgid "size %0.3fK exceeds %dK" msgstr "" #: src/common/lpd_rcvjob.c:296 src/common/lpd_rcvjob.c:624 #: src/common/lpd_secure.c:202 #, c-format msgid "%s: insufficient file space" msgstr "" #: src/common/lpd_rcvjob.c:311 src/common/lpd_rcvjob.c:676 #, c-format msgid "%s: sending ACK 0 for '%s' failed" msgstr "" #: src/common/lpd_rcvjob.c:345 src/common/lpd_rcvjob.c:649 #, c-format msgid "%s: transfer of '%s' from '%s' failed" msgstr "" #: src/common/lpd_rcvjob.c:375 src/common/lpd_rcvjob.c:412 #: src/common/lpd_rcvjob.c:463 src/common/lpd_rcvjob.c:854 #: src/common/lpd_rcvjob.c:890 src/common/lpd_rcvjob.c:926 #: src/common/lpd_rcvjob.c:1337 src/common/lpd_rcvjob.c:1413 #, c-format msgid "Error setting up job ticket file - %s" msgstr "" #: src/common/lpd_rcvjob.c:505 #, c-format msgid "Receive_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_rcvjob.c:570 #, c-format msgid "%s: cannot set up printer" msgstr "" #: src/common/lpd_rcvjob.c:638 #, c-format msgid "%s: Receive_block_job: sending ACK 0 failed" msgstr "" #: src/common/lpd_rcvjob.c:659 #, c-format msgid "Receive_block_job: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:706 #, c-format msgid "Receive_block_jobs: write to fd '%d' failed" msgstr "" #: src/common/lpd_rcvjob.c:772 src/common/lpd_rcvjob.c:831 #, c-format msgid "Scan_block_file: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:787 #, c-format msgid "bad length information '%s'" msgstr "" #: src/common/lpd_rcvjob.c:819 #, c-format msgid "Scan_block_file: read failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:824 msgid "Scan_block_file: read unexecpted EOF" msgstr "" #: src/common/lpd_rcvjob.c:1017 #, c-format msgid "%s: no permission to print" msgstr "" #: src/common/lpd_rcvjob.c:1500 src/common/lpd_rcvjob.c:1525 #, c-format msgid "Do_incoming_control_filter: lseek failed '%s'" msgstr "" #: src/common/lpd_rcvjob.c:1613 #, c-format msgid "Get_route: lseek failed '%s'" msgstr "" #: src/common/lpd_remove.c:73 msgid "missing user or printer name" msgstr "" #: src/common/lpd_remove.c:81 src/common/lpd_status.c:175 #, c-format msgid "printer '%s' has illegal character at '%s' in name" msgstr "" #: src/common/lpd_remove.c:110 #, c-format msgid "Job_remove: error '%s'" msgstr "" #: src/common/lpd_remove.c:203 #, c-format msgid "Printer %s@%s:\n" msgstr "" #: src/common/lpd_remove.c:232 #, c-format msgid " checking perms '%s'\n" msgstr "" #: src/common/lpd_remove.c:249 #, c-format msgid " no permissions '%s'\n" msgstr "" #: src/common/lpd_remove.c:263 #, c-format msgid " removing incoming job '%s'\n" msgstr "" #: src/common/lpd_remove.c:266 #, c-format msgid " dequeued '%s'\n" msgstr "" #: src/common/lpd_remove.c:275 #, c-format msgid "error: could not remove '%s'" msgstr "" #: src/common/lpd_remove.c:384 msgid " ERROR: " msgstr "" #: src/common/lpd_secure.c:81 #, c-format msgid "bad command line '%s'" msgstr "" #: src/common/lpd_secure.c:113 #, c-format msgid "bad printer name '%s'" msgstr "" #: src/common/lpd_secure.c:124 #, c-format msgid "bad printer '%s'" msgstr "" #: src/common/lpd_secure.c:166 #, c-format msgid "unsupported authentication '%s'" msgstr "" #: src/common/lpd_secure.c:173 #, c-format msgid "no receive method supported for '%s'" msgstr "" #: src/common/lpd_secure.c:195 #, c-format msgid "%s: job size %0.0f is larger than %d K" msgstr "" #: src/common/lpd_status.c:357 #, c-format msgid "%s: no permission to show status" msgstr "" #: src/common/lpd_status.c:476 #, c-format msgid " (originally %s)" msgstr "" #: src/common/lpd_status.c:486 msgid "" "\n" " Error: " msgstr "" #: src/common/lpd_status.c:491 #, c-format msgid " - %s" msgstr "" #: src/common/lpd_status.c:494 #, c-format msgid " - printer %s@%s not in printcap" msgstr "" #: src/common/lpd_status.c:498 #, c-format msgid " - printer %s@%s has bad printcap entry" msgstr "" #: src/common/lpd_status.c:724 #, c-format msgid " " msgstr "" #: src/common/lpd_status.c:736 #, c-format msgid " Job: %s" msgstr "" #: src/common/lpd_status.c:737 #, c-format msgid "%s status= %s" msgstr "" #: src/common/lpd_status.c:740 #, c-format msgid "%s size= %0.0f" msgstr "" #: src/common/lpd_status.c:743 #, c-format msgid "%s time= %s" msgstr "" #: src/common/lpd_status.c:747 #, c-format msgid "%s error= %s" msgstr "" #: src/common/lpd_status.c:752 #, c-format msgid "%s CONTROL=" msgstr "" #: src/common/lpd_status.c:758 #, c-format msgid "%s HOLDFILE=" msgstr "" #: src/common/lpd_status.c:778 #, c-format msgid " %d job" msgid_plural " %d jobs" msgstr[0] "" msgstr[1] "" #: src/common/lpd_status.c:782 #, c-format msgid " (%d held)" msgstr "" #: src/common/lpd_status.c:787 #, c-format msgid " (%d move)" msgstr "" #: src/common/lpd_status.c:810 #, c-format msgid " Comment: %s" msgstr "" #: src/common/lpd_status.c:821 #, c-format msgid "" "\n" " Printing: %s\n" " Aborted: %s\n" " Spooling: %s" msgstr "" #: src/common/lpd_status.c:867 #, c-format msgid "" "\n" " %s: " msgstr "" #: src/common/lpd_status.c:875 #, c-format msgid " (%s" msgstr "" #: src/common/lpd_status.c:890 #, c-format msgid "" "\n" " Redirected_to: %s" msgstr "" #: src/common/lpd_status.c:893 #, c-format msgid " (redirect %s)" msgstr "" #: src/common/lpd_status.c:903 #, c-format msgid " (dest %s@%s)" msgstr "" #: src/common/lpd_status.c:910 #, c-format msgid "" "\n" " Serving: %s" msgstr "" #: src/common/lpd_status.c:913 #, c-format msgid " (serving %s)" msgstr "" #: src/common/lpd_status.c:920 #, c-format msgid "" "\n" " Classes: %s" msgstr "" #: src/common/lpd_status.c:923 #, c-format msgid " (classes %s)" msgstr "" #: src/common/lpd_status.c:930 msgid "" "\n" " Hold_all: on" msgstr "" #: src/common/lpd_status.c:933 msgid " (holdall)" msgstr "" #: src/common/lpd_status.c:940 msgid "" "\n" " Auto_hold: on" msgstr "" #: src/common/lpd_status.c:943 msgid " (autohold)" msgstr "" #: src/common/lpd_status.c:951 #, c-format msgid "" "\n" " Message: %s" msgstr "" #: src/common/lpd_status.c:954 #, c-format msgid " (message: %s)" msgstr "" #: src/common/lpd_status.c:983 msgid " Queue: no printable jobs in queue\n" msgstr "" #: src/common/lpd_status.c:987 #, c-format msgid " Queue: %d printable job\n" msgid_plural " Queue: %d printable jobs\n" msgstr[0] "" msgstr[1] "" #: src/common/lpd_status.c:994 #, c-format msgid " Holding: %d held jobs in queue\n" msgstr "" #: src/common/lpd_status.c:1000 msgid " Server: no server active" msgstr "" #: src/common/lpd_status.c:1003 #, c-format msgid " Server: pid %d active" msgstr "" #: src/common/lpd_status.c:1011 #, c-format msgid " Unspooler: pid %d active" msgstr "" #: src/common/lpd_status.c:1023 #, c-format msgid "%s SPOOLCONTROL=\n" msgstr "" #: src/common/lpd_status.c:1037 msgid " Status: " msgstr "" #: src/common/lpd_status.c:1041 msgid " Filter_status: " msgstr "" #: src/common/lpd_dispatch.c:39 #, c-format msgid "Dispatch_input: bad request line '%s' from %s" msgstr "" #: src/common/lpd_dispatch.c:177 msgid "Service_connection: getpeername failed" msgstr "" #: src/common/lpd_dispatch.c:224 msgid "Service_connection: BAD LocalHost_IP value" msgstr "" #: src/common/lpd_dispatch.c:230 #, c-format msgid "Service_connection: bad protocol family '%d'" msgstr "" #: src/common/lpd_dispatch.c:261 msgid "no connect permissions" msgstr "" #: src/common/lpd_dispatch.c:284 #, c-format msgid "Service_connection: peek of length %d failed" msgstr "" #: src/common/lpd_dispatch.c:326 #, c-format msgid "Service_connection: cannot read request from %s in %d seconds" msgstr "" #: src/common/lpd_dispatch.c:330 #, c-format msgid "Service_connection: short request line '%s', from '%s'" msgstr "" #: src/common/lpq.c:119 #, c-format msgid "" "usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n" msgstr "" #: src/common/lpq.c:245 #, c-format msgid "Printer: %s is %s@%s\n" msgstr "" #: src/common/lpq.c:252 #, c-format msgid "Printer: %s - cannot use printer, not in privileged group\n" msgstr "" #: src/common/lpq.c:369 src/common/lpq.c:374 src/common/lpq.c:384 #: src/common/lpq.c:431 src/common/lpq.c:438 msgid "Printer:" msgstr "" #: src/common/lpq.c:477 msgid "fork() failed" msgstr "" #: src/common/lpq.c:484 #, c-format msgid "Term_clear: waitpid(%d) failed" msgstr "" #: src/common/lpq.c:510 msgid "lpq: please use the LPRng lpstat program\n" msgstr "" #: src/common/lpstat.c:195 msgid "scheduler is running\n" msgstr "" #: src/common/lpstat.c:199 msgid "no system default destination\n" msgstr "" #: src/common/lpstat.c:201 #, c-format msgid "system default destination: %s\n" msgstr "" #: src/common/lpstat.c:208 #, c-format msgid "system for %s: %s\n" msgstr "" #: src/common/lpstat.c:250 #, c-format msgid " Printer: %s - cannot use printer, not in privileged group\n" msgstr "" #: src/common/lpstat.c:259 #, c-format msgid " Printer: %s - direct connection to device '%s'\n" msgstr "" #: src/common/lpstat.c:387 #, c-format msgid "" "%s not accepting requests since %s -\n" "\tunknown reason\n" msgstr "" #: src/common/lpstat.c:389 #, c-format msgid "%s accepting requests since %s\n" msgstr "" #: src/common/lpstat.c:397 #, c-format msgid "printer %s unknown state. disabled since %s. available\n" msgstr "" #: src/common/lpstat.c:398 #, c-format msgid "printer %s unknown state. enabled since %s. available\n" msgstr "" #: src/common/lpstat.c:404 #, c-format msgid "\tDescription: %s@%s\n" msgstr "" #: src/common/lpr.c:157 msgid "nothing to print" msgstr "" #: src/common/lpr.c:162 msgid "cannot use printer - not in privileged group\n" msgstr "" #: src/common/lpr.c:168 #, c-format msgid "no remote support for %s@%s" msgstr "" #: src/common/lpr.c:179 #, c-format msgid "%d data files and maximum allowed %d" msgstr "" #: src/common/lpr.c:221 src/common/lpr.c:1164 #, c-format msgid "Cannot open file '%s', %s" msgstr "" #: src/common/lpr.c:232 msgid "(lpr_filter)" msgstr "" #: src/common/lpr.c:295 src/common/lpr.c:332 #, c-format msgid "Status Information, attempt %d:\n" msgstr "" #: src/common/lpr.c:299 src/common/lpr.c:336 #, c-format msgid " of %d:\n" msgstr "" #: src/common/lpr.c:312 #, c-format msgid "Waiting %d seconds before retry\n" msgstr "" #: src/common/lpr.c:351 #, c-format msgid "request id is %s\n" msgstr "" #: src/common/lpr.c:354 #, c-format msgid "request id is %d\n" msgstr "" #: src/common/lpr.c:366 #, c-format msgid "Error unlinking '%s' - %s" msgstr "" #: src/common/lpr.c:374 #, c-format msgid "Done %d\n" msgstr "" #: src/common/lpr.c:430 src/common/lpr.c:603 msgid "USER environment variable undefined" msgstr "" #: src/common/lpr.c:448 msgid "-ncopies -number of copies must be greater than 0\n" msgstr "" #: src/common/lpr.c:452 msgid "nobanner" msgstr "" #: src/common/lpr.c:455 msgid "width" msgstr "" #: src/common/lpr.c:530 #, c-format msgid "bad -F format string '%s'\n" msgstr "" #: src/common/lpr.c:533 #, c-format msgid "duplicate format specification -F%s\n" msgstr "" #: src/common/lpr.c:545 msgid "-Kcopies -number of copies must be greater than 0\n" msgstr "" #: src/common/lpr.c:608 msgid "Missing mail name" msgstr "" #: src/common/lpr.c:622 #, c-format msgid "duplicate format specification -%c\n" msgstr "" #: src/common/lpr.c:666 #, c-format msgid "" "Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default " "printer.\n" msgstr "" #: src/common/lpr.c:702 #, c-format msgid "" "Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default " "printer.\n" msgstr "" #: src/common/lpr.c:803 msgid "Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)" msgstr "" #: src/common/lpr.c:827 src/common/lpr.c:832 msgid "(STDIN)" msgstr "" #: src/common/lpr.c:881 msgid "-U (username) can only be used by ROOT" msgstr "" #: src/common/lpr.c:897 #, c-format msgid "Get_local_host: '%s' FQDN name not found!" msgstr "" #: src/common/lpr.c:924 #, c-format msgid "Bad format specification '%c'" msgstr "" #: src/common/lpr.c:931 #, c-format msgid "Sorry, can only print %d files at a time, split job up" msgstr "" #: src/common/lpr.c:937 #, c-format msgid "Maximum of %d copies allowed" msgstr "" #: src/common/lpr.c:1001 msgid "authentication conficts with -k option" msgstr "" #: src/common/lpr.c:1004 msgid "send_block_format configuration option conficts with -k option" msgstr "" #: src/common/lpr.c:1007 msgid "send_data_first configuration option conficts with -k option" msgstr "" #: src/common/lpr.c:1010 msgid "multiple copies conficts with -k option" msgstr "" #: src/common/lpr.c:1013 msgid "files on command line conflicts with -k option" msgstr "" #: src/common/lpr.c:1101 msgid "Make_temp_fd failed" msgstr "" #: src/common/lpr.c:1103 msgid "You have closed STDIN! cannot pipe from a closed connection" msgstr "" #: src/common/lpr.c:1110 msgid "Copy_STDIN: write to temp file failed" msgstr "" #: src/common/lpr.c:1115 #, c-format msgid "Copy_STDIN: stat of temp fd '%d' failed" msgstr "" #: src/common/lpr.c:1171 #, c-format msgid "Check_files: stat of temp fd '%d' failed" msgstr "" #: src/common/lpr.c:1215 #, c-format msgid "cannot print '%s': %s" msgstr "" #: src/common/lpr.c:1224 msgid "not a regular file" msgstr "" #: src/common/lpr.c:1229 msgid "cannot read it" msgstr "" #: src/common/lpr.c:1244 msgid "" "unprintable characters at start of file, check your LANG environment " "variable as well as the input file" msgstr "" #: src/common/lpr.c:1251 #, c-format msgid "option '%c' missing argument" msgstr "" #: src/common/lpr.c:1270 #, c-format msgid "option %c parameter `%s` is not positive integer value" msgstr "" #: src/common/lpr.c:1274 #, c-format msgid "option %c parameter `%s` is not integer value from 0 - %d" msgstr "" #: src/common/lprm.c:234 #, c-format msgid "Printer: %s - cannot remove jobs from device '%s'\n" msgstr "" #: src/common/lprm.c:246 #, c-format msgid "Printer: %s - not in privileged group\n" msgstr "" #: src/common/lprm.c:354 #, c-format msgid "" " usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n" msgstr "" #: src/common/lprm.c:372 #, c-format msgid "" " usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n" msgstr "" #: src/common/sendjob.c:169 #, c-format msgid "sleeping %d secs before retry, starting sleep" msgstr "" #: src/common/sendmail.c:87 #, c-format msgid "printer %s job %s" msgstr "" #: src/common/sendmail.c:93 msgid " was successful.\n" msgstr "" #: src/common/sendmail.c:98 msgid " failed, and retry count was exceeded.\n" msgstr "" #: src/common/sendmail.c:103 msgid " failed and could not be retried.\n" msgstr "" #: src/common/sendmail.c:108 msgid " died a horrible death.\n" msgstr "" #: src/common/sendreq.c:114 #, c-format msgid "no network support for '%s' operation" msgstr "" #: src/common/getopt.c:82 msgid "--X option form illegal\n" msgstr "" #: src/common/getopt.c:93 #, c-format msgid "%s: Illegal option '%c'\n" msgstr "" #: src/common/getopt.c:115 #, c-format msgid "%s: missing argument for '%c'\n" msgstr "" lprng-3.8.B/autogen.sh0000755000131400013140000000035711531672127011612 00000000000000#!/bin/sh set -e rm -f aclocal.m4 libtool config.cache config.status echo "Running autoreconf -i ..." autoreconf -i echo "Now you can run ./configure" echo "(use --enable-maintainer-mode if you want Makefile.in automatically regenerated)" lprng-3.8.B/Makefile.am0000644000131400013140000000426311531672126011644 00000000000000 # still to include: TESTSUPPORT DISTRIBUTIONS SUBDIRS = UTILS po src man conf CLEANFILES = a.out *.bak ? ?.* core *.old *~ autom4te DISTCLEANFILES = *.orig configure.lineno config.cache config.log config.status MAINTAINERCLEANFILES = configure Makefile.in \ config.rpath config.guess config.sub \ aclocal.m4 config.h.in \ depcomp install-sh ltmain.sh missing mkinstalldirs EXTRA_DIST = ABOUT-NLS.LPRng CHANGES autogen.sh\ KERBEROS_configuration STANDARD_configuration MIT_configure \ CONTRIBUTORS COPYRIGHT LICENSE README.SSL.SECURITY update-po: (cd po && $(MAKE) $(AM_MAKEFLAGS) update-po) || exit 1 # ############################################################################### # # Update the patch level when you make a new version # # do this before you start changes # # Don't even think about making this configurable, it is for # # distribution and update purposes only! # # Patrick Powell # ############################################################################### # # update: # rm -f src/include/license.h src/include/copyright.h # sed -e 's/"/\\"/g' -e 's/.*/"&",/' LICENSE >src/include/license.h # sed -e 's/"/\\"/g' -e 's/.*/"&",/' COPYRIGHT >src/include/copyright.h # for i in VERSION ./src/include/patchlevel.h configure.in ; do \ # rcs -l $$i; chmod +w $$i; \ # done; # if [ -x /bin/pwd ] ; then DIR=`/bin/pwd`; fi ; \ # if [ -x /usr/bin/pwd ] ; then DIR=`/usr/bin/pwd`; fi ; \ # DIR=`echo $${DIR} | sed 's,.*/,,'`; \ # DIRVER=` echo $${DIR} | sed 's,.*-,,'`; \ # echo DIR $${DIR}, DIRVER $${DIRVER}; \ # echo "#define PATCHLEVEL \"$${DIR}\"" >./src/include/patchlevel.h; \ # echo $${DIR} >VERSION; \ # S=`echo *.sh | sed -e 's/\.sh//g'`; \ # perl -spi -e "s,=.*,=$${DIRVER}, if(/^VERSION=/ or /^#.* VERSION=/); \ # s,^DISTNAME=.*,DISTNAME=$${DIR},; \ # s,^PORTNAME=.*,PORTNAME=$(PACKAGE),; \ # s,^PORTVERSION=.*,PORTVERSION=$${DIRVER},; \ # s,package name \".*\",package name \"$${DIR}\",; \ # s,^SCRIPTS=.*,SCRIPTS=$$S,;" \ # configure.in lpd.perms.in \ # DISTRIBUTIONS/*/Makefile \ # po/Makefile.in.in printcap # perl -spi -e 's,.*,"Project-Id-Version: $(PACKAGE) $(VERSION)\\n", if(/^"Project-Id/);' \ # po/*.po lprng-3.8.B/README0000644000131400013140000001022011531672126010456 00000000000000 LPRng - An Enhanced Printer Spooler Patrick Powell This is a modified version by other people than Patrick Powell, though most of the code and documentation is from him, though he is not involved in any of the changes since then. last updates 2007-01 The following is a guide to the documentation and LPRng files, and the order you might want to read it in. Files marked with + should (must?) be read in order to succesfully install LPRng. Patrick Powell + README - this file (and please read all of it!) + INSTALL - installation instructions + LPRng-Refernece.html, LPRng-Refernece.pdf, the LPRng Reference Manual available as extra package. + PrintingCookbook - a set of 'printing recipes' or setups and procedures that are commonly encountered. split out of the main LPRng and available as extra package. OVERVIEW The LPRng software is an enhanced, extended, and portable implementation of the Berkeley LPR print spooler functionality. While providing the same interface and meeting RFC1179 requirements, the implementation is completely new and provides support for the following features: lightweight (no databases needed) lpr, lpc, and lprm programs; dynamic redirection of print queues; automatic job holding; highly verbose diagnostics; multiple printers serving a single queue; client programs do not need to run SUID root; greatly enhanced security checks; and a greatly improved permission and authorization mechanism. The source software compiles and runs on a wide variety of UNIX systems, and is compatible with other print spoolers and network printers that use the LPR interface and meet RFC1179 requirements. The package comes with filters for PostScript and HP printers, as well as the usual 'dumb' printers. Note that the PostScript and HP filters do page counting and produce accounting information accounting. In addition, there are a wide variety of other filters that can do page formatting, and produce banner pages. For users that require compatibility with the SVR4 lp and lpstat interface, lpr and lpq will simulate this interface, eliminating the need for another print spooler package. In addition, a publically available PCNFSD server is distributed with LPRng, and interfaces with the PC/DOS/Windows based NFS style print spoolers. For users that require secure and/or authenticated printing support, LPRng supports Kerberos V and/or SSL authentication methods. Additional authentication support is extremely simple to add. Finally, Astart Technlogies (http://www.astart.com) offers commercial support for the LPRng software. WHERE TO GET THE SOFTWARE: The sourceforge project page for this software is: http://sourceforge.net/projects/lprng/ New versions will be available for download at: http://sourceforge.net/project/showfiles.php?group_id=34420&package_id=26541 The CVS repository can be browsed online at: http://lprng.cvs.sourceforge.net/lprng/lprng/ and checked out via: cvs -z3 -d:pserver:anonymous@lprng.cvs.sourceforge.net:/cvsroot/lprng co -P LPRng The LPRng developer mailinlist is lprng-devel@lists.sourceforge.net and can be subscribed via: https://lists.sourceforge.net/lists/listinfo/lprng-devel PLACES TO GET OLDER (UNMODIFIED) VERSIONS FROM: Web Page and Refernce Manual in HTML format: http://www.lprng.com/LPRng.html and the Reference/ directory in the distribution The software may be obtained from ftp://ftp.lprng.com/pub/LPRng (Main site) Mirrors: ftp://ftp.informatik.uni-hamburg.de/pub/os/unix/utils/LPRng (DE) DISTRIBUTION: The LPRng software distribution has the following structure: README* - various README files INSTALL - Installation information configure, Makefile.in, ... - configuration and installation scripts. src/* - source code ABOUT-NLS.LPRng - description of the GNU internationalization man/* - man files for the major components. I recommend reading lpd.8, printcap.5, and lpd.conf.5 CHANGES - change log TESTSUPPORT - a mini lpr setup that can run as user UTILS/* - set of utilities used during developement and for management lprng-3.8.B/ChangeLog0000644000131400013140000001447611531672125011370 000000000000002011-02-03 brl use LPRng.pot as shipped instead of lprng.pot. 2011-01-30 wh remove dead code and add NULL check 2010-07-16 brl add support for dynamically loaded authentication plugins 2010-07-16 brl remove pgp support 2010-07-16 brl remove kerberos4 support 2009-11-19 os fix layout in lpr.n for option -X and -Y 2009-09-22 brl put configured lpd_listen_port default in lpd.conf.5 2009-09-22 brl apply manpage patches by cs from the Debian package 2009-08-09 brl do not link monitor and checkpc with unneeded files 2009-08-08 brl move security structs to the code implementing them 2009-08-08 brl move authentication methods to new src/auth/ directory 2009-08-08 brl fix building on GNU/kFreeBSD (see http://bugs.debian.org/537857) 2009-03-30 brl simplify subserver forking code 2009-03-24 brl remove unused arguments from Read_pid and add Read_pid_from_file 2009-03-24 brl remove Check_str_dup and Check_dup from lpr.c 2009-03-21 brl remove IPP port support as there is no IPP protocol support 2009-03-19 brl make --enable-nls need ngettext and use that for plural forms 2008-07-16 cs Added updated Vietnamese PO file 2008-05-09 brl remove AC_CANONICAL_SYSTEM and code depending on it 2008-05-03 brl use AS_HELP_STRING and newstyle AM_INIT_AUTOMAKE in configure.ac 2008-05-02 brl/wh replace macros with unbalanced parentheses 2008-03-29 brl really only link programs needing it to ssl libraries 2008-03-16 brl adopt lpd.n's description of filter expansion to reality 2008-02-24 wh document that lpd's -L argument has to exist already 2008-02-22 brl move lpc's print of supported authentications to usage() 2008-02-22 brl move lpc's print of supported authentications to usage() 2008-02-22 brl fix unsafe tmpfiles in lprng_certs 2008-02-05 brl make form_addr_and_mask more robust 2008-02-03 brl explicitly set lpd_listen_port and document it better in sample config 2008-02-03 brl add --enable-lpd.conf.local to include that file in default lpd.conf 2008-01-28 brl only link programs needing it to kerberos and/or ssl libraries 2008-01-28 brl remove or "#if 0"-comment some unused functions 2008-01-27 brl new server_tag in user_auth, so kerberos5 in config works again 2008-01-25 brl cast size_t to int before giving it to %d in error messages 2008-01-25 brl make some more functions static as only used within the same .c 2007-11-01 brl increase savefprintf buffer, so multi-line messages fit in 2007-11-01 brl remove default maximum size of accounting files (taken from 3.8.32 or earlier) 2007-10-26 wh/brl (re)generate banner before printing (taken modified from 3.8.32 or earlier) 2007-10-21 brl add new _AIX51 and _AIX52 conditionals from 3.8.32 2007-10-11 brl add k5conn method from 3.8.32 (perhaps rather .29) 2007-10-09 brl add discard_zero_length_jobs from 3.8.32 2007-10-06 brl add forwarding and routing fixes from 3.8.32 (perhaps rather .30) 2007-10-05 brl print list of supported authentications, taken from 3.8.32 2007-10-05 brl add new file locking strategy from 3.8.32 (perhaps rather .29) 2007-10-05 brl also ignore ENOTTY in checkwrite's SETFL (taken from 3.8.32) 2007-10-04 brl save authentication information in control file (taken from 3.8.32) 2007-10-04 brl do without com_err.h or without krb5_read_message (taken from 3.8.32, but modified) 2007-10-04 brl drop patchlevel.h, get version information from autogenerated config.h 2007-08-09 cs Updated Vietnamese and Polish PO file 2007-07-25 cs Added Vietnamese PO file 2007-06-09 brl quiet different compiler warnings 2007-06-09 brl clean up lpf.c and fix bug with spaces before arguments 2007-06-08 brl move some #ifdefs into portable.h 2007-06-08 wh/brl mark messages to be translated in various files 2007-05-31 brl revert 10_linelist_closefd patch that slipped in earlier 2007-05-04 brl make programs' usage message into single string constants 2007-05-01 brl linelist.c: remove unused functions, made local functions static 2007-05-01 brl remove some unused variables gcc complains about 2007-04-07 brl remove unecessary mystrlen from plp_snprintf 2007-04-01 elfring remove some needless variable assignments in monitor.c 2007-03-18 brl demerge code to make binaries a bit smaller 2007-03-06 brl fix lpq with -t on remote printer 2007-02-24 wh add missing option to lpq manpage 2007-02-22 wh clean up checkpc lpd and lpq manpages 2007-02-17 brl add --disable-remote option 2007-02-12 brl INSTALL update move config and init.d examples to conf/ install sample config files in install 2007-02-08 brl generate lpd.conf on make all 2007-02-08 brl clean up KERBEROS_configuration, STANDARD_configuration 2007-02-08 brl add unused AUTHENTICATE/*.c into "make dist" generated tarball 2007-02-07 brl update-po run, only line numbers references have changed 2007-02-07 brl move from gettextize generated po Makefile snippets to manual one 2007-02-06 brl replace md5 sum calculation code 2007-02-04 brl add test-code for md5 sum calculation 2007-02-03 brl correct incorrect static in checkpc.c 2007-02-02 brl make some more local functions static 2007-02-01 wh LPRM option, divert into SYSV style and BSD style 2007-01-29 brl lpbanner.c: more functions made static and Time_str cleanup 2007-01-29 brl make lpbanner not include headers for stuff it does not include make local functions and variables static 2007-01-18 brl switch to automake 2007-01-14 brl fix incomplete prototypes, fix missing prototypes, make local functions static 2007-01-13 brl add noreturn __attribute__ to cleanup functions cast pid_t, gid_t and uid_t when put into printf 2007-01-11 brl add checks for format strings directly use strerror if it exists 2007-01-09 brl various format string parameter fixes 2006-12-30 wh cleanups of lpstat.n 2006-12-17 brl no special case for executables and ar archives (both are not ascii) 2006-12-17 wh replace only occurrence of bzero with memset 2006-12-09 brl replace cancel.n, lpstat.n and lp.n fix some dates in other manpages 2006-12-09 wh multiple manpage fixes (spelling, new contact address, ...) 2006-12-08 wh lpr.c: don't let filename escaping interfere with lpr -r 2006-12-04 cs linelist.c: Close FD before creating LDAP sockets 2006-11-30 brl casts to prevent warnings on architectures with signed chars 2006-11-30 cs fix lpc.8 to tell it is section 8 2006-11-28 brl call CLEAR with argv[0] set to CLEAR, too 2006-11-28 wh make global variable 'msg' local lprng-3.8.B/conf/0000777000131400013140000000000011531672402010611 500000000000000lprng-3.8.B/conf/init.redhat0000644000131400013140000000513311531672130012661 00000000000000#!/bin/sh # # lpd This shell script takes care of starting and stopping \ # lpd (printer daemon). # # chkconfig: 2345 60 60 # description: lpd is the print daemon required for lpr to work properly. \ # It is basically a server that arbitrates print jobs to printer(s). # processname: /usr/sbin/lpd # config: /etc/printcap # replace with the path you installed LPRng's lpd in: LPD_PATH=/usr/sbin/lpd # same with checkpc: CHECKPC_PATH=/usr/sbin/checkpc # how to install this (according to the old postinstall.linux from 2001): # - disable all previous printing systems, e.g.: # for n in lpr lpd lprng cupy cups-lpd ; do /sbin/chkconfig $n off ; done # - update the paths above # - run checkpc -f manually # (and make sure all config files are in place so it succeeds) # - install this file to /etc/rc.d/init.d/lpd # - register this file with chkconfig: # /sbin/chkconfig --add lpd # /sbin/chkconfig --list lpd # /sbin/chkconfig lpd on # service lpd start # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration and check that networking is up. if [ -f /etc/sysconfig/network ] ; then . /etc/sysconfig/network [ "${NETWORKING}" = "no" ] && exit 0 fi [ -x "$LPD_PATH" ] || exit 0 prog=lpd RETVAL=0 start () { echo -n $"Starting $prog: " # Is this a printconf system? if [[ -x /usr/sbin/printconf-backend ]]; then # run printconf-backend to rebuild printcap and spools if ! /usr/sbin/printconf-backend ; then # If the backend fails, we dont start no printers defined echo -n $"No Printers Defined" #echo_success #echo #return 0 fi fi if ! [ -e /etc/printcap ] ; then echo_failure echo return 1 fi # run checkpc to fix whatever lpd would complain about $CHECKPC_PATH -f # start daemon daemon $LPD_PATH RETVAL=$? echo [ $RETVAL = 0 ] && touch /var/lock/subsys/lpd return $RETVAL } stop () { # stop daemon echo -n $"Stopping $prog: " killproc $LPD_PATH RETVAL=$? echo [ $RETVAL = 0 ] && rm -f /var/lock/subsys/lpd return $RETVAL } restart () { stop start RETVAL=$? return $RETVAL } # See how we were called. case "$1" in start) start ;; stop) stop ;; status) status $LPD_PATH RETVAL=$? ;; restart) restart ;; condrestart) # only restart if it is already running [ -f /var/lock/subsys/lpd ] && restart || : ;; reload) echo -n $"Reloading $prog: " killproc $LPD_PATH -HUP RETVAL=$? echo ;; *) echo $"Usage: $0 {start|stop|restart|condrestart|reload|status}" RETVAL=1 esac exit $RETVAL lprng-3.8.B/conf/init.freebsd0000644000131400013140000000174311531672130013027 00000000000000# # -- START -- # init.freebsd.sh # This file can be installed in /usr/local/etc/init.d # as lprng.sh # Freebsd 3.x and 4.x will run all files in this directory # with the suffix .sh as shell scripts # # If you do NOT replace the FreeBSD lpd with LRPng's # in /usr/sbin/lpd, then you should edit the /etc/rc.conf # and set # lpd_enable=NO # # replace this with the absolute path to where you installed lpd at: LPD_PATH=/usr/sbin/lpd lprng_enable="YES" if [ -f /usr/local/etc/rc.subr ] ; then . /usr/local/etc/rc.subr load_rc_config lprng name=lprng rcvar=`set_rcvar` lprng_enable=`eval echo \\$\$rcvar`; elif [ -f /etc/rc.conf ] ; then . /etc/rc.conf fi # ignore INT signal trap '' 2 case "$1" in restart ) $0 stop sleep 1 $0 start ;; stop ) kill -INT `ps -ax | awk '/lpd/{ print $1;}'` >/dev/null 2>&1 ;; start ) if [ "$lprng_enable" != NO ] ; then echo -n ' printer'; $LPD_PATH fi ;; esac lprng-3.8.B/conf/init.solaris0000644000131400013140000000300311531672130013060 00000000000000# # -- START -- # init.solaris.sh # # for Solaris # copy this script to /etc/init.d/lprng # Then make links as required in /etc/rc2.d to the script # cp init.solaris /etc/init.d/lprng # (cd /etc/rc2.d; ln -s ../init.d/lprng S80lprng) # (cd /etc/rc1.d; ln -s ../init.d/lprng K39lprng) # (cd /etc/rc0.d; ln -s ../init.d/lprng K39lprng) # (cd /etc/rcS.d; ln -s ../init.d/lprng K39lprng) # some tips from the old postinstall.solaris script # to disable Solaris' print spool before: # - remove or rename /usr/bin/lp /usr/bin/lpstat /usr/sbin/lpadmin /usr/sbin/lpfilter # /usr/sbin/lpforms /usr/sbin/lpmove /usr/sbin/lpshut /usr/sbin/lpsystem # /usr/sbin/lpusers /usr/ucb/lpc /usr/ucb/lpq /usr/ucb/lpr /usr/ucb/lprm # /usr/ucb/lptest /usr/lib/lp/lpsched /usr/lib/lp/lpNet # - remove printer line from /etc/inetd.conf # and restart inetd # - call lpshut if it exists # - remove the nlsadmin entires: # nlsadmin -r lpd tcp # nlsadmin -r lp tcp # - remove /var/spool/cron/crontabs/lp # - remove all /etc/*.d/*lp # replace with the path you installed LPRng's lpd into: LPD_PATH=/usr/local/sbin/lpd # ignore INT signal trap '' 2 case "$1" in start) # Start daemons. /bin/echo "Starting lpd: \c" $LPD_PATH /bin/echo "" ;; stop) # Stop daemons. /bin/echo "Shutting down lpd: \c" pkill -INT lpd # or: kill -INT `ps -e | awk '/lpd/{ print $1;}'` >/dev/null 2>&1 /bin/echo " server stopped"; ;; *) echo "Usage: $0 {start|stop}" exit 1 ;; esac lprng-3.8.B/conf/printcap0000644000131400013140000001460511531672130012274 00000000000000## The Super Quick Guide to LPRng Printcaps ## Patrick Powell ## Thu Nov 15 13:31:08 PST 2001 # # LPD print queue configuration - Default options # The printcap entry below sets defaults. Add default options # or other entries here # .common: :sd=/var/spool/lpd/%P :sh:mx=0:mc=0 # # [Translation: # .common - the period (.) causes LPRng to treat this as a 'information # only entry. This idea was stolen^H^H^H^H^H^H borrowed from the Unix # 'hidden' file convention, i.e. file names starting with a period # are not displayed by 'ls' or matched by '*' # :sd=/var/spool/lpd/%P # Spool queue directory for temporary storage of print jobs. The # %P will be expanded with the print queue name. Each print queue # MUST have a different spool queue directory, and by using %P # this is guaranteed. # :sh - suppress banners or header pages # :mx=0 - maximum job size in K bytes (0 is unlimited) # :mc=0 - maximum number of copies (0 is unlimited) # ] # # LPD print queue definitions: Define print queues # # Printer on Parallel Port (i.e. - /dev/lpt0) #lp:lp=DEVICE:tc=.common # Example: # lp:tc=.common:lp=/dev/lpt0 # [Translation: # lp - name of the print queue # :tc=.common - include the options in the .common printcap entry # the 'tc' options will be put at the START of the printcap entry # :lp=/dev/lpt0 - open and write the print job to /dev/lpt0 # ] # # Printer on Serial Port (i.e. - /dev/tty00) # Use the :stty to set the speed, bits, and parity using 'stty(1)' # options. Note: almost all printers use 8 bits, no parity. #lp:tc=.common:lp=DEVICE:stty=STTY OPTIONS # Example: # lp:tc=.common:lp=/dev/tty0:stty=19200 raw crtscts # [Translation: lp, :tc, :lp as for A) above. # :stty= options used to configure serial port # ] # # Printer on Network Print Server (i.e. - HP JetDirect) # connecting via a TCP/IP socket. IPADDR is IP address or Fully Qualified # Domain Name of the print server, PORT is the TCP/IP port. # # HP JetDirect uses port 9100 by default. # # Warning: check the Network Print Server documentation for correct # port number. Most non-HP Network Print Servers and non-HP printers # do not use port 9100. # #lp:tc=.common:lp=IPADDR%PORT # Example: # lp:tc=.common:lp=10.0.0.2%9100 # [Translation: lp, :tc, as for A) above. # lp=10.0.0.2%9100 - open a connection to 10.0.0.2, port 9100 # and write the print job to this port. # ] # # D) printer on Network Print Server (i.e. - HP JetDirect or LPD server) # connecting via the LPD print protocol. QUEUE is the name of the # print queue and IPADDR is the IP address or Fully Qualified Domain # Name of the print server. # # Warning: check the Network Print Server documentation for correct # QUEUE name. The 'lp' queue is used on the HP JetDirect as the # default print queue. If there are multiple printer ports on the # device then the QUEUE name is used to select the port. # # Warning: Using this protocol with JetDirect units will almost always # cause a 'banner page' to be generated by the JetDirect unit. # Check the HP documentation on how to disable this most annoying feature. # Usually you simply telnet to the JetDirect and then use the # simple configuration menu presented when you first make connection. # #lp:tc=.common:lp=QUEUE@IPADDR # # Example: # lp:tc=.common:lp=lp@10.0.0.2 # [Translation: lp, :tc, as for A) above. # lp=lp@10.0.0.2 - open a connection to 10.0.0.2, port 515, # and use the RFC1179 (LPD) protocol to transfer the job # to the QUEUE print queue. # ] # # Step 4: Format Conversion (Filter) Required? # # You may discover that your printer does not support PostScript or # requires a special initialization to be done. This is handled # by a filter program. The 'ifhp' filter program is supplied with # LPRng and supports a very wide number of printers. If you need # to have a filter, then add the following lines to the printcap # entry: # # :filter=PATH_TO_IFHP_FILTER # :ifhp=IFHP_OPTIONS # # Note: the LPRng :filter= option replaces the legacy BSD lpd options # :if, :vf, ... options that specify filters for 'f' format, 'v' format, # and so forth (yes, yes, :if is for 'f' format, don't ask). # The :filter option specifies a default filter for all job formats. # Most modern filters such as IFHP, Magikfilter, and RedHat print # filters are smart enough to determine the job format and perform # the appropriate conversions. # # Examples: # # lp:tc=.common:lp=/dev/lpt0 # :filter=/usr/libexec/filters/ifhp # :ifhp=model=hp4simx # # lp:tc=.common:lp=10.0.0.2%9100 # :filter=/usr/libexec/filters/ifhp # :ifhp=model=hp4simx # # lp:tc=.common:lp=lp@10.0.0.2 # :filter=/usr/libexec/filters/ifhp # :ifhp=model=hp4simx # # IFHP Options: # For almost all simple configurations you will only need to # supply the model of printer that you have attached. See the # /etc/ifhp.conf file for a complete listing of supported models. # The default model is for an HP Laserjet 4 SiMx, which supports # PostScript, PCL, and PJL. # # Warning: # IF: # Your model of printer normally provides status and error # reporting over a TCP/IP link # AND: # You are using lp=IPADDR%PORT to connect to the printer # THEN: # The IFHP filter will normally expect to have status information # returned by the printer to tell it that the printer is in working # condition. This will have a small but significant overhead # on job throughput, but you will also get error information. # # HOWEVER: # If the printer SHOULD return status but CANNOT due to either # the printer hardware configuration or it is on a unidirectional # and not bidirectional parallel printer port, then you must use # :model=...,status@ # to tell the IFHP filter not to expect status information. # # Example: # lp:tc=.common:lp=10.0.0.2%9100 # :filter=/usr/libexec/filters/ifhp # :ifhp=model=hp4simx,status@ # # Step 5: Queue creation and LPD restart # Run the following commands to create your spool queues and # then tell the LPD server that it should use them: # su - # checkpc -f # lpc reread lprng-3.8.B/conf/init.generic0000644000131400013140000000161011531672130013022 00000000000000# # -- START -- # init.generic.sh # This file can be installed in /usr/local/etc/init.d or # /etc/init.d as appropriate as lprng.sh or lprng.init or # lpd.init depending on your system. # # You will most likely have to make symlinks to it from /etc/rc.d # directories called Slprng (to run at that level, where number # indicates when to start it) or Klprng (to not run at that level) # replace this with the absolute path to where you installed lpd at: LPD_PATH=/usr/sbin/lpd # if -e does not list all processes, try -ax PSHOWALL=-e # ignore INT signal trap '' 2 case "$1" in restart ) $0 stop sleep 1 $0 start ;; stop ) # or replace with some other method to stop it: kill -INT `ps $PSHOWALL | awk '/lpd/{ print $1;}'` >/dev/null 2>&1 ;; start ) echo -n ' printer'; $LPD_PATH ;; esac lprng-3.8.B/conf/lpd.perms.in0000644000131400013140000002625411531672130012770 00000000000000########################################################################### # LPRng - An Extended Print Spooler System # # Copyright 1988-2001 Patrick Powell, San Diego, CA # papowell@lprng.com # See LICENSE for conditions of use. # ########################################################################### # MODULE: TESTSUPPORT/lpd.perms.proto # PURPOSE: prototype printer permissions file ########################################################################## # Printer permissions data base ## # ## LPRng - An Enhanced Printer Spooler ## lpd.perms file ## Patrick Powell ## ## Access control to the LPRng facilities is controlled by entries ## in a set of lpd.perms files. The common location for these files ## are: /etc/lpd.perms, /usr/etc/lpd.perms, and /var/spool/lpd/lpd.perms. ## The locations of these files are set by the perms_path entry ## in the lpd.conf file or by compile time defaults in the ## src/common/defaults.c file. ## ## Each time the lpd server is given a user request or carries out an ## operation, it searches to the perms files to determine if the action ## is ACCEPT or REJECT. The first ACCEPT or REJECT found terminates the search. ## If none is found, then the last DEFAULT action is used. ## ## Permissions are checked by the use of 'keys' and matches. For each of ## the following LPR activities, the following keys have a value. ## ## Key Match Connect Job Job LPQ LPRM LPC ## Spool Print ## SERVICE S 'X' 'R' 'P' 'Q' 'M' 'C' ## USER S - JUSR JUSR JUSR JUSR JUSR ## HOST S RH JH JH JH JH JH ## GROUP S - JUSR JUSR JUSR JUSR JUSR ## IP IP RIP JIP JIP RIP JIP JIP ## PORT N PORT PORT PORT PORT PORT PORT ## UNIXSOCKET V SK SK SK SK SK SK ## REMOTEUSER S - JUSR JUSR JUSR CUSR CUSR ## REMOTEHOST S RH RH JH RH RH RH ## REMOTEGROUP S - JUSR JUSR JUSR CUSR CUSR ## CONTROLLINE S - CL CL CL CL CL ## PRINTER S - PR PR PR PR PR ## FORWARD V - SA - - SA SA ## SAMEHOST V - SA - SA SA SA ## SAMEUSER V - - - SU SU SU ## SERVER V - SV - SV SV SV ## LPC S - - - - - LPC ## AUTH V - AU AU AU AU AU ## AUTHTYPE S - AU AU AU AU AU ## AUTHUSER S - AU AU AU AU AU ## AUTHFROM S - AU AU AU AU AU ## AUTHSAMEUSER S - AU AU AU AU AU ## REMOTEIP is an alias for REMOTEHOST ## REMOTEPORT is an alias for PORT ## IP is an alias for HOST ## ## KEY: ## JH = HOST IP address/DNS name of host in control file ## RH = REMOTEHOST connecting host IP address/DNS Name ## JUSR = USER user in control file ## CUSR = REMOTEUSER user making control operation request ## JIP= IP IP address/DNS name of host in control file ## RIP= REMOTEIP IP address/DNS name of requesting host ## PORT= connecting host origination port ## SK= true (match) if connection from a unix socket ## CONTROLLINE= pattern match of control line in control file ## ## SA= IP of source of request == IP of host in control file ## SU= user name making request == user in control file ## SV= IP of source of request = IP of server host or server Localhost ## LPC= lpc command globmatched against values ## AU= Authorization check on transfer ## AUTH will be true (match) if authenticated request ## AUTHTYPE will match authentication type of request to pattern ## AUTHUSER will match client authentication id to pattern ## AUTHFROM will match request originator authentication id to pattern ## AUTHSAMEUSER will match requestor authentication id ## to authentication id in job ## ## Match: S = globmatch, IP = IPaddress[/netmask], ## N = low[-high] number range, V= matching or compatible values ## SERVICE: 'X' - Connection request; 'R' - lpr request from remote host; ## 'P' - print job in queue; 'Q' - lpq request, 'M' - lprm request; ## 'C' - lpc spool control request; ## NOTE: when printing (P action), the remote and job check values ## (i.e. - RUSR, JUSR) are identical. ## NOTE: the HOST, USER, SAMEUSER and SAMEHOST checks always succeed ## when checking permissions for a spool queue; they are active only when ## checking permissions of a spooled job. ## ## The UNIXSOCKET will match (true) when connection was made over a UNIX ## socket. ## ## The SAMEHOST match checks to see that one (or more) of the ## IP addresses of the host originating a request is/are the ## matches one or more of the IP addresses of the host whose ## hostname appears in the control file. ## The SAMEHOST match checks to see that one (or more) of the ## IP addresses of the host originating a request is/are the ## matches one or more of the IP addresses of the server. ## FORWARD is the same as NOT SAMEHOST, i.e. - request is ## forwarded. ## ## The special key letter=patterns searches the control file ## line starting with the (upper case) letter, and is usually ## used with printing and spooling checks. For example, ## C=A*,B* would check that the class information (i.e.- line ## in the control file starting with C) had a value starting ## with A or B. ## ## A permission line consists of list of tests and an a result value ## If all of the tests succeed, then a match has been found and the ## permission testing completes with the result value. You use the ## DEFAULT reserved word to set the default ACCEPT/DENY result. ## The NOT keyword will reverse the sense of a test. ## ## Each test can have one or more optional values separated by ## commas. For example USER=john,paul,mark has 3 test values. ## ## The Match type specifies how the matching is done. ## S = glob type string match OR /dev/null start-stop-daemon --start --quiet --oknodo --pidfile "${PIDFILE}" \ --exec $DAEMON echo "done." ;; stop) echo -n "Stopping LPRng: " start-stop-daemon --stop --quiet --oknodo --pidfile "${PIDFILE}" cleanup echo "done." ;; reload) echo "Reloading LPRng: " start-stop-daemon --stop --signal 1 --quiet --pidfile \ "${PIDFILE}" --oknodo echo "done." ;; restart|force-reload) echo -n "Restarting LPRng: " start-stop-daemon --stop --quiet --pidfile "${PIDFILE}" sleep 1 checkpc -f > /dev/null start-stop-daemon --start --quiet --pidfile "${PIDFILE}" \ --exec $DAEMON echo "done." ;; *) echo "Usage: /etc/init.d/lprng {start|stop|restart|force-reload}" >&2 exit 1 ;; esac exit 0 lprng-3.8.B/conf/init.linux0000644000131400013140000000362111531672130012551 00000000000000# # -- START -- # init.linux.sh # # lpd This shell script takes care of starting and stopping # lpd (printer daemon). # Taken from the RedHat Linux 6.2 distribution for the lpd startup # modified to make things a little more robust # # chkconfig: 2345 60 60 # description: lpd is the print daemon required for lpr to work properly. \ # It is basically a server that arbitrates print jobs to printer(s). # processname: lpd # config: /etc/printcap # replace this with the path you installed LPRng's lpd. LPD_PATH=/usr/sbin/lpd # Source function library. if [ -f /etc/rc.d/init.d/functions ] ; then . /etc/rc.d/init.d/functions fi # Source networking configuration. if [ -f /etc/sysconfig/network ] ; then . /etc/sysconfig/network fi # Check that networking is up. [ "${NETWORKING}" = "no" ] && exit 0 [ -f "$LPD_PATH" ] || exit 0 [ -f /etc/printcap ] || exit 0 RETVAL=0 # ignore INT signal trap '' 2 # See how we were called. case "$1" in start) # Start daemons. echo -n "Starting lpd: " if [ -f /etc/redhat-release ] ; then daemon $LPD_PATH RETVAL=$? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/lprng else $LPD_PATH RETVAL=$? fi echo ;; stop) # Stop daemons. echo -n "Shutting down lprng: " if [ -f /etc/redhat-release ] ; then killproc lpd RETVAL=$? [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/lprng else kill -INT `ps ax | awk '/lpd/{ print $1;}'` >/dev/null 2>&1 RETVAL=0 fi echo ;; status) if [ -f /etc/redhat-release ] ; then status lpd else lpc lpd fi RETVAL=$? ;; restart|reload) $0 stop $0 start RETVAL=$? ;; *) echo "Usage: $0 {start|stop|restart|reload|status}" exit 1 esac exit $RETVAL lprng-3.8.B/depcomp0000755000131400013140000004271311531672272011171 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2007-03-29.01 # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007 Free Software # Foundation, Inc. # This program 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, or (at your option) # any later version. # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> $depfile echo >> $depfile # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> $depfile else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # X makedepend shift cleared=no for arg in "$@"; do case $cleared in no) set ""; shift cleared=yes ;; esac case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix="`echo $object | sed 's/^.*\././'`" touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test $1 != '--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o, # because we must use -o when running libtool. "$@" || exit $? IFS=" " for arg do case "$arg" in "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: lprng-3.8.B/CHANGES0000644000131400013140000117775211531672125010621 00000000000000This file documents the history of the original LPRng from Patrick Powell. While this version of lprng was originally based uppon 3.8.28, most of the changes in 3.8.32 are included. (3.8.29, 3.8.30 and 3.8.31 were never publically released up to the time of this writing to all of my knowledge, so things may be attributed to .32 that were actually earlier in other parts of the documentation). Things documented here but not included in this version is the support as CUPS-backend server and the corresponding PDEs for that and changes to the build or install scripts (as those are replaced anyway). Additional changes not done by Patrick Powell can be found in the ChangeLog and NEWS files. Version LPRng-3.8.32 - Thu Sep 6 15:07:19 PDT 2007 added: discard_zero_length_jobs flag zero length jobs are now discarded rather than trying to be printed. However, sometimes zero length jobs are actually MEANT to be printed as the various filters will expand the zero length job into content. This is the way to put the name of a file you want printed from an archive into an option line/flag and then have the back end print it. Ugly, but it works. Version LPRng-3.8.31 - Fri Feb 16 17:33:35 PST 2007 postinstall.freebsd: /etc/rc.conf is not truncated Version LPRng-3.8.30 - Thu Sep 21 11:53:39 PDT 2006 Fixed: If job was forwarded to queue, or redirected to queue, then queue would not start printing. Fixed: If job with multiple copies (lpr -Kxxx) was forwarded to queue or redirected to queue, then forwarded then only a single file copy was printed. Fixed: If the 'router' or 'chooser' was used, then only 1 copy of file was sent to destination queue, and job may unexpected die. Version LPRng-3.8.29 - Fri Jan 28 11:05:58 PST 2005 ATHENTICATION: added k5conn (kerberos 5) method. This is identical to the kerberos method, but does not do encrypted data transfer. BUG FIXES: The authentication information is now saved in the control file. The status of incoming jobs is now displayed with the LPQ command. Unfortunately, the incoming job size is displayed as 0 until the entire job file arrives. The file locking strategy has been modified once more, due to dealing with problems of HUGE incoming jobs that would cause all the LPD/LPRM/... facilities to lock. This required the 'Get_hold_file_info' and 'Set_hold_file_info' usage to change. - job reception: the hold file is created and then modified when all of the job files have been received. - job deletion - you can remove an incoming job. The incoming process is killed as well. If you have 'multiple retries' enabled for job transfer, then the job will be sent again. Such is life. - job printing - the job file remains locked until the 'lpd' server decides what to do with it. This is usually a VERY short period, but if a process needs to be run to determine the destination of the job, it may remain locked until the process has completed. Apple OS-X - LPR+kerberos as backend for CUPS server Added support for the using LPR+kerberos authentication with CUPS backend on Apple OS X. See the README.kprPDE file for the gory details. Basically, OS-X has a 'Printer Driver' set up that specifies the capabilties of a printer as well as the 'driver' or 'transport program' which will handle the transfer of the print job to the remote printer. If compiled with the correct flags, when lpr is invoked as 'klpr', it will assume that it is being used by OS-X as a 'transport program' and take the necessary steps to obtain the user Kerberos credentials and then forward the print job to the LPD server. Note that much of this code is totally dependent on the OS-X system, and I (Patrick Powell) do not have access to details of how it is supported or implemented. The code was supplied by Rich Cochran of Cornell, and has been added to the LPRng system at his and others request. If the PDE support changes on OS-X, then it will be necessary to redo this support. Note that the PDE files are BINARY, and contain compiled and executable code. Kerberos, Red Hat Enterprise Linux The 'com_err.h' file has been removed from some versions of RHEL. Configure now checks to see if it is found. This may break if com_err.h is not in one of the 'standard' locations, or is in a subdirectory such as /usr/kerberos/include, or some other permutation. Updated preinstall, postinstall, preremove, postremove, to be more compatible with package systems such as the FreeBSD 'ports' and rpms. Major Installation Change: If you want to have the LPRng install run a script that stops your current LPD installation, or your current CUPS installation, you will need to use: make STARTSERVER=YES install New Directory: The /usr/local/share/LPRng/ or ($datadir)/LPRng directory will now be used for holding sample versions of configuration files. During the install process these will then be moved to the appropriate destinations by the 'postinstall' scripts. By doing this, you can now generate FreeBSD ports/packages that will have a 'constant' set of locations for files, but then can move them or copy them to system specific destinations. This solves a nasty set of problems with FreeBSD ports/packages, which have a 'fixed' pkg-plist file, but also allows you to specify the destinations of printcap, lpd.conf, and do forth. Files: printcap.sample lpd.conf.sample lpd.perms.sample lprng.sh.sample (startup script), postinstall New Installation Assistance File: /usr/local/share/LPRng/postinstall This can be used to set the sample versions of configuration files to their destinations. In addition, you can also run a set of commands that will attempt to replace your current LPD system with the LPRng system: Bourne/bash shells: STARTSERVER=YES postinstall Others: env STARTSERVER=YES postinstall If you are building a package for mass distribution, then after installing the package on a host you can run this script: pkg_add LPRng-.tar env STARTSERVER=yes /usr/local/share/LPRng/postinstall Version LPRng-3.8.28 - Fri Jul 23 09:01:55 PDT 2004 MAJOR CHANGES: The 'hold file' is now referred to as the 'job ticket' file. This is really what it is. Reference manual, Cookbook, etc., will be modified to reflect this change. incoming_control_filter: The input to this filter now has the format: X=option (from original control file) key=option (options for job) Output for changes should have the format: X= (for option deletion) key= (for option deletion) X=newvalue (for option modification) key=newvalue (for option modification) The following environment variables are also passed, and have slightly different formats than before. CONTROL - image of the control file. Note that the data file entries have the form. f/path/to/temporary/file DATAFILES - space separted list of data files. These are in the format /path/to/temporary/file. Added translations for German. (Translations by: Walter Harms ) Fixed yet another silly problem with moving jobs from a queue while the queue is busy. Now the main server will NOT start another process to move the job if it can do the work itself. Added a counter to make sure that if a job is moved more than a specified number of times, that we catch this and stop moving the job. This code now works (ahem). Version LPRng-3.8.27 - Wed Apr 21 11:32:41 PDT 2004 Fixed: 'Missing HOLD_FILE' logic error fixed in lpd_rcvjob.c (Noted by: Mark Tamisiea ) (And another suggestion by: Christian Reiber ) Fixed: configure with-initpath --with-initpath=PATH now works correctly (Reported by: Jeff Bastian ) Fixed (well, clarified): Errormsg() now checks for a 'null' error string and provides a printable version of errno for logging. Edited the Scan_queue() function to print error message and removed some dead code. (Inspired by comments from: Russell Adams ) lpc MOVE could result in endless loop. (Problem reported by: Wichert Akkerman to Debian bug list, forwarded by: Craig Small ) lpc MOVE will now start printing job in destination, rather than just copying and preserving status of last operation. Added detailed error message for connection failure. (Inspired by comments by: Russell Adams ) Found a really small (1 byte) memory leak in LPD. Solves the mystery of the server dying with malloc failed messages. (Information supplied by: Russell Adams ) Version LPRng-3.8.26 - Tue Feb 3 16:58:00 PST 2004 ADDITION to UTILS: VeryFlexibleChooser.pl script uses SNMP to get printer status and selects printer. (Contributed by: Henrik Edlund ) Fixed: --disable-werror configuration option not set correctly. (Noticed and patched by: Gabriele Balducci ) IPP listening enabled by default. Should not be enabled by default. (ipp_listen_port=0) Version LPRng-3.8.25 - Wed Jan 7 04:46:12 PST 2004 MAJOR CHANGE in internals: The legacy 'control file' has been removed from the spool queue as all of the information is duplicated in the hold file. The various LPRng documents will be updated to reflect this. Users who access the control file information external to LPRng should be warned that this is not a good idea due to file locking, etc. MAJOR CHANGE in 'move' operation: The 'lpc move' is now 'nonblocking'. If you request a job to be moved, the LPD server will start a process to (almost) immediately move the job. Until this job is moved, no other job processing for the queue will be done. If the move is to a local queue on the same host, then the job will be copied via a file copy. This action is identical to the action for sending a job to a 'load balance' queue, with the difference that the job is immediately marked as done rather than after the load balance queue has printed it. Note: if you enter a non-existent remote queue, then the LPD subserver process trying to move the job will/may sit in an endless loop trying to move the job. Added: discard_large_jobs option discard_large_jobs - if this option is set, large jobs are accepted and then discarded. Fixed: Priority and Class For incoming jobs, the first letter of the C (class) field in the control file is used to set the priority. This action is modified by the: # ignore requested user priority ignore_requested_user_priority=0 # do not set priority from class name break_classname_priority_link=0 If not present or the break_classname_priority_link, the default priority value is used to set the priority. (C=) and class (class=) values in the control file. This deals with several lpd print clients that appear to to assign random control file names and do not have a C field in the control file. Not to mention users who try to manipulate queue priorities. Modified: incoming_control_filter action This filter is applied to the incoming job control file. and is used to modify the actions of the LPD server. options. The output can be in the form: Xoption X (no option) Xoption ... key=value key=value The Xoption is equivalent to X=option. The key=value set of options is separated from the first by a blank line. If an option is not specified, it is not modified. The X (no option) or X= (no option) form will remove the option from the control file. It is dangerous to try to modify the A (identifier) option unless the user has intimate knowledge of the LPRng lpd server operation. Modified: filter environment variables Filters are now invoked with the HF environment variable set to the hold file contents. This assists with the incoming_control_filter and control_filter actions. Fixed: The 'Remove_done_jobs' code now removes done and error jobs. This makes the 'done_jobs' and 'done_jobs_max_age' actions symmetrical. Documented: added more details to the -D flags. debug flag format: num | flag[+num] | flag=str flag names: print[+N], lpr[+N], lpc[+N], lprm[+N], lpq[+N], network[+N], database[+N], log[+N], test=num use on command line, or in printcap :db=... entry for server: print: show queue (printing) actions, larger number, more information NUMBER same as print+NUMBER lpr: show servicing lpr actions lpq: show servicing lpq actions lprm: show servicing lprm actions network: show low level network actions database: show low level database actions log: Testing. Don't use this unless you read the code. test: Testing. don't use this unless you read the code. for clients (lpr, lpq, etc): print: show client actions, larger number, more information NUMBER same as print+NUMBER network: show low level network actions. database: show low level database actions. Modified: The lpq display now shows Pr/Class (Priority/Class) information if the priority is different than the class information. This better shows information on the class/priority relationshiop. The Class information is in the 'class=' field in the control file and the Priority information is in the priority field. The 'nonexistent printer message' has been modified to be a little more helpful, or at least more verbose: Status Information, attempt 1 of 3: sending job 'papowell@h110+563' to xx@localhost connecting to 'localhost', attempt 1 connected to 'localhost' requesting printer xx@localhost job 'papowell@h110+563' transfer to xx@localhost failed error 'NONZERO RFC1179 ERROR CODE FROM SERVER' with ack 'ACK_FAIL' sending str '^Bxx' to xx@localhost error msg: 'spool queue for 'xx' does not exist on server h110.private' error msg: 'check for correct printer name or you may need to run' error msg: ''checkpc -f' to create queue' Waiting 10 seconds before retry Version LPRng-3.8.24 - Fri Dec 12 15:03:02 PST 2003 Small bugfixes Cygwin patch applied. (From "Luke Bakken" Comment: I thought I'd check LPRng to make sure that the latest version still works OK with Cygwin. Everything seems OK except for the checkpc.c "root" user warning. Will this patch be OK for that file? GCC 3.xx giveth, GCC 2.95 taketh a hard line. Patch for - t = 0; char buffer[128]; in user_auth.c (From: "Marcus Overhagen" and Jeff Chua ) Version LPRng-3.8.23 - Wed Nov 12 13:32:02 PST 2003 I did not document that the default locations of the lpd.conf and lpd.perms file are now /etc/lpd/lpd.conf and /etc/lpd/lpd.perms This change puts all of the lpd files, except /etc/printcap, whose location is hardwired into too many places, in the /etc/lpd directory. You can change this: configure --help --with-config_subdir=CONFIG_SUBDIR configuration subdirectory (default 'lpd') --with-lpddir=DIR lpd executable directory (default \${sbindir}) --with-lpd_conf_path=PATH path of lpd.conf (default: \${sysconfdir}/${CONFIG_SUBDIR}/lpd.conf) --with-lpd_perms_path=PATH path of lpd.perms (default: \${sysconfdir}/${CONFIG_SUBDIR}/lpd/lpd.perms) --with-printcap_path=PATH path of printcap (default \${sysconfdir}/printcap) --with-lpd_printcap_path=PATH path of lpd_printcap (default \${sysconfdir}/${CONFIG_SUBDIR}/lpd_printcap) --with-initpath=PATH path of lpd startup file (default /usr/local/etc/rc.d/lprng.sh) Also, the postinstall will now copy the old files to the new locations and issue a warning message. Fixed up a very subtle problem with 'chooser' functionality. we now have to find out if we really need to call the chooser if we are working and have a single queue, then we do not need to call the chooser if :sv= p1,p2 but none are available then we do not need to call the chooser if :sv == "" - then we do need to call the chooser if :sv == p1,p2 and at least one is available - then we do need to call the chooser Added the 'chooser_scan_queue' flag. If the flag is 1, then we check all the jobs in the spool queue to see if any can be sent to any destination. If the flag is 0 (default), then only the first printable job in the queue is checked. This causes only the first job in the queue to be tested, which is probably the appropriate behaviour for the majority of situations. Determined that it was possible to do a denial of service attack on the LPRng system. Added a zillion timeouts for reads/writes to socket/pipe connections. - for 'non-printing' actions, used Send_query_rw_timeout - for 'printing' actions, used Send_job_rw_timeout - on initial connections, use Send_job_rw_timeout, then Connect_timeout, and finally fall back to 10 seconds. While this does not totally eliminate the attack, it does try to make the LPD server responsive after the timeout periods. This is better than nothing. Note that there is a problem when you use these timeouts AND you are connecting to a slow printer. This solves the mystery of the 'hanging lpr processes' on some systems where a connection is made to the lpd server and then nothing is sent so there is no way to timeout things. Added a further fallback for missing filters: job format X - filter is :Xf=/filter if present, else filter is :filter=/filter if present, else filter is :if=/filter if present. Added --with-config_subdir (=lpd) to allow the $sysconfig/$subdir to be the directory for lpd.conf and lpd.perms files, also SSL files. The :ppd=file option now specifies the location of a PPD file. This is used by foomatic-rip (http://www.linuxprinting.org) to specify options and by ifhp. - checkpc -f checks to see if the file is present and readable - lpc ppd will return the PPD file contents We can now integrate lrpng into KDE in a straight forward manner, as the ppd file should be standard. Also, you can specify a default PPD file in /etc/lpd.conf. This will be added to the printcap entries shown by lpc printcap and passed to the filters. Added a 'pc_entries_required' option that will force the specified printcap entries to be put into the PRINTCAP_ENTRY information if they have a defined value and are not in the printcap entry. The current (only) value is ppd, but I suspect others might be nice. Fixed a bug in the way that the PGP security was implemented. - removed the PGP* environment variables from the default pass list for clients - did sanity checks for PGPPASS, PGPPASSFILE, and PGPPASSFD, and passed only the correct ones. Also opened the PGPPASSFILE and passed the file descriptor. - made sure that the file descriptor specified in PGPPASSFD was actually connected to the open file. - only passed PGPPASS if running as a client. - on clients, passing the PGPPATH environment value, on server using printcap :pgp_server_pgppath value (if specified). - updated the Reference (AKA LPRng-HOWTO) manual to reflect these changes. In summary, we now use: lp: :pgp_path - path of the PGP program :pgp_id - id for clients to use when sending to server - id used by server for decoding client requests :pgp_server_pgppath - PGPPATH environment variable for server :pgp_server_passphrasefile - file containing passphrase (must be absolute path name or is relative to the spool directory) :pgp_forward_id - for server to server communications id of the remote server :pgp_passphrasefile - default client passphrase file For clients, the following environment variables are used: PGPPATH - location of PGP configuration and key files PGPPASS - password PGPPASSFD - file descriptor to file with password PGPPASSFILE - file with password If PGPASSFD and PGPPASSFILE not defined, then - if PGPPATH defined, look for $PGPPATH/$passphrasefile - if $HOME defined, look in $HOME/.pgp/$passphrasefile Error in SSL Support discovered by Geoff Greene and patch supplied. (Patch and hard work by: Geoff Greene ) Amazing speed of some systems is so fast that jobs complete in less than the resolution of the system clock. This, needless to say, has some interesting problems with job order. Added some sequence numbers as well as time to various places. Screwed up the patch sent by Henrik Edlund . It should have been: > for(i = 0; i < listv.count; ++i ){ > s = listv.list[i]; > - if( (t = safestrpbrk(s,File_sep)) ) *t++ = 0; > + if( (t = safestrpbrk(s,Value_sep)) ) *t++ = 0; > Free_line_list(&l); > - Split(&l,t,Value_sep,0,0,0,0,0,0); > + Split(&l,t,File_sep,0,0,0,0,0,0); > DEBUGF(DLPQ1)("Job_status: Force_lpq_status '%s'='%s'", s,t); (Correction by: Henrik Edlund ) Misimplemented Hendriks accounting fixes. - if( Match_ipaddr_value(&l,&RemoteHost_IP) ){ + if( Match_ipaddr_value(&l,&RemoteHost_IP) == 0 ){ Oooops. (Correction by: Henrik Edlund ) utiltities.c: modified the 'Find_{str,flag,decimal}_value routines so that they did not take a separator option. This appears to be an oversite due to the importation from another set of code. Apparently I wanted to used non-printable characters as separators, but this turned out to be too hard to debug, so I used '=', '#', and '@' instead. Modified the init.freebsd.sh, postinstall.freebsd.sh, and preremove.freebsd.sh files to be a bit more 'ports' friendly. Updated the STANDARD_install to be more in line with FreeBSD/NetBSD. Documented the max_accounting_file_size and min_accounting_file_size option and changed the lpd.conf comment to indicate a 0 value disables truncation. (Lack of documentation pointed out by: Jim Trocki ) Fixed typos in INSTALL document. (Pointed out by: Daniel E Singer ) Version LPRng-3.8.22 - Fri Sep 5 08:45:33 PDT 2003 Updated the LPRng, IFHP, and LPRngTool LICENSE with the new Artistic License from the www.opensource.org web site. Updated the DISTRIBUTIONS/FreeBSD port information to meet the current (new) port format. Renamed LPRng HOWTO to LPRng Reference Manual. Added notes to the Printing Cookbook. lpf.c - removed log() and fatal(). (Suggested by: Torsten Rohlfing ) Filter command line options now allows ${X} to reference a control file option. You can now use: $X with -X (if present) $0X with -X (adds space) $'X with -X'' (adds quotes) $-X with (drops key) $0-X with (same as $-X) $'-X with '' (adds quotes) ${ss} with value of printcap option ss $'{ss} with quoted value of printcap option ss or job control file option Example: filter=ifhp -Z '${S},${O}' This will get the O and S options from the job control file. Note that $S is the 'printer comment name' and '$P' is the 'actual printer name'. (prompted by a question from: Paul Armstrong ) Fixed vars.c 'fifo' option - -{ "fifo", 0, STRING_K, &Fifo_DYN,0,0,0}, +{ "fifo", 0, FLAG_K, &Fifo_DYN,0,0,0}, (Thanks to the Debian folks - especially Craig Small ) Fixed up printer@remotehost%port parsing so you can do: localhost:lp=pr@%P and it gets expanded to: localhost:lp=pr@localhost This is pretty far down the extrema of wierd... But somebody came up with a use for it. Sigh... (Lots of head scratching caused by: Michael J. Carter ) Filters no longer have file descriptor 3 connected to the 'accounting file'. Since the '-a accounting_file' option provides the name of the file and this should be used instead. plp_snprintf now handles '*' in floating precision correctly. (Patch by: Henrik Edlund ) if( Run_OF_filter(), Status_file_DYN ) problem found. (Thanks to the Debian List: Sam Lown and Craig Small ) If you want to use force_lpq_status according to the docs (HOWTO), the following patch has to be applied. Otherwise it doesn't work when you have several ip netmasks listed as in the example: force_lpq_status=s=pc*.eng.com,130.192.12.0/24,l=sun*.eng.com Change is: - Split(&l,t,Value_sep,0,0,0,0,0,0); Value_sep DEFINE( = " \t=#@" ); + Split(&l,t,File_sep,0,0,0,0,0,0); File_sep DEFINE( = " \t,;:" ); (Pointed out to me by: Henrik Edlund ) Updated the configure and src/krb5_auth.c to be consistent with latest Kerberos releases. Added 'accounting_namefixup' option as suggested by Henrik Edlund accounting_namefixup=list[,list]* where list is: host(,host*)[=user(,user*)] The incoming job is check to see if the originating host (RemoteHost_IP) is in the list of hosts; the first matching one found is used. Each host list has the format: host,host... where host has the same format used for the 'oh' and other host name matching options. You can use '!host' to invert matching. For example: host1,127.*,!somehost When a host match is found, the name to be used for the user is determined from the user list; if none is specified then no changes are made. Each entry in the user list has the format ${option} or 'name'; the ${option} values are extracted from the control file (capital letters) or printcap/configuration information (lower case letters/names). The first non-empty value found is used. For example: ${R},${L},${accounting_name},default If the control file 'R' option is present, the R option value is used else if the control file 'L' option is present, the L option value is used, else if the printcap/config option 'accounting_name' is not empty then it is used, otherwise the 'default' value is used. (Original suggestion and patches by: Henrik Edlund ) Fought with the various Kerberos distributions and appear to have a new version that compiles with the Kerberos 1.3.1 release and with other legacy releases. Added the "# REJECT NOT SERVER" comment to the lpd.perms file to cause LPRng to reject all jobs/connections from external (non-localhost) clients Version LPRng-3.8.21 - Mon Mar 17 07:06:57 PST 2003 The LPQ 'stalled' indication is now based on status information updates, rather than the job run time. If there has been no status update for the specified stall time, i.e. - log file (lf=...) or status file (ps=...) then the stalled indication will be displayed. Karol Lewandowski discovered that psbanner, a printer filter that creates a PostScript format banner and is part of LPRng, insecurely creates a temporary file for debugging purpose when it is configured as filter. The program does not check whether this file already exists or is linked to another place writes its current environment and called arguments to the file unconditionally with the user id daemon. -- reported by security.debian.org -- Debian Security Advisory DSA 285-1 Fixed. Version LPRng-3.8.20 - Tue Jan 7 09:18:15 PST 2003 The lpd.conf now uses (EMPTY STRING) for defaults which are empty strings... Before it was '0'. Oops. Patrick At the request of Karl Kopper I reviewed the issues of queue starting, polling the queues for done jobs, and other issues. A small side effect of this is that the LPD server process now starts printing processes. This is actually beneficial as it can now limit the total number of printing processes and allow some LPQ/LPC/LPR etc actions. Here is a summary of the current operation and the options that control it: Options: lpd_force_poll - forces a check of the spool queues, even when there is most likely no reason to. Used when you have some REALLY odd programs running that will directly manipulate the LPD spool queues and you do not want to have to connect to the server. (default is OFF). lpd_poll_time - interval in secs between checking queues for work. Done if there is some reason to suspect that some spool queue had problems and might need to be restarted. This also handles a race condition where a job arrives just as the process servicing the spool queue exits. (default is 5 minutes or 600 seconds) lpd_poll_start_interval - if there are spool queues which need service, fork up to 'lpd_poll_servers_started' processes at a time and then wait for lpd_poll_start_interval seconds before forking more. This prevents the deadly situation where the LPD server is started and in turn starts a gizillion process; the rc starupt scripts may fail because there are no free processes (I kid you not on this one, it drove me nuts trying to find out why the system would crash ONLY when LPD ran with NO debugging - the IO caused it to slow down enough so that the other scripts could run). (default now 1 second) lpd_poll_servers_started - maximum number of processs to fork to be spool queue servers at a time. this prevents the massive forking a huge number of processes at once. (default now 3) max_servers_active - the maximum number of children of LPD that are handling spool queues. Since each spool queue process may have up to 5 children, and these in turn make fork other ones, you should make sure that the limits for the LPD server are set as high as possible, or use this value to throttle activity. The actual limit used by LDP value is the minimum of max_servers_active value and maximum children processes per process/2 as determined by the getrlimit(), sysconf(), or other appropriate system calls. Most problems reported by systems with heavy load are caused by restrictive process limits. Run 'lpd -F -D1 | grep Get_max_servers' (as an ordinary user) and see the limits for processes and file descriptors. Summary: lpd_force_poll=0 lpd_poll_time=600 (5 minutes) lpd_poll_start_interval=1 (1 second) lpd_poll_servers_started=3 (3 per start interval) max_servers_active=1024 Experiments with heavily loaded systems (FreeBSD 4.7, Solaris 2.8, Linux RedHat 7.3, and Mandrake 8) indicate that these values should not cause system trauma. Your milage may vary; if the load average goes up very high, then set lpd_poll_start_interval to a larger value and/or decrease the lpd_poll_servers_started value. Both is best. The amount of free memory seems to be the limiting factor on the system loading. When you send a job via LPR, the LPD server forks a 'service socket' process to handle job reception; in previous versions after receiving the job the process would then call Do_queue_jobs() to take on the duties of the 'handle the jobs in the spool queue' process. In this version the 'service socket' process sends a 'start queue' request to the LPD server and then exits. The LPD service will then fork a process to become the 'handle the jobs' process. Similarly, when an lpc operation needs to start a 'handle the jobs' process, a message is sent to the LPD server to start the process. While there is no real difference in performance on lightly loaded systems, there is a big difference on heavily loaded systems. Now the LPD server can control the total number of active spool queues much easier, and the system does not get overloaded as easily. Also, the LPRng server does not clobber the system at startup time as badly now. By the way, queues which are started or have jobs put in them by LPC or LPR have priority over queues that are started by the LPD process looking for work, and the LPD server will brutally try to start as many as possible. Thus, if you do an 'lpc start all' you can bring the system to its knees for a short time until all of the forking and file reading activity is completed. Since only the administrator can do an 'lpc start' command, this should not be an issue... Keith ("HP Printer Dies Horrible Death") Rinaldo has reported that some HP printers lock up and do not report status, etc., and display a nasty low level error message on the printer console such as 7900FE. The IFHP filter or LPD would sit there waiting for a response. The 'keepalive' TCP/IP facility does not solve this problem, as sometimes the TCP/IP stack is OK but the job handling code (i.e. - print engine) is non-functional. You need to try to get a response from the printer, which is what the IFHP filter does. NOTE: send_job_rw_timeout default value is now 0 (no timeout). In order to not surprise new users, the default value for send_job_rw_timeout is now 0, i.e.- no timeout. Details below. The send_job_rw_timeout is now used to set a maximum time that the printer (network, parallel port or serial port) connection will be 'inactive', i.e. - no data input and not available for data output, OR, starting with this release, that the various filter processes do not update the status file (by default, ${spooldir}/status.printer). When the timeout expires the job will terminate with a JTIMEOUT status, which will be treated as a JFAIL status. /* LPRng internal process exit status */ #define JTIMEOUT 43 /* 12 timeout */ The IFHP filter (ifhp-3.5.11) now has a similar 'send_job_rw_timeout' option that has the same effect as the LPD 'send_job_rw_timeout'. If the file descriptor used to communicate with the printer is inactive for this period of time, then the IFHP filter will exit with a JTIMEOUT error code, which will be treated as a JFAIL status. This will only work if the printer goes totally catatonic and does not reply with status, or the print filter goes catatonic and does not update the status file. This situation, unfortunately, can happen when the printer is taken offline in the middle of a job in order to put paper in the paper tray. You can't win them all... but if the time taken to put the paper in the tray is less than the send_job_rw_timeout then you should be OK. Version LPRng-3.8.19 - Thu Dec 5 12:34:45 PST 2002 Check_for_missing_files was not writing control file. (Spotted by Keith ("Wanna bet on that?") Rinaldo Version LPRng-3.8.18 - Mon Dec 2 12:08:34 PST 2002 Added the 'fifo' option - this now makes LPRng handle one incoming job at a time in FIFO order. If you send jobs A B C then they get delivered in order A B C. For users who MUST have sequential delivery of jobs. Some Linux distributions set 'unlimited' resources for all parameters, such as user processes. Added limit of 1024 processes for such cases as the system will die a horrible death at startup. Version LPRng-3.8.17 - Sat Oct 26 20:11:28 PDT 2002 Found a race condition between LPD printing, LPRM, and LPC actions that would cause LPD to stop printing if you removed or did an LPC action on a job. After a bit of thought, decided that the job would get moved or removed anyways. Sigh... But you might get a bogus error message about 'cannot find id' as the job hold file has been removed. Version LPRng-3.8.16 - Mon Aug 12 15:26:05 PDT 2002 lpr now honors :mx=xx values so you can check job size before you send it. (Suggested by: Rick Cochran ) configure --disable-werror removes the -Werror option from CFLAGS. (From the wish list of: Rick Cochran ) Bad incoming jobs are removed. You do not get the jobs left in the queue as errors. Note - spoolers will keep trying to send jobs even when they get error and sit in an endless loop. No solution for this one except to get a better print spooler or whatever... Version LPRng-3.8.15 - Sun Aug 11 13:11:48 PDT 2002 Remove_done_jobs - checks to see if the INCOMING flag is set BEFORE it checks to see if there is an error and only checks for the data files if the ERROR or DONE flags are set. This removes a race condition. It was bloody obvious when I looked at it... I wonder why I did not see it before? Version LPRng-3.8.14 - Tue Aug 6 09:14:06 PDT 2002 man page fixes. (Spotted by the eagle eyes of: Eric S. Raymond ) Based on third hand reports, some installations of GNU compilers on HPUX and other systems now have 'fd_set' data types. I have modified configure so that it checks for 'fd_set' being present. I wish there was a way to read the man pages and find out if this was the real case. The configure 'enable-ssl/disable-ssl/' option was not working. Once again beating on autoconf 1.53 ... It now understands 'enable-OPTION' and 'disable-OPTION'. The Samba examples in the LPRNG-Howto were not consistent. changed queuepause command = /usr/sbin/lpc -P%p stop queueresume command = /usr/sbin/lpc -P%p start to queuepause command = /usr/local/sbin/lpc stop %p queueresume command = /usr/local/sbin/lpc start %p (Suggested by: Jim Van Sickler ) Version LPRng-3.8.13 - Mon Jul 22 09:07:57 PDT 2002 Major Enhancement In Printcap and Configuration Functionality After much consideration, added the 'client.xxx' and 'server.xxx' facility. Briefly, if you have a printcap entry of the form client.xxx or server.xxx then this can be used to set the corresponding xxx variable when the printcap entry is used by the lpd server or the LPRng client programs lpr, lpq, lprm, checkpc, etc. Entry Program Type Sets server.xxx = vvv lpd (server) xxx = vvv client.xxx = vvv lpr,lpq... (client) xxx = vvv The purpose of this enhancement is to allow a single printcap entry to be used for both client and server operation, especially in situations where the lpd server is forwarding or sending jobs to another lpd queue. Example of use: lp: # used by clients, forcess them to send to # specified server :lp=%P@server.hostname:force_localhost@ # used by lpd server # the server will now send jobs to the # specified destination :server.lp=%P@destination This is equivalent to and replaces the :client and :server printcap flags, as shown below: lp:client :lp=%P@server.hostname:force_localhost@ lp:server :lp=%P@destination This selection operation also works with values in the lpd.conf file, allowing global overrides for clients and servers. (I can't imagine a use for this, but it is there if somebody wants to use it.) The lpc client and lpc server commands will display the selected client.xxx and server.xxx values. They are also propagated to the PRINTCAP_ENTRY environment variables for filters. Typo's in documentation corrected. (Patch by: Stepan Kasal ) lpr Kerberos authentication failures were not being reported. (Problem noticed by: Rick Cochran ) Added SSL authentication. See the README.SSL.SECURITY file for the truly complicated details. Note that testing with certificates signed by non-root CA indicates that the client is not sending a certificate, even though one has been requested and the certificates and signing certs are in the right places. lpd.conf did not have 'include' functionality working. (Patch by: Stepan Kasal ) Added Yet Another LPRng Option: user_is_authuser user_is_authuser: if( header_info && User_is_authuser_DYN && (s = Find_str_value(header_info,AUTHUSER,Value_sep)) ){ Set_str_value(&job->info,LOGNAME,s); DEBUG1("Check_for_missing_files: authuser '%s'", s ); } printcap: lp:auth=kerberos5:user_is_authuser:... Causes the principle name to be used as the user name. lpq_in_perl was screwed up (Patches by: Anthony Thyssen ) generate_banner core dumped. Turned out not to be setting banner format ("f") when generating entry, so that control file generation core dumped when generating new control file. (Problem reported by: "Keith Rinaldo" ) Updated Remove_done_jobs to sort jobs by completion time. Added 'Set_nz_flag_value' function to stop the ERROR_TIME value from being gratuitously updated by various routines. Found possible cause of 'job data files not removed' problem in the Remove_done_jobs() code. There is a possibility of a data file being orphaned if a 'done job' is removed by the spooler at the same time that another processes such as lpq information gathering examines the print job. Rare, but possible. Put warnings in the LPRng-HOWTO section on Samba about the done_jobs option and interaction with SAMBA job status. (Suggested by: Marcus Manske ) Added yet another wakeup and kick to the master server process so that printer pools will respond faster. Sigh... Version LPRng-3.8.12 - Mon May 6 08:21:49 PDT 2002 patch for TCPWRAPPERS added a gratuitous -lwrap to the src/Makefile. (Spotted by: Rabellino Sergio ) Version LPRng-3.8.11 - Thu Apr 4 07:49:30 PST 2002 Subtle problem when a filter fails and produces zero length file. This is now treated as a JABORT level error. The problem is that RFC1179 treats a file length as 0 as a 'read until end of file on socket'. This means that folks who have filters that WILL produce zero length files need to do something to produce at least one byte of 'dummy' output. (Brought to my attention by: Sergij Kovalenko ) Fixed up a portability issue for Solaris 2.6, in linksupport.c. Need to do an unsigned long cast to do comparison of INADDR_NONE. (Original patch from: Dr Andreas F Muller ) Added patches to support TCP wrappers. Use: configure --enable-tcpwrappers (Patch by: Tobias Burnus ) Added a 'Linux Standards Base' (LSB) style startup script for Linux systems. (Provided by: Tobias Burnus ) Missing initialization for statb (Patch by: Rob Joyce ) Clobbering Logfile_LPD in common/lpd.c (Patch by: Hugh McDonald ) Added a call to 'Remove_done_jobs()' in lpd_status.c; then modified Remove_done_jobs to return indication that a job was removed so that lpd_status.c would RESCAN queue... Sigh... OK, but it now works 'right'. (Stale jobs not getting removed noted by: Richard Ems ) The problem of saturating a server when checking for work was re-examined. The new approach is: a) if some work was done, then check for success at lpd_poll_time intervals. If there remains work to be done and there is no process actively doing the work, mark the queue as needing service. b) for the marked queues, start at most 'lpd_poll_servers_started' queues at once, and start these at intervales of 'lpd_poll_start_interval' seconds. The effect of this will be to limit the number of processes that LPD will start at a time. (Pushed to look at the problem by: Johan Bengtsson ) Found a very odd bug... the escape code for '\:' in printcap entries appears to be broken. The fix was to assume that the only places where it would be used was in 'filter' or other options where the 'expand escape sequences' code would be called and would take care of replacing "\:" by a ":". . The 'Printer_device()' routine, when opening a filter as an output device, did not provide 'stdout' for the filter. Some filters such as pap from Appletalk seem to need this as they produce messages on STDOUT (fd 2) as well as STDERR (fd 3). Version LPRng-3.8.10 - Sun Mar 31 11:31:19 PST 2002 printcap.5 had :as and :ae examples reversed (Spotted by the guy with the red pen and the eagle eyes: Craig Small ) Slew of patches sent in by Tim Waugh - silly little kerberos include file patch - can't spell printer patch - si no moleste the files in the spool queue patch (already done) - added configure ability to find 'pr' program - GCC flags -W -Wall -Werror -Wno-unused-parms - also fixed up &*)*(&)*(& unsigned and signed integer casts Added patch to allow tcp wrappers to be used. Configure updated configure --enable-tcpwrappers use tcp wrappers (-lwrap) (Patch from: Tobias Burnus ) The authentication and connection information for permissions checking is now recorded so it can be used for permissions checking. and a couple of new fields have been added. The following permission tags now have the indicated values UNIXSOCKET - true (match or 1) if connection was over a UNIX socket, i.e. - the local host. When SERVICE=P REMOTEHOST - the original remotehost from which the job was sent (previously was the HOST value) REMOTEPORT - the original port from which the job was sent (previously was undefined ) AUTH - true (match or 1) if job sent using authentication AUTHTYPE - authentication type AUTHUSER - value of authentication key for user who originated job. For example, for kerberos this is the user's principle value AUTHFROM - value of authentication key for sender of job. For example, if the job was from the LPR program, this would have the same value as AUTHUSER. However, if it was forwarded from a server, it would have the server's authentication name or value. lpd.perms.in update to match the new entries (Requested by: Toby Blake ) Once again the checkpc file creation stuff is modified so that it can create files in a directory NOT owned by the lpd group/user. This is necessary for log files and other items. Note that this MAY cause problems for log file truncation as you need to copy file contents rather than just renaming them. But it turns out that I am already doing this so it appears to be OK. CAVEAT EMPTOR. (Reported by: Torsten Wiebesiek ) Usage messages now display version information as well as options and available debug flags. Idea shamelessly swiped from somebody else. (Stolen from: 'Guido' Van Rossen) Version LPRng-3.8.9 - Sat Mar 2 15:02:11 PST 2002 The 'unix_socket_path' and 'lpd_port' options have been modified slightly to correct some ambiguous behaviour, and a 'lpd_listen_port' option has been added. lpd -p lpd_listen_port -P unix_socket_path - the -p and -P command line options override the lpd.conf lpd_listen_port and unix_socket_path options - the default values for lpd_listen_port is "", indicating the use the 'lpd_port' value. The value "off" suppresses opening a port or socket. This allows the following operation: No unix socket: lpd -Poff (/etc/lpd.conf unix_socket_path=off) No lpd listening socket: lpd -poff (/etc/lpd.conf lpd_listen_port=off) Note that LPD will still open connections to the remote LPD servers using 'lpd_port'. If you want to override the destination lpd port, you must modify the lpd.conf file. Jeff Chua of FedEx (Federal Express) showed up at my office armed with a set of test scripts and a laptop running LPRng. He demonstrated the problem of the 'missing datafile' during job transfers. I have fixed the problem in this release. See the UTIL/testpr file. (Thanks to: Jeff Chua: ) more autoconf + automake + libtool insanity: WITH_LINK removed STRIP now used by libtool, changed to STRIP_OPTION Added AC_C_VOLATILE (see note on volatile below) (Reported by: Rick Troxel ) Forced a rescan of the input queue when the number of done jobs exceeds 'done_jobs' or the time since the first done job exceeds done_jobs_max_age . This solves a silly problem that shows up when you have a slew of jobs in a queue, the subserver is processing them, and no new jobs arrive while it is processing them. Under these conditions the 'done jobs' would not have been removed until all were done. If you were printing 1000 jobs then you could not submit any new jobs, even though you have done 999 of them... :-) Sigh... these boundary conditions are the pits. Added the 'volatile' option to declarations of static and nonstatic variables updated in signal handlers. You really don't want to hear the frothing about over-enthusiastic optimizing compilers, do you? Ran the Kerberos tests, discovered minor definition problems with krb4_auth.h and Kerberos4 support. Have no way to test this, hope the problem is resolved. The AUTHUSER information received at job submission time was not being stored and used later when printing permissions were checked. (Discovered by: Toby Blake ) Added a 'UTILS/README.ForKerberosHackers' file so that Kerbero Hackers can quickly and brutally set up a test LPRng system. Not for the faint hearted. Carry a dog nummy when you read this stuff... Some users hit themselves in the head and complain about headaches. If the 'lpd_port' value is 0, then checkpc and lpd squawk. (Not telling me who the user was, but reported by: Craig Small ) Version LPRng-3.8.8 - Sat Feb 23 07:35:45 PST 2002 Restored include file functions to lpd.conf. Also put in recursion depth checks so that it will stop if you have a loop. Version LPRng-3.8.7 - Fri Feb 22 12:24:38 PST 2002 Modified the wildcard lookup so that it returns some sane values for defaults, i.e. - '*' is not treated like a real printer and the first 'real' printer is used. Sigh... autoconf, automake, and libtoolize insanity. Each of these facilities has a different version of the config.guess and config.sub files, and will brutally copy them to the distribution directory when you run automake, autoconf, or libtoolize. Problem sort of solved by running through the /usr/local/share/{auto*,libtool} directory and finding latest versions of things. As the CarTalk guys say, "Bo-0H-OH-OH Gus!". Sigh. The 'Service_connection: bad request...' error message now has the IP address of the sender added. (Good idea from: Rainer Tammer ) Makefile.in had the diagnostic options left enabled after regression tests. BAD! Bad Programmer! BAD! No coffee for you today. (Reported by: Petri Kaukasoina among others...) Portability stuff, // comments, and src/Makefile referencing ${SRC}/../UTILS instead of ../UTILS. (Reported by: Hans Peter Verne ) Missing check in lpstat for end of string condition: for( t = Printer_DYN; t && !isspace(cval(t)); ++t ); => for( t = Printer_DYN; !ISNULL(t) && !isspace(cval(t)); ++t ); (Reported by: Villy Kruse ) psbanner was creating a /tmp/before file. (Reported by: Anthony R Iano-Fletcher ) Fixed the 'job done' status message so that it shows the job id. (Suggested by: Christoph Beyer ) Added some sanity checks to handle cases when hold files and control files do not have identifier information in them. Checkpc now checks for duplicate spool directories. Version LPRng-3.8.6 - Fri Feb 8 19:31:52 PST 2002 HF_NAME not getting set when hold file read and it is not in file. This makes updates miserable. (Problem spotted by: Helmut Jarausch ) Fixed typeo in configure where I had unixsocket and unixsocketpath instead of unix_socket and unix_socket_path... (Pointed out by: Craig Small csmall@eye-net.com.au) Modified the host/printer lookup behavior when clients are using 'force_localhost'. You now use the 'original' queue name rather than the 'destination' queue name. Wonder how long this has been there. (Prompted by a problem report from: Andrew Gray" ) Missed a 'AF_UNIX' definition. Now guarded with ifdefs. Corrected LPRngHOWTO accounting information: (Error reported by: "Dirk Krause" ) Example: lpd generates: jobstart - from the lpd.conf 'as=' option jobend - from the lpd.conf 'ae=' option -H - host name -n - user name -P - printer -k - control file name -b - byte count of job/file -t - current printing time -J - Jobname (if present in control file) -C - class (if present in control file) -M - mailname (if present in control file) ifhp filter generates: start/end - of filter, for entire job filestart/fileend - if or other filter, for each file (options above are same) -A - identifier information (if present in control file) -q - process id of filter -p - current value of page counter, 0 indicates no page counter on printer or it is not readable jobstart '-Hh110.private' '-nroot' '-Plp' \ '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:36:36.000' ^^^ bytes in file start '-q26130' '-p105340' '-t2001-10-19-09:36:38.330' \ ^^^^^^^ starting page counter value for job '-Aroot@h110+129' '-nroot' '-Plp' filestart '-q26132' '-p105340' '-t2001-10-19-09:36:38.350' \ ^^^^^^^ starting page counter value for file '-Aroot@h110+129' '-nroot' '-Plp' fileend '-b19' '-T435' '-q26132' '-p105359' '-t2001-10-19-09:43:51.504' ^^^^^^^ ending page countvalue for file ^^^ number of pages printed for this file '-Aroot@h110+129' '-nroot' '-Plp' end '-b19' '-T435' '-q26130' '-p105359' '-t2001-10-19-09:43:51.504' ^^^^^^^ ending page countvalue for job ^^^ number of pages printed for this job '-Aroot@h110+129' '-nroot' '-Plp' jobend '-Hh110.private' '-nroot' '-Plp' \ '-kcfA129h110.private' '-b48780' '-t2001-10-19-09:43:51.000' ^^^ bytes in file Version LPRng-3.8.5 - Tue Jan 22 15:58:46 PST 2002 Added a minor fix to lpq so that it will check all queues. (Courtesy of Jim Trocki ) Version LPRng-3.8.4 - Thu Dec 13 08:25:17 PST 2001 ARGH! ARGH! screwed up lpq -a by forgetting to get the 'all' printer information. Doh! (Spotted by and slapped his forehead by: Patrick Powell ) "Why do we need a TCP/IP port?" quoth the raven, I mean Craig Small . "I have a version that has this facility..." respondeth Patrick ("Mr. Grumpy") Powell. "But I think you will not be happy". I merged the two versions. Be Happy. configure: Added these options --enable-unix_socket (default disabled) --with-unix_socket_path=PATH (default /dev/lprng) /etc/lpd.conf: OPTION TYPE DEFAULT PURPOSE unix_socket FLAG 1 enables/disables the UNIX socket unix_socket_path STR /dev/lprng path to the pipe using this Also: lpd_port = 0 will disable the TCP/IP port lpd -p 0 - disables the TCP/IP port or /etc/lpd.conf lpd_port=0 lpd -P /path - enables, unix socket specified by path or /etc/lpd.conf unix_socket@ lpd -P off - disable unix socket Permissions: Connections to the UNIX socket will appear to come from localhost, (127.0.0.1) port 0. You can use the UNIXSOCKET to check for this condition, or explicitly for localhost/port 0 ACCEPT/REJECT ... UNIXSOCKET Also updated the INSTALL note. checkpc: I was using 'To_daemon()' calls all through the code. This was not needed and would cause a substantial slowdown in operation. I now do exactly ONE call at the start of operations. updated the config.guess and config.sub to the latest version provided by autoconf. Incoming jobs now have a status entry. This is to support IPP and status reporting for incoming jobs. The idea is that you can start transferring a job and then, when the whole job is transferred, the job will be done. To make this happen you need to put an entry in the queue to act as a place holder and reserve the job number for this action. When transfering an IPP job, you can send it in chunks. This now allows the IPP system to send the job header (request), set up the job status, and then the job contents. Just to make life interesting... Found some places where I was using 'sizeof(xxx)' instead of a passed value for an error message buffer. Very short error messages - 3 chars long... :-) LPD now REALLY uses the lock files to prevent multiple instances from running. This might/will/could break on systems that NFS mount their lock directories. Cleaned up the error message about bad print job formats. Clearly there are some REALLY strange printing systems out there. (reported by: Phil Moses ) Checkpc -A XX -r now has nicer format: t1: file 'hfA877', age 24.57 hours > 24.00 hours maximum (Spotted by: (Craig Small) csmall@eye-net.com.au) Added the following to the pass_env options: LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION LC_ALL This should help with LOCALE support. Version LPRng-3.8.3 - Mon Dec 10 20:40:02 PST 2001 Fixed the operation of 'lpr -Pxx' when printcap for xxx has the format: xx:direct:lp=... Sigh... too many special cases... (Pointed out at LISA2001, and fixed on site... Now who was that masked Sysadmin???...) (From the mailing list: James Thomas Klaas ) Removed spurious commas in control file Z options. Configure did not set 'done_jobs_max_age' correctly. (Patch from: Dejan Ilic ) lpc flush now cleans out status as it should have done... GRRR... user pointed this out at LISA 2001... Fixed up a problem with global variable Name. From: Rick Cochran I got LPRng to build under OSX. It required only one patch which seems to be due to the fact that "Name" is declared "extern" all over the place, but is only defined in getopt.c. Since lpstat doesn't use getopt, ld complains. I'm not sure why GNU ld should complain under OSX and not on other platforms. (Patch by: Rick Cochran ) Editted the lpr man page. Updated the information about obsolete options. Updated the installation procedures for FreeBSD, linux, etc. The STANDARD_configuration script now checks to see if there is a /usr/share/man and if so, runs configure with --mandir=/usr/share/man. Man pages now show up in the right place. This was true on *BSD, various LINUX distros, and some versions of SunOS/Solaris. Updated the DISTRIBUTIONS/FreeBSD entry and the postinstall scripts so that the port stuff works better. Now if you do: cd LPRng/DISTRIBUTIONS/FreeBSD* make PREFIX=/usr SYSCONFDIR=/etc You will get the same effect as: cd LPRng sh STANDARD_configuration make clean all install But, as you might suspect, there are some minor gotchas. The man pages usually get installed in /usr/share/man, but when you use the PORT system and override PREFIX it insists on installing them in /usr/man... and various versions of the FreeBSD and OpenPort stuff INSISTS that when generating a port that the originals of the man pages are in the ${PREFIX}/man/manX directories. I gave up and cheated: you get an obnoxious warning to either create /usr/man or to make a symbolic link from to /usr/share/man from /usr/man before installation starts. I know, I know. But I don't have that many brain cells left to fry... Version LPRng-3.8.2 - Mon Dec 3 12:26:52 PST 2001 MAJOR CONFIGURATION CHANGE: LPRng can retain status of last N completed jobs configure --with-done_jobs=N - set done_jobs value, default 1 configure --with-done_jobs_max_age =N - set done_jobs_max_age value, default = 0 (no expiry) Or in the printcap/lpd.conf: :done_jobs=1 :done_jobs_max_age=1 Example: Printer: t1@h110 'Test Printer 1' Queue: no printable jobs in queue Server: no server active Status: job 'cfA231h110.private' removed at 18:25:36.281 Rank Owner/ID Class Job Files Size Time done papowell A 278 /tmp/hi 3 18:25:31 Controlled by: :save_on_error - all jobs with error saved, status not removed :save_when_done - all jobs with no error saved, status not removed :done_jobs=N - last N jobs completed (error or no error) saved :done_jobs_max_age=N - jobs with status older than N seconds removed This is best explained by: On job completion: if( (no error && save_when_done) || (error && save_on_error) || done_jobs > 0 || done_jobs_max_age > 0 ){ do not remove job } When queue updated: if( !(save_on_error || save_when_done) ){ while( done_jobs_max_age >= 0 && the time since completion of oldest done job > done_jobs_max_age ){ remove the oldest done job } while( done_jobs >= 0 && total number of done jobs > done_jobs ){ remove the oldest done job } } Fixed up the order of 'require_explicit_q' in the variable list. Added 'lpd -p port' so that lpd port can be specified at run time. (Suggested by: Chris J. Herbst ) Added 'PrintingCookbook' to the distribution. The 'shorthost' DNS lookup result was not being set correctly if DNS lookup failed and you had to drop back to using IP address. Clearly the shorthost form of IP10.0.0.1 is IP10.0.0.1, not IP10. Added patches to help support Win32 porting using Cygwin: UID 0 is now ROOTUID instead of 0 value. ROOTUID is set by ifdef in portable.h checkpc -f no longer puts out the annoying '/var/run/lpd.515 does not exist' message. List_sep (which is only used in Check_for_rg_group) needs a comma. (Discovered by: Graeme Wood ) Reworked the 'start lpd subprocess' code so that it is a little more civilized. Modified portable.h so that LPRng compiles properly on HPUX 11.xx systems. lpc help fixed up - 'redo - reprints jobs' Cleaned up the 'Make_sort_key' code so it does not do needless malloc. Version LPRng-3.8.1 - Thu Nov 15 16:08:41 PST 2001 The original default actions and values for the LPD_PRINTCAP_PATH have been restored, as it broke too many other things. A work around for the problems with using LPD and database based configuration has been found... ugly, but it works. Chooser also now will wait when it cannot find a queue instead of just exiting. This solves the problem of 'hung' load balance print queues using 'chooser' support. Trim the accounting file information. This now solves the 'mysterious full spool partition' error messages. 'indefinately' is really 'indefinitely' ... so says 'ispell' The 'remove_z' now really removes 'Z' options. (Found by: Ryan Lovett ) The 'require_explicit_q' added for those folks who absolutely require that a queue be specified and do not want them to use a default queue. (Patch to code supplied by: James Thomas Klaas with a little help from Dan Escapa) Grrr... left in a line of code when I was doing some testing of the setuid functions in Win32 and screwed up the setuid stuff. Fixed up a silly problem with file descriptor 0 not bound to /dev/null in lpd subprocesses. Fixed the 'Trim_status_file' routine so that it now treats file descriptor 0 and -1 as 'closed' files. This prevents some silly problems with initialization. Release LPRng 3.8.0 Mon Oct 15 12:09:13 PDT 2001 At line 174 in accounting.c: } else if( safestrncasecmp( s, "hold", 4 ) ){ This should be } else if( !safestrncasecmp( s, "hold", 4 ) ){ otherwise anything send back to lpd from the accounting filter other than accept will result in a JHOLD! (Spotted by: "C. L. McAvaney" ) Added :force_ipaddr_hostname option. This causes the IP address of the remote host to be used for the hostname, overriding the information in the control file. This can be used when you really need the IP address rather than the hostname in the control file. (Needed by: Rick Cochran ) Release LPRng 3.7.9 Mon Oct 15 06:18:43 PDT 2001 Version control strikes again. Sigh... Now all the files are carefully put into place (Fumble fingers by: Patrick Powell ) Release LPRng 3.7.8 Tue Sep 25 12:35:46 PDT 2001 Can't spell... fixed typos in man pages. (Corrections from: Karsten Weiss ) lpd_logger.c - free(sp); s=0 ... this sure does make free() and malloc() unhappy... (Found totally by accident: Patrick Powell ) lpr '-Y' (enable lpr_filter) processing fixed up a bit. Now has better diagnostics and information. An extremely rare but annoying network condition causes LPQ print status to fail. When running as root (setuid root), and doing an LPQ operation, the lpq process will try to bind to a port in the low port range (512 - 1023). This will sometimes fail with a timeout if the port has been recently used and bound to. I have put a bit more 'randomization' into the selection of the port, but there is really nothing that can be done, as the TCP/IP error status does not distinguish between 'connection refused because you just connected from this port' and the remote printer being off line. Sigh... The obvious answer to this is to bind to the low ports only when needed, but this requires users to know when to set the option. I give up. Release LPRng 3.7.7 Fri Sep 14 15:54:48 PDT 2001 checkpc whooped its cookies when running checkpc -f and the device is /dev/null (lp=/dev/null). Apparently I cannot set /dev/null to use blocking IO... Sigh... So I do not count 'changing non-blocking IO to blocking IO' as an error. i8n French Translation (gettext) added. (Supplied by: Francois Mescam ) The files generated by the 'incoming control filter' were not being re-read by the LPRng system. Silly me. (Discovered by: Tuomas Toropainen ) The 'bq_format' option was not being handled correctly for defaults. This option has the value: bq_format=IoIo...D I = original input format (or '*' for wildcard match) o = filter output format D = default (if present), otherwise keep original It now handles the case where no translation is required correctly. (Prompted by a question from: Rainer Tammer ) Did not check to see that I was a client before doing setgroup to daemon. Stupid of me. GRRRR... I now have a test for this in the code. (Warning from: Petri Kaukasoina ) Release LPRng 3.7.6 Fri Sep 7 05:36:00 PDT 2001 There was no call to Getdaemon_group so the default daemon group was 0. This, as they say, was double plus ungood. (Spotted and reported with a cackle of diabolical laughter by: Petri Kaukasoina ) I added a 'half_close' flag so that you can force a 'close(fd)' rather than a 'shutdown(fd,1)' to be done for those problem child network printers that whoop their TCP/IP stacks and die horrible deaths when they get a half closed connection. This is, as they say, a bug in the print server, but I have encountered worse. The same printers also whoop their cookies when reporting status but I don't seem to be doing a half-close on 'lpq' connections so this doesn't seem to be a problem. I have modified the 'lpq' code so it does not do a 'half-close'. Example: lp:lp=host%9100 # happy, well behaved, print spooler box lpb:lp=host%9100:half_close@ # buggy print spooler box Grammar fixed in LPRng-HOWTO. (Red pencil work done by: ) Release LPRng 3.7.5 Sun Sep 2 12:43:39 PDT 2001 I was not closing all open file descriptors. This caused checkpc and lpd (when running as 'spool queue server') to die mysteriously after processing a couple of jobs. (Clue to cause supplied by: Heiko Burghardt ) The lpc -s status only reported number of jobs. Now it also reports queue status, as it used to, and should have. And it reports only the number of printable jobs. (Patch by: Garry Zacheiss ) Patch to accommodate Broken RFC1179 Implemenation #39 from Apple. (Gory details and a patch by: Darius Davis ) The 'Read_fd_len_timeout' and 'Write_fd_len_timeout' code would not pause indefinately if the timeout value was 0. (Noticed by: David E. Cross ) A slew of patches from Crutcher Dunnavant at redhat.com: From the LPRng-3.7.4-23.src.rpm at the RedHat ftp site: LPRng-3.7.4-direct.patch - fixed a typeo in vars.c LPRng-3.7.4-inet_ntop.patch - conflicting/duplicate definition of inet_ntop. NOTE: I also fixed the inet_pton() definition to be consistent with the patch. LPRng-3.7.4-jobfilescan.patch, LPRng-3.7.4-lockfile.patch a little less agressive checkpc operation. Checkpc now does not NOT update the targets of symbolic links. This solves the problem of various tools creating files in the spool directory as well as symbolic links to filters. The FILES need to be accessible by filters running as the LPD user, the targets of the symbolic links should not be touched. LPRng-3.7.4-kerb5.patch - not used, do not want to hardwire paths into configure. Modified RPM config file to add /usr/kerberos/{include,lib} instead LPRng-3.7.4-lockfile.patch - lockfile created now LPRng-3.7.4-manpage.patch - typo in lpr.1 fixed LPRng-3.7.4-nointl.patch - configure using wrong -lintl value. LPRng-3.7.4-nonblock.patch - changed some blocking opens to nonblocking opens in checkpc so that checkpc did not hang. Silly of me not to have done this, as the Check_write() routine even had a nonblocking flag just for this purpose. LPRng-3.7.4-s390.patch, LPRng-3.7.4-setgroups.patch This is a fiddle, not a major problem. The only exploit possible is if the lpd server is started with "extra" groups besides the default one. If you do not install lpd SETUID root (which is the default) then you have to be root to start this (su root OR login as root), and this means that either login or su is not setting up the group membership correctly. But it is better to err on the side of paranoia than be careless. LPRng-3.7.4-shutdown.patch Note: the 'shutdown()' patch was NOT applied as it breaks a slew of other things. Clearly we have some problem printers out there that need to be identified. (Courtesy of: Crutcher Dunnavant ) Updated GETTEXT/i8n support to gettext-0.10.39. The printcap option 'prefix_option_to_option' is declared as a flag in src/common/vars.c in both versions 3.7.4 (line 355) and 3.6.26. { "prefix_option_to_option", 0, FLAG_K, * &Prefix_option_to_option_DYN,0,0}, should be: { "prefix_option_to_option", 0, STRING_K, &Prefix_option_to_option_DYN,0,0}, (From: Anthony R Iano-Fletcher ) Redid the authentication documentation and code... cleaned it up a bit. And comments. And printcap.5 updated, HOWTO updated. Sort of works now. Fixed up '$a' filter options so that :af=xxx is put on command line only if it is NOT a filter. This clears up the mysterious Linux Printfilter deaths. Permission checking now works for SERVICE=X. You can only do remote host and port comparisions (REMOTE_IP=, REMOTE_HOST=, PORT=). This was initiated by a bug report about address mask generation. (From: Willi Burmeister ) 'lpc client' now displays defaults. The changes to use the 'initgroups()' call for setting process group and effective group also cleared up problem reported by some Debian users. You can now put a colon in printcap entry values using: \:. This makes life a little easier for some folks who need to have options of the form "http://...". You can now do: filter=/.../sendftp -d ftp\://some/site The configure defaults for filter_path (PATH value for filters) are now /bin:/usr/bin:/usr/local/bin The configure defaults for filter_ld_path (LD_LIBRARY_PATH value for filters) are now /lib:/usr/lib:/usr/local/lib Reviewed LOTS and LOTS of documentation. Fiddles all over the place. Release LPRng 3.7.4 Wed Dec 27 07:10:27 PST 2000 ARGH ARGH! Distributed the test version and not the release version for 3.7.3 - this has not been a good week. The printcap entry '*:client:rm=IPADDR:force_localhost' now works correctly with lpq -a. Side effect: you do not get status if you do not have a default printer. i.e. - 'lp|*:client:rm=IPADDR' is better. I now kill off process by using SIGHUP, SIGINT, SIGQUIT and SIGCONT. Even Guido thinks this is overkill but expects that there will be some system where even this does not work. Added a check for the VERSION of gdbm as well. ARGH ARGH ARGH... I fixed a problem with signals (SIGINT) killing off the process waiting for a lock on a file descriptor, but I did it wrong. (Pointed out most gleefully, complete with TRUSS output by: Doug Morris AND John Perkins ) Release LPRng 3.7.3 Sun Dec 24 17:47:52 PST 2000 Updated the default printcap file with a simplified set of instructions. There was a 'sleep(1000)' instead of a 'plp_usleep(1000)'. Needless to say, this did slow things down a bit. LPRng HOWTO Section on Samba had 'printcap file' instead of 'printcap name' (Spotted by: Marcel Kunath" ) HPUX compilation without GCC had a gratuitious CFLAGS=-Aa. I removed the flags. (Reported by: Ryan Novosielski ) Release LPRng 3.7.2 Fri Dec 22 10:45:00 PST 2000 Discovered that job moves were not working correctly. Was removing the lpd_port value by mistake. Close_gdbm() was not defined, and the #if HAVE_GDBM_H confused some compilers. (Reported by: Shane Voss ) ifhp.conf got the 'reverse_priority' description wrong. (Proof-reder was: Michael J. Carter ) When I added the user printcap stuff I did not set a return value and the 'tc=' broke. Sigh. (Reported by: gizillions of people, including Michal Kouril ) RFC1179 does not ABSOLUTELY PROHIBIT some print spooler expecting multiple LPQ request. So it does not close the connection after sending status. So I now do a shutdown() to cause it to not expect further commands. (Detective work done by Rainer Tammer ) The 'short_status_date' and 'full_time' options seem to conflict with each other. The 'full_time' means to use full time formats in LPQ status, and the 'short_status_date' means to use short date formats. The 'full_time' option now controls both of these, which is probably what was intended in the first place. (Pointed out by: Bill Kemp ) Get_all_printcap_entries() was not clearing All_line_list so you would get duplicate entries. Solved the 'mystery duplicate printer' problem observed during testing. Natter in the README and INSTALL for Solaris users. Release LPRng 3.7.1 - Tue Nov 28 06:33:32 PST 2000 Major Changes That Effect Backwards Compatibility 1. local printcaps for users - ${HOME}/.printcap This allows users to specify a printcap in their local directories. Of course, you can use the 'user_printcap@' option to disable this. But why bother? 2. job file filtering always enabled The classical 'store and forward' behavior has been changed. If you have a print queue with filters AND you have a file with the format specified for a filter THEN the file is filter and the filtered output is used. This is CONTRADICTORY to 'vintage' BSD and 'legacy' LPRng behavior. If you want to have 'job flattening', that is, to have the job combined into a single file with all the files processed, you need to use 'lpd_bounce'. If you are currently using 'lpd_bounce' you will see no difference in behavior. The bq_format option is used to get the 'new' formats after filtering. Bq_format has the form: OnOnOn...D where O is the original format, n is new format, and D is default if there is the original format is not present. If no default then original is retained. The bq_format default is now 'f', not 'l'. Example: bq_format=f (default) all processed files have 'f' format bq_format=flmf (default) f -> l, m -> f, others unchanged if processed. 3. lpr -k option is now re-enabled to allow lpr to handle pipe input without creating large data files. Note that if you kill programs off then you might end up with a truncated job. You can use: cat | lpr -k OR cat | lpr -k -- - 4. You can now have :lpr= Command Line Options This will prepend the command line option flags to the lpr command. Note that this now allows you to set up a user printcap entry that has command line options suitable for lpr. 5. Super lightweight no spooler printing to devices with filter support. New command line options: -B, -X filter, -Y New printcap option: :direct SEND JOB DIRECTLY TO REMOTE TCP/IP PORT: lpr -Y -Phost%port file1 file2 OR: use :direct flag in printcap In your ${HOME}/.printcap or /etc/printcap file put: lp:direct:lp=h14%9100:remote_support=R:client And use: lpr -Plp file (:direct is effectively the same as -Y) Effectively: ( for i in file1 file2 ; do ${filter} <$i; done ) > h14%9100 where ${filter} is chosen from the printcap entry. Note: if you do not specify a file then this reduces to reading from STDIN, e.g.- ${filter} > h14%9100 NOTE EXTREMELY WELL- for 1 file jobs: The STDOUT of the filter is the TCP/IP port connection. This allows the filter to get status and other information from the remote printer. SEND JOB VIA A PROGRAM (SAMBA smbclient, for example): lpr -Y -P '|/smbclient //server/share' file OR: lp:direct:lp=|/smbclient //server/share:remote_support=R:client lpr -Plp file Effectively: ${filter} temp.$i ; done lpr -Ppr@host temp.file1 temp.file2 ... USER SPECIFIED FILTER: To use a user specified filter: lpr -X filter Example lpr -Y -Phost%port -X userfilter file OR: lp:direct:...:filter=userfilter:client Effectively: cat file | userfilter >host%port NOTE EXTREMELY WELL- for 1 file jobs: The STDOUT of the filter is the TCP/IP port connection. This allows the filter to get status and other information from the remote printer. SPECIAL CASE for lp=queue@host: lpr -X userfilter -Pqueue@host file1 file2 Effectively: send control file; for i in file1 file2 ; do userfilter $i > tempfile send tempfile; done EXTREMELY SPECIAL CASE: -k option The -k option with RFC1179 spooling AND a single file will case the following actions to be taken: send control file send a 'expect BIG file' command cat userfile | filter > server You can also add -X userfilter and get: send control file send a 'expect BIG file' command cat userfile | userfilter > server This is done so that you could run lpr as a filter and send HUGE data files to the printer. This is done by invoking the '0 length file is read to EOF' facility of RFC1179. Unfortunately, this is not supported by all network print spooler boxes, so the 'fakelargefile' option allows you to fake this by sending a very large file number (in K bytes). I suggest using 1000000 - i.e. - a 1 Gigabyte file. Start of a new branch: iNTERNATIONALIZATIOn (i18n) Support Revisted iNTERNATIONALIZATIOn support has been reviewed and incorporated in a much more stable and maintainable manner. Rewrote the ABOUT-NLS.LPRng file. Modified the Makefile to update version information in the po/*.po files as well. Reviewed much of the error message and status messages, and added them to the translation list. Added the N_() facility for 'static' messages and tables. On 4 Sep 2000, a compromise problem with the gettext facility was announced. This was based on the standard 'fprintf' functions, which have a '%n' option to allow values to be written to memory. I have totally eradicated the use of the standard printf, fprintf, and so forth, and use a safe version of snprintf without this capability. This allows LPRng to be used on systems where similar attacks can be launched. In addition, if the executable is running with uid or euid 0 (i.e. - root), then NLSPATH environment variable is unset. This may break some of the 'set process name' code on some systems, but I cannot think of another method that will do this. You can now use FreeBSD/BSDI/ and most likely some other newer versions of the BSD Make in addition to GMake. What a pain this was. If your make supports VPATH it should work. Hopefully. GDBM used to store information. This now makes handling LARGE numbers of files, etc., in a spool queue directory feasible. Needless to say, status generation time is VERY small. There are several caveats on this. If you kill off the lpd server when it is in the middle of updating the database file, you will end up corrupting the database file or having an incomplete one. To resolve this problem, the 'checkpc -f' command can be used, as well as the 'lpc flush' command. Also, the initial queue scan done at system startup will rebuild the databases. IPV6 portability was not quite there. Some minor fiddles. So I stopped playing the violin. Maybe some time in the future. (Fiddling done and patch supplied by: John Perkins ) Fixed the lpq.c status trimming functions to be a little more robust. Also, put back the recursive lpq functionality. (Recursion loss spotted by: Christoph Beyer ) The lpraccnt program is removed from the distribution. The 'monitor' program can be used instead. I wonder why I had two of these in the distribution. The load balance queues are now treated like 'first class' queues and jobs moved to them are treated like incoming jobs. This allows all of the incoming filters to be run, routing to be done, and other abuses far too esoteric to grace these CHANGES notes. This involved doing some very odd things with chdir(), etc. to make sure that the filters would run with the correct directory. Also, status information for load balance queues changed so that you don't get silly messages about non-existent jobs which have been moved to the load balance queue. Fixed up problems when you run out of file space with load balance queues. Fixed up debug and status file information logging with load balance queues. Fixed a really silly design flaw in Setup_printer() that closed the status file just when you did not want it closed - and then truncated it. Debug file is now closed and opened only ONCE during a call to Do_queue(), making it possible to debug the queue service. All in all, a really thorough redoing of the queue handling was necessary to make them into first class citizens. (Motivated by the questions of: Jason Keltz ) lpd now mumbles at you when you try to start it up and it has problems. Of course, most folks do 'lpd >/dev/null 2>&1' but we will ignore them... (Inspired by the well chosen arguments of: and Craig Small ) lpd now CORRECTLY opens output filters - lp=|/path (Spotted by: Seth Chaiklin ) LPRng-HOWTO - Samba example corrected (Correction by: Philippe Weill ) lpd_port=[ipaddr%]port now will cause lpd to bind to the interface with the specified IP address. (Prompted by the whingings of some anonymous Debian user and forwarded by: Craig Small ) checkpc runtime help was wrong. (Spotted by: James P. Dugal ) INSTALL_PREFIX replaced by DESTDIR to be consistent with other distributions and packages. lp -f formname now makes the CLASS information 'formname' as well. (Inspired by: Dave Lovelace ) In LPRng/common/linelist.c, many missing checks for null pointers. (Found in a core dump supplied by: Mike Whitson ) lpr -o option is now the same as lpr -Z option (Suggestion to save sanity of SYSV users by: Joseph Krahn ) lpq did not always have a space before job file size. (Noted by: Jonathan Briggs ) Release LPRng 3.6.26 Fri Oct 13 07:38:38 PDT 2000 unsetenv() is not available on some systems. Fallback to setenv and then putenv() if not present (Found by: Niklas Edmundsson ) Release LPRng 3.6.25 Tue Oct 3 09:19:11 PDT 2000 syslog Compromise - modified syslog to use 'syslog(xx,"%s", msg). gettext Compromise - added the following to Initialize(): if( getuid() == 0 || geteuid() == 0 ) unsetenv("NLSPATH"); IN6_ADDR removed, in fact IPV6 stuff removed. See the various CERT advisories. Sigh... Release LPRng 3.6.24 - Fri Aug 11 08:03:23 PDT 2000 LPRng-HOWTO - added update for Samba print queue configuration. LPRng-HOWTO - added section on how to configure Solaris lp printing to communicate with LPRng. (Changes courtesy of: Gerald Damian ) Typo in gethostinfo.c spotted. (Courtesy of the debugging talents of: Robin Sommer ) And I removed the wrong line so that the data files were not being deleted when a job was completed. Helps to read the control file and get the data file names... (Pointed out by: Thomas Emmel ) There was a 'cut and pasteo' that caused me to use the wrong value to get trim lpq status. (Core dump and clues supplied by: John Perkins ) LPRng HOWTO - added small section on setting up Solaris lp queues to forward jobs to LPRng/BSD printers. IPV6 Support fixed up a bit to actually work... (Spotted during testing, now that we actually have IPV6 working on our router.) Added a 'flush cached status' when a spool server exits. Now you get the correct status when there is no active server. Modified the 'Read_write_timeout' code to be consistent with reading status from parallel port printers the way that the ifhp filter does it. Found a minor sillyness in the 'send_to_logger()' code - I carefully format data and then toss it way. Now I do checks first. Fixed up lpq status generation - only read a small part of the status file for information. Release LPRng 3.6.23 - Fri Aug 11 08:03:23 PDT 2000 The Linux Printing Summit was held from July 27-28, 2000 in San Jose, and was Sponsored by VA Linux. There was an extremely enjoyable interchange of views between all of the various interested factions. You will see some additional changes in LPRng as a result of these meetings and the input from users and developers. Support for status caching has been incorporated in LPRng. In addition, 'spool queue lookup throttling' has been added in order to improve the speed of status gathering. And there are now facilities to control the format of returned status. This is implemented as follows: a) Each queue has a file containing keys corresponding to status queries. For example, if you do 'lpq' then the query key would be "4_" corresponding to the "\004\n" query sent to the server. If you do 'lpq this that' you have the key "4_this_that_" and so forth. b) Corresponding to each query is a file containg the status for the query. If the status is 'stale', that is, older than 'lpq_status_stale' seconds, then the lookup is redone. c) When a job is submitted to a queue, or the status of a job changes, or a control operation is performed on the queue, then the cache is flushed. Currently, this means that the status has to be regenerated for all queries. d) If the queue status was changed less than 'lpq_status_interval' seconds ago, then the cached status (if any) will be used. e) If the process needs to update the print queue, it will attempt to lock the status file. This means that at most one process will be scanning the print queue for status at a time. This has had an extremely good improvement on status reporting, especially under high load conditions and multiple processes attempting to scan the queue. This locking actually improved throughput much to my surprise. A careful analysis showed that by having only one or two processes scanning the directory at a time, the OS was better able to cache and buffer data. In actual fact, the second process would then find the files that it was looking for already in memory or in the buffer cache. Also, if the two processes were getting the same data (lpq -a), the first one would set up the data in the cache and the next one would simply read the cached data. The 'lpc flush' command has been added to flush all of the cached status. This was added for testing and for administrative purposes. A new Super Secret option (well, it is documented now) has has been added to the 'lpq' facility. The following only works with LPRng servers (as of this release, of course): lpq -- -lines=N (in general: lpq -- -opt=v,opt=v) The '-lines=N' is passed directly through to the LPRng lpd server, where used to set the size of the returned status. It is NOT propagated to other servers, BUT it is used to truncate status returned from them. This will effectively give you a VERY compressed status extremely quickly when combined with the caching facility. The -- is used to indicate that the -lines=N is actually an option to be passed through to the server. This capability has been in LPRng, but this is the first documented use of it that will be supported. The addition of this facility has some interesting implications. You can now have a VERY lightweight lpq facility, for getting the status of one printer, if you know the server it is on: echo "\004printer -lines=2 xx xx xx" > nc host 515 (nc is the 'netcat' program written by mudge@avian.org) Of course you do not have authentication, etc., but this is One Of Those Tradeoffs. YOU ARE WARNED: USE THE SOCKET CONNECTION METHOD AT YOUR OWN RISK AND DON'T WHINE WHEN YOU DISCOVER THAT THE LACK OF AUTHENTICATION IS CAUSING YOU PROBLEMS. If this is a problem, use the 'lpq' application and turn on authentication. On the other hand, you can now get printer status WITHOUT the use of an 'lpq' process to format it. I expect the various folks building WebServer interfaces for LPRng print status will be more than happy now, as this works well in a multi-threaded environment, is strictly socket/connection based. Another benifit is that NonLPRng (can you say Microsoft?) based applications can now use the -lines=N entry to select the amount of status that they want returned. This allows remote clients not LPRng based to select the level of verbosity. This work was inspired by the Samba Developers, especially Andrew Tridgell, John Terpstra, and Jeremy Allison, , and their presentations and discussions at the Linux Printing Summit held in San Jose, July 26-31, Sponsored by VALinux. You can now specify a filter for your input files at the user level. This is to support the requirements and/or desires of the various users of print spooling software to have a filter applied at the application end. The syntax is: lpr -X /path file1 file2 equivalent to: for each file in filelist; do tempfile=maketempfile; /path <$file >$tempfile end lpr $tempfile1 $tempfile2 ... The filter is invoked once per job file, on each job file. The options passed to the filter are the usual ones for all LPRng filters. Some will not have any meaning, such as job number, etc., and will not be present or have a '0' value. The filter will run as the user's id, and will not have root capabilities. If this is needed, then the filter must have the capability of acquiring them. This work was inspired by the GIMP Project presentation of Robert Krawitz http://www.tiac.net/users/rlk/ Project lead for The Gimp Print -- http://gimp-print.sourceforge.net at the Linux Printing Summit held in San Jose, July 26-31, Sponsored by VALinux. I ran into problems with the SysV to LPRng option passing. Apparently different versions of SysV printing pass options as S, O, or whathave you values in the control file. The prefix_o_to_z option has been replaced by the more general 'prefix_option_to_option' facililty. This specifies the control file option lines to prefix to a control file option line. For example: prefix_option_to_option=S,O Z will prefix S and O to Z prefix_option_to_option=Z O will prefix Z to O. This now appears to cover all cases, and the LPRng HOWTO has been modified as well. The simple minded 'send mail to user' facility had some problems. I fixed them up, and added a 'sendmail_to_user' flag that allows the facility to be disabled for sending mail to users, but still sends mail to operator. I have also updated the HOWTO with some notes about using this facility. (Patches sent by: Maja Gorecka-Wolniewicz ) Several calls to Print_job(...) assumed that a file will respond with status information, as would a real printer. Not a good assumption. I wonder where my mind is at somedays... The 'Network Grace' timeout should only be used when a server is trying to connect - clients should not have to wait. I have once again changed the checkpc code to be very very very conservative in what it removes from the spool queues. This will make the folks who use netatalk, etc. very happy. The bad news is that files put into these directories by other tools will not get removed. C'est la vie, C'est la guerre... (Patches inpiring the changes sent by: "William R. Knox" ) pclbanner had a stupid typeo left over from debugging. It wrote debugging information out to /tmp/before The 'lpr_bounce' code did not work after the last fix to solve problems with Print_job closing files. Now you can use filters again from lpr. I have added the 'wildcard' print queue names and 'incoming_control_filter' options. Together, they implement a way to put options and other information into the control file when a job is submitted. This method was exploited by Adeel Khurshid while at Fujitsu Network Communications, and is used by the 'apsfilter' by Andreas Klemm and Thomas Bueschgens. Example: lp|lp_*:lp=%P@server lp|lp_*:server :incoming_control_filter=/.../update_z :... When you use lpr -Plp_landscape_ledger you will actually end up sending the job to the lp queue, with the queue name (Q control file line) set to lp_landscape_ledger. This information can be used to update the various control file lines. The LPRng/UTILS/update_z file has an example of a script that will do this. Note that this makes the use of the apsfilter utility even easier. (Inpired by a control filter by: Adeel Khurshid ) I removed a couple of bogus entries that I was putting into the job control file. These appear to be holdovers from some testing. They were put in but never used. Strange, that. The append_z, prefix_z, and other related Z operations are done only when the job is received. This now allows the job to be processed by filters and not have the work undone. sigh. Documentation cleaned up as well. The control file processing has been cleaned up and the redunant and erroneous (sigh) copy of the control file in the job{} data structure has been ruthlessly purged. I sure wish Ruth worked for me, I seem to be doing so much ruthless cleanup. I see the hand of testing and debugging in much of this stuff, and the tracking down of memory leaks as well. You can now use [^x] in the glob patterns. Sigh... The things people do when they get the bit in their teeth. The LPD support for 'lpq' and 'lprm' requests has been modified so that if there are chained queues and each queue is on the server THEN I simply call a routine and do not fork a process. This solves a problem with process exhaustion when somebody had a loop in their printcap. I also put in some tests for this. However, without adding Yet Another Option to the LPRM and LPQ stuff I don't see how I can do it. You can now send up to 'max_jobfiles' (default 52) to the server. Note: you can actually only send 52*52 = 2704 The data files are given names dfAnn -> dfZnn -> dfann -> dfznn -> dgAnn -> dgZnn -> dgann -> dgznn -> dzAnn -> dzZnn -> dzann -> dzznn -> daAnn -> daZnn -> daann -> daznn -> deAnn -> deZnn -> deann -> deznn -> dAAnn -> dAZnn -> dAann -> dAznn -> dZAnn -> dZZnn -> dZann -> dZznn There is now support for the HP extensions: (Courtesy of Richard Hart USG , who sent me the following information) Summary of HP's Extensions to RFC-1179 1. 4-Digit Job Numbers HP preserves the System V-style 4-digit sequence number, or job number, in file names and attributes, while BSD uses 3-digit job numbers. 2. Control and Data File Naming Conventions Control files are named in the following format: cA is the 4-digit sequence number (aka job number). is the originating host name. The data file naming sequence format is: dA through dZ followed by... da through dz followed by... eA through eZ followed by... ea through ez ... etc. ... So the first data file name in a request begins with "dA", the second with "dB", the 27th with "da", the 28th with "db", and so forth. 3. HP-Specific BSD Job Attributes (Control File Lines) The following control file lines are extensions of RFC-1179: R Write to the named login's terminal when the job is complete. This is an alternate to the RFC-1179-style e-mail completion notification. This notification is selected via the lp "-w" option. -- R line -> M line A Specifies the System V-style priority of the request, a single digit from 0-7. -- A value -> priority N B Note that this line begins with an "N", a space, and then a "B". The argument is the banner page title requested via the lp "-t" option. If that option was not given then the argument is null. -- banner -> T banner N O Note that this line begins with an "N", a space, and then an "O". The argument contains the System V-style "-o" options specified in the lp command line. The option names appear without a leading "-o". The first option name begins in the fourth character of the line; each option is separated by a blank. If no "-o" options were given then the argument is null. -- -> appended to Zvalue The following control file lines are generated differently than in standard BSD: J The argument is the System V-style request-ID, for example, "printer-42". Note that leading zeros are not present in the sequence number. If a System V-style title is requested then it is sent using a "N B" attribute, and not the "J" attribute. There is now a new and improved error message for fumble fingers: h4: {1185} % lpq -Pxx Printer: xx@h4 - ERROR: spool queue for 'xx' does not exist on server h4.private non-existent printer or you need to run 'checkpc -f' h4: {1186} % lprm -Pxx ERROR: spool queue for 'xx' does not exist on server h4.private non-existent printer or you need to run 'checkpc -f' h4: {1187} % lpc -Pxx status Printer Printing Spooling Jobs Server Subserver Redirect Status/(Debug) xx@h4: spool queue for 'xx' does not exist on server h4.private non-existent printer or you need to run 'checkpc -f' I hope that this cuts down on the problems reported by people who do not RTFM about 'checkpc -f'. I have added code to track the maximum open file descriptor so that the 'cleanup' code is a little more intelligent. Release LPRng 3.6.22 - Sun Jul 23 17:37:02 PDT 2000 There is yet one more problem with high load levels - I did not set the timeout to reasonable value and the lpd server goes into a tight loop waiting for it. Release LPRng 3.6.21 - Sun Jul 16 16:58:19 PDT 2000 Clean up some Tru64 system warnings about casts. (Supplied by: "Justus J. Addiss" ) Seemed to have found a solution to the parallel port problem by brutally using fstat() to see if we have a device, and if so, then unless it is a tty, assuming that it is a write only device. This is stupid, and I just KNOW that when somebody adds a USB device I will suffer for this. When you have a 'write only' file descriptor, you just do a 'write' with timeout. No select, nothing. Just a write. This seems to solve the problem. Oh yes. You also make sure the file descriptor is non-blocking. (By: Patrick Powell ) There is a bizzare problem with doing select for read on some Solaris systems with certain patch sets on file descriptors that have been set for non-blocking. The select call will actually return and indicate that the device can be read... But when you do, you get -1, and EUNAVAIL or some similar code indicating no data to be read. This is truly bizzare. To ensure that this does not happen, you must do a select on a nonblocking file descriptor. To add injury to insult, this seems to not be reliably reproducible. You really had to be there for this one. I now set all the file descriptors into blocking mode and then do select, then put them in nonblocking mode to do the write or read. The mysterious 'lpc reread' killing lpd was discovered to be caused by trying to free an already freed pointer, which was garbage. This was related to cleaning up the memory leak problem in 3.6.20. Sigh... I cannot spell krbros... krb5... or kb5... and thus cannot invoke the dog in the configuration script. (Happily pointed out by: John Perkins ) Release LPRng 3.6.20 - Sat Jul 8 12:32:38 PDT 2000 One of the silly memory leaks that has been reported, tested for, analyzed, etc., finally was found. The problem was in the child.c file, where I keep track of children processes by dynamically allocating a list. While I carefully cleaned up the list in children of the main LPD process, I never cleaned up the list in the main LPD process. Thus, if you created a large number of children the list would grow a small amount (4 bytes) for each child. This problem was found by brutally using the 'DMALLOC' debugging package, finding every 'malloc' call in the main LPD process and then looking for a matching free call in the main line loop. When one was not found for the case where I had 0 processes I knew that I had found the problem. Sigh. (Stumbled over after staring at the code for a week by: Patrick Powell ) Makefile now checks that POSTINSTALL is 'NO' or 'no' (Noted by: Craig Small ) checkpc -C and checkpc -c file removed. Legacy options and I don't know why they were still there. (Noticed by: Jesper Dangaard Brouer ) The call to 'Remove_tempfile()' routine was removed from the 'cleanup()' when trying to find the above mentioned memory leak and was not put back. Bad Coder! Bad! (Found by: A Earle ) The pclbanner and psbanner had some errors that showed up under bash. Very odd that the ksh and /bin/sh did not whoop on them. (Clever debugging by: David Livingstone ) checkpc -r -A was a little too agressive and it blew away all sorts of files. The -r now only works on job files. I do NOT remove job files unless the -r -A age options are given. This prevents some problems with jobs being moved into a queue just as checkpc is being run from cron. Sigh... Cron. I forgot all about Cron. (Noticed by: Craig Small ) Release LPRng 3.6.19 - Sun Jun 25 11:13:35 PDT 2000 The filter status was not getting used correctly. This was a side effect of trying to clean up aborted jobs and accounting. One step forward, one step back. Sigh. The Tru64 compiler objects to casting pointers to ints, so we have to cast to a long THEN to an int. (Reported by: Justus J. Addiss ) Did not update the 'Tempfile' variable when I was checking multiple print queues. This meant that it was using a stale queue name. Only shows up if the queue directories are on different file systems. (Spotted by the eagle eyes of: Robin Sommer ) Apparently the CHANGES file had 'z_append' instead of 'append_z'. So it is changed. Do we need a Meta-CHANGES file to record changes to the CHANGES file? (Caused by the readings of: Michael J. Carter ) Release LPRng 3.6.18 - Mon Jun 19 09:37:04 PDT 2000 The UTILS/accounting.pl script did not handle malformed lines caused by truncation well. It now does, but insists that you have lines starting with start, filestart, end, fileend for status. This ties into ifhp-3.6.15 Updated the DISTRIBUTIONS/FreeBSD to make the port correctly Updated the DISTRIBUTIONS/RPM to make the port correctly Changed the psbanner font to a more readable font (Artistic criticsm by: Bodo Moeller ) Lowercased DNS lookup return values. (Need discovered by: Alf Wachsmann ) Tru64 cc compiler whoops its cookies on void * conversions... (Reported by: Justus J. Addiss ) Release LPRng 3.6.17 - Sat Jun 17 15:58:21 PDT 2000 Analysis of the Setuid Compromise for LINUX done; LPRng is only susceptible if a non-root user manages to run a client program that in turn runs a program that she has compromised. Since the programs run by LPRng and other servers should owned by root and not writable, this would require the compromiser to have already modified these - by alreadying having root perms. This means that they have already compromised the system. Replaced the agressive 'check at all times and costs' with a) a configure time check for the 'bad linux kernel' b) a run time check done only by clients for a compromise. c) not installing LPD setuid ROOT so that it cannot be started and used as a compromised process. Release LPRng 3.6.16 - Thu Jun 8 15:24:37 PDT 2000 Long numbers and the silly 'is this really and IP address code' conflicted. Fixed it again. (Spotted and reported 32 minutes after the release was out by: Thomas Vogt ) Did not check for null pointer, the following printcap was not read correctly: .junk: stuff:tc=.junk <- ummm... nothing there, CRASH (Spotted and reported 30 minutes after the release was out by: Justus Addiss ) Changed :as and :ae checks so that you can use :as=/path as well as :as=|/path (Inspired by comments from: Sree Lakshmi ) pclbanner did not work under RedHat. (Spotted by: David Kerr Livingstone ) Goofs in the HOWTO spotted. (Spotted by: Zanferrari Domenico ) Updated the HOWTO format. Now using DocBook to generate output. RPM packages not generated correctly If the -Dxxx option is the VERY FIRST on the command line, then you set up the debug options very early in the parsing and operation. This can lead to a GREAT deal of rubbish unless you need it. Release LPRng 3.6.15 Thu Jun 8 15:24:37 PDT 2000 postinstall.generic.sh was sytactically incorrect. (Patch by: Justus Addiss ) RPM Fixes: /usr/docs/LPRng now removed Linux (and possibly other) SETUID BUG compromise detection added. The setuid(n) call is supposed to be a one-way trip to uid n, but this can be compromised by users setting flags. Present in kernels before 2.2.16, and possibly other capabilities based systems. Added a test to make sure that this is really a one-way trip. As far as I can tell, this would only be an issue if the user had a shell script that was executed by LPRng and the script could be replaced by something else. This is possible in systems which are using NFS - I have exercised the compromise and it exists. Release LPRng 3.6.14 Sat May 6 08:46:26 PDT 2000 configure now has --with-lockfile=path. (Courtesy of: Willi Burmeister ) Complete configure options are now: --with-cc=COMPILER select compiler to use --with-ccopts=CFLAGS select compiler command line options --with-linker=LINKER select linker to use --with-ldopts=LDFLAGS select linker command line options --with-cppopts=CPPFLAGS select compiler preprocessor command line options --disable-setuid disable setuid root client and server executables --enable-priv_ports require connections to be from privileged ports --disable-force_localhost force_localhost default to disabled --disable-require_configfiles client programs require lpd.conf, printcap --enable-kerberos enable kerberos support --enable-mit_kerberos4 enable MIT Kerberos 4 support --disable-kerberos_checks disable kerberos library location and checking for support --with-lpddir=DIR lpd executable directory (default ${sbindir}) --with-lpd_conf_path=PATH path of lpd.conf (default: ${sysconfdir}/lpd.conf) --with-lpd_perms_path=PATH path of lpd.perms (default: ${sysconfdir}/lpd.perms) --with-printcap_path=PATH path of printcap (default ${sysconfdir}/printcap) --with-lpd_printcap_path=PATH path of lpd_printcap (default ${sysconfdir}/lpd_printcap) --with-lockfile=PATH lockfile PATH, default /var/run/lpd --with-ld_libary_path=PATH LD_LIBRARY_PATH value --with-filter_path=PATH filter PATH value --with-userid=NAME run LPRng software as this userid, default daemon --with-groupid=NAME run LPRng software as this groupid, default daemon --with-chooser_routine=NAME load balance queue chooser routine name in user object file --with-order_routine=NAME queue order routine name in user object file --with-user_objs=NAME user specified object file --with-user_include=NAME include file with function prototypes for user object file --with-filterdir=DIR filter directory (default ${libexecdir}/filters) --disable-strip disable stripping binaries by default --enable-nls use Native Language Support --with-included-gettext use the GNU gettext library included here --with-catgets use catgets functions if available Terminal clearing now done by using 'clear' program. Configure will look for a clear program and LPQ will fork and exec it. If no clear, then simply send a '^L' or '\014' (form feed) to the stdout. This is due to the horrible support in most OS's for curses, termlib, termcap, term... well, you get the idea. For a true trip through hell, read the configure script for 'vim' and see what they do. Not for me, when this is only a VERY small part of a much larger system. (Changed after finding curses, ncurses, and sys5 curses on a system by: Patrick Powell ) Makefile.bsd is now a VERY small makefile: # List the things you want to generate: all clean install uninstall: gmake $(MAKEFLAGS) $@ I know that some of the BSD folks will hate me for this, but I have decided that trying to support both types of Makefiles and making them work was just too much effort. Also, the BSD folks now have much better supporort for Gmake in their build scripts. Also, see below... Enhanced Install and Package Creation Support. Enhanced Install and Package Creation Support (Laid at the feet of: Craig Small ) One of the problems that is encountered when trying to build a package or do an install is to compile stuff in one directory and then install it in another. The trouble is, you want to install it in a MIRROR directory. For example, you have ${SYSTEMSRC}=/private/src, where the source is, ${BUILD}=/var/tmp/BUILD/ where you are going to build all the stuff, ${MIRROR}=/var/tmp/MIRROR where you want to place what you created The following is generally what is done during distribution creation to do this: cd ${BUILD}/.../LPRng; ${SYSTEMSRC}/.../LPRng/configure --prefix=/usr/local --sysconfdir=/etc make make install XX=${MIRROR} -> puts thing in ${MIRROR}/usr/local ${MIRROR}/etc After trying 9 (nine) different variations on a theme, I now have the following method to do this: make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO What is this? The install script/steps will install files in ${INSTALL_PREFIX}${prefix}, ${INSTALL_PREFIX}${sbindir}, etc. etc., where ${prefix}, ${sbindir}, etc, are hardwired by the configure step to the /usr/local/, etc. Now you might wonder why this is done. The reason is that GMAKE, bless its little heart, will use the $PREFIX environment variable value if it is set. So you cannot do ${PREFIX}/${sysconfdir} in install scripts, and if you do not set it on the command line, have it put in the right place. The POSTINSTALL=NO is used to suppress 'true' postinstallation stuff that would copy files into 'unexepect' places, such as '/etc/printcap' or '/etc/lpd.perms' or '/etc/lpd.conf'. Now if you are building a system distribution for raw install, then you want this to be done, and you would use: make install INSTALL_PREFIX=${MIRROR} If you are building, say a FreeBSD 'package' distribution or a RedHat RPM then you would use: make install INSTALL_PREFIX=${MIRROR} POSTINSTALL=NO Now for all of you who want to make a package and need to find the files that LPRng will install, I suggest you look at the following: INSTALL_PREFIX=/var/tmp/LPRng #note that you do NOT export this ( cd $INSTALL_PREFIX; mkdir usr/local/bin usr/local/sbin /usr/local/libexec /etc /usr/local/etc/rc.d .... ) make; make install INSTALL_PREFIX=${INSTALL_PREFIX} (cd $INSTALL_PREFIX; find . -type f | sed -e '/man[0-9]/d' \ -e '/\/info\//'d -e 's/..//' >/tmp/files find . -type f | sed -n -e '/man[0-9]/s,.*man[0-9]/,,p' \ -e 's/..//' >/tmp/manpages You can now find the non-doc files, manpages, etc. etc. etc. and then update the various locations as you need. Clearly this should be done only as root, on a system where you do not have other users running, where somebody cannot do 'ln -s /etc/passwd /tmp/manpages' and so forth. For a truly abusive use of this method, look at the DISTRIBUTIONS/FreeBSD* and DISTRIBUTIONS/Solaris* directories. Yes, I have no shame. (Put into the distribution after telling people 5 times how to use this by: Patrick Powell ) lpr -U option did not work correctly when UID was root. (Patch happily submitted after a long search by: Roberto Togneri ) lpd was mangling jobs with more than 26 files - caseless compare strikes again. (Found with great consternation by: Peter Scheurer ) permissions and filters: When you use a filter for "perms_path" was not executed when a connection to the lpd is made. So there are no rules then and the result of the permission check simply is the default_permission (and it results in having no rules for the 'R'-check as well) By convention, a line containing the name of the printer for which permission is wanted. Now a blank line is written for 'X' rules. Added capability of filter getting permissions to Setup_printer(). (Found by: Robin Sommer ) lpd_jobs: race condition eliminated at the cost of a high system overhead when multiple jobs are spooled to the same queue. (Inspired by: Shawna Chase" ) client connections on Solaris 2.5 systems fail with EADDRNOTAVAIL, and need a 'retry'. Alternative is to use non-priveledged port. (Found by: Peter A. Harris ) innetgr() needs FQDN on some systems, and 'shorthost' on others. Added check to do both. (Reminded by: Robin Sommer ) syslog messages not working. May need to add 'ordering' test to configure for level comparison. (Noticed by: Jurgen Northe ) RFC1179 transfer failures to remote spool queue did not do retries correctly. The 'JFAIL' status was treated as a permanent failure, not a temporary. The 'Service_printer' code now uses the number of send attempts to do a retry and backoff on transfer times: configuration and/or printcap options: send_try: maximum number of times to send to remote (0 = infinite) - default 3 connect_grace: minumum time between attempts - default 0 connect_interval: interval between attempts - default 10 sec max_connect_interval: maximum time to wait - default 60 sec if( attempt > 0 && max_connect_interval > 0 ){ n = connect_interval * (1 << (attempt-1)) + connect_grace; if( n > max_connect_interval ) n = max_connect_interval; sleep(n); } (Discovered by: Christof Drescher ) Default filter options were missing '$b'. (Pointed out by: Jose Carlos Rodrigues Lopes ) The md5 authentication support did not return back 'error' status for lpr operations. (Noticed by: Patrick O'Brien ) The 'IS_OS' macros are now set to the OSVERSION; this makes tests like #if defined(IS_BSDI) && IS_BSDI > 401 possible. Sigh... The filter_path (PATH environment value for filters) added /usr/contrib/bin (Suggested by: Jeffrey C Honig ) UTILS directory needs to be part of the global 'make' so that tools are created with the right paths. (Discovered when fixing a problem found by: Jeffrey C Honig ) check_for_nonprintable default is now OFF due to 85 distinct problems reported by various users. (Email that broke the camel's back sent by: John Hawley ) lp -s was printing status. (Discovered and fix by: Mark.Belton@mgc.com.au) proctitle() code was mangling the envp[] - this only showed up if you happened to set debug level 6 or higher. (Discovered by: Vincent Fox ) Microsoft now sends the IP address as part of the control and data file names. OK. We can handle that. (Pointed out by: Rainer Schoepf ) When using a routing filter, the DATAFILES environment variable contains the data files. The routing filter can modify the datafiles, but cannot remove them or truncat them. The default for bq_format is now 'f' - i.e. - you can reprocess outputs of bounce queues. The old default was l (binary), which was not processable. The 'lpq -s ID' command was not reporting information correctly. It always reported the total printable, not the ones selected by the options. (Discovered by: Patrick Powell ) Retested Kerberos 5 and Kerberos4 stuff with Kerberos 1.1.1, found problems with compilation, fixed them. (Helped by: Mike Whitson ) Updated Version and Copyright information. Added configure --enable-kerberos option for folks who need to build 'non-exportable' binaries. Added a '$(INSTALL_PREFIX) entry to the install scripts to allow folks who want to install the binaries in a different subtree to do so. I might make this 'PREFIX' to fit in better with feedback. More fixing of Kerberos stuff - fixed up the problems with different uses of krb5_xfree. Added tests for the krb4des library. (Helped by: Mike Whitson ) The spool_file_perms option was not being used to set permissions for files in the spool directory. Noted in the Debian LINUX bugs list. It was also noted that the user was trying to set some very odd permissions that would result in a possible security loophole, but Hey! I just do LPRng... Users (not the LPD server) use 0600 permissions, just to avoid those nasty security problems. Nit pick on man pages: SEE ALSO should not reference same man page. (Submitted by: Debian Linux Bug List) checkpc now checks for server printcap entries with lp=xxx and rm=yyy values. This way you at least warn the users when they screw up. (Good suggestion by: Craig Small ) Moved tests for 'setproctitle' in configure around to deal with some problems of libraries being included when they should not have been. Fixed up the distclean. Removed junk files. Move the LPRng_DOCS into the HOWTO, as there were no other files left. Fixed permissions. Did some fiddling to add easier FreeBSD/NetBSD etc. support. Side effect was that testing install is easier. Added a 'INSTALL_PREFIX' to the installation paths that allows me to make sure that things go to the right places. Move the various distribution specific information into DISTRIBUTIONS directory. Made the LPRng and ifhp configure.in mainly identical. Also use the same portable.h file. Fixed (once again) typeos in the man pages, and the installation of compressed man pages. Sigh... Added a 'filter_stderr_to_status_file' flag that causes print filter errors to be written to the status file (:ps=file) rather than to the status log file. Also added truncation of the status file. (Inspired by : "William D. Colburn (aka Schlake)" ) Discovered, as a result of testing the 'filter_stderr_to_status_file' flag that backslash '\' escapes were not being handled correctly on the filter line. Fixed this. If a filter has <,>,;, or | in it, or starts with ( then it is executed by using: :if=/.../filter xxx -> /bin/sh -c '/.../filter xxx' This allows you to do things like '/.../filter 2>>status' Updated checkpc to check for matching () for filters. Modified the src/linksupport/connection() code so that the lpq and other clients do not try binding to port 515. This can cause problems when used with Samba. The code in linksupport.c that set SO_REUSEADDR and SO_KEEPALIVE was also tidied up. lpc -a now works sort of correctly and the documentation has been changed to reflect it. The LPC=xx permissions checking did not require a 'C' operation. Also, cleaned up some message printing. Make_passthrough was examined and a couple of changes made to handling the case when the filter path contained a meta character. The path now has parenthesis put around it. By default, this form of invocation does NOT have options passed to it. Added a '$*' parameter to provide all the default command line options. This now allows you to do: :if=(/some/path $* | output filter) New functionality: remove_z, prefix_z, and append_z (Inspired by a comment by: Richard Kaszeta ) remove_z=pattern,pattern,... remove the -Z option specified by the pattern. Example: -Ztest,this,thing + remove_z=th*,out -> -Ztest append_z=option,option,... appends this to the -Z options Example: -Ztest + append_z=landscape -> -Ztest,landscape prefix_z=option,option,... prefixes this to the -Z options Example: -Ztest + prefix_z=landscape -> -Zlandscape,test Example of use: You want to have a set of queues where you can have the queue set the functionality: landscape:append_z=landscape:lp=remote@host portrait:append_z=portrait:lp=remote@host lpr will add these options before the job is sent. OR you have a 'bounce queue' situation where you want to add -Z options as the job goes through: portrait:append_z=portrait :lp=remote@host:server lpd will put these options into the job file ON RECEPTION. Also, before sending to a remote queue as well. Kinda bombproof, but covers most situations. If you have force_localhost then you want to connect to the server with the primary name of the printcap entry. The clients were using the lp=pr@remote pr value instead. CONFIGURATION OPTION: ld_library_path and filter_path you can set these values through configure. Portability Support: DISTRIBUTION directory and init files Put the init scripts for various OS's in the main directory. This helps the poor administrator who is trying to figure out what init script he needs. Gathered up all of the various system dependency stuff and put it in one big directory. Fixed up the DISTRIBUTION/Solaris.pkg stuff The 'subserver' queue management now works. The problem was that the main queue server process had to fork a subserver process for the subserver queue, and it could not tell that the subserver queue had been changed. The following solved this: a) in the lpd_control.c code, if the queue is a subserver queue, 1. I set a 'changed' flag in the spool control file. 2. I send a SIGUSR1 signal to the process that is the server for the subserver queue. 3. If that signal is unsuccessful, then I send a SIGUSR1 signal to the main queue process. 4. If that signal is unsuccessful I restart the server b) in the lpd_jobs.c code, in the Process_jobs() routine: 1. I check to see if this queue has subservers, and then check the subserver queues. If the 'changed' flag was set or some other reason exists to start the subserver, I start a subserver process. 2. In the main queues 'wait for work' loop, when I get a 'SIGUSR1' I scan the subserver queues and check to see if their 'changed' flag is set. If it is set AND there is no subserver process THEN I will start a server process. Otherwise I wait until the subserver process exits. 3. In the main queues 'wait for work' loop, when I look for a free subserver queue to use AND I find one which is available AND it has a change flag set THEN I start a subserver process. As you suspect, this was NOT a simple set of changes. (Painfully debugged by: Patrick Powell ) Kerberos Fix From MIT: added auth=none support, and allow default principal lookup. (Patch by: Robert A Basch ) FreeBSD port/package support, Solaris pkg support, RPM (RedHat) Support The configuration, build, and install process has been modified to better support package generation. (I know, it is a dirty business and I am trying to make it easier for the vendors.) I have been driven to this by problems that people have with installing stuff for the first time, and the rising level of 'Did not RTFM'. a) postinstall script selection The last step of the make install process is to find a 'postinstall' file and execute it. The file is chosen by looking in the configuration directory for a suitable file. The file is found by using the 'OSNAME' value found by the configure script. Linux is a special case - mainly because I tested several versions and found that they had different 'linux-this' and 'linux-that' suffixes. I also locate a 'preremove' script and do the same selection. There is a default 'postinstall' and 'preremove' script as well. OSNAME=${OSNAME}; case "$${OSNAME}" in *linux* ) OSNAME=linux;; esac; \ echo "OSNAME orig $(OSNAME) '$${OSNAME}'"; \ s=`ls postinstall.$${OSNAME} 2>/dev/null`; \ echo POSTINSTALL "'$$s'"; \ if test -n "$$s" ; then cp $$s postinstall; fi; \ s=`ls preremove.$${OSNAME} 2>/dev/null`; \ echo PREREMOVE "'$$s'"; \ if test -n "$$s" ; then cp $$s preremove; fi; b) postinstall script execution If the POSTINSTALL option is not NO, then I execute the postinstall script as the last step of the 'install' process: if [ "${POSTINSTALL}" != "NO" ] ; then MAKEINSTALL=YES INSTALL_PREFIX=$(INSTALL_PREFIX) $(SHELL) postinstall ; fi; Note that the 'MAKEINSTALL' environment variable is set to YES. This can be used to determine that the postinstall script is being executed by the 'make install' step. c) "pseudo root" or "PREFIX" support I have put a "${INSTALL_PREFIX}" variable at all points where a normal script would have a target. Thus if you do: mkdir /var/tmp/LPRng-root make install INSTALL_PREFIX=/var/tmp/LPRng-root you will find that all of the files are now put in sub directories of /var/tmp/LPRng-root. You can now do: (cd /var/tmp/root; find . -type f -ls ) >/tmp/files (cd /var/tmp/root; find . -type d -ls ) >/tmp/directories cat /tmp/files | grep 'man[0-9]' >/tmp/manpages cat /tmp/files | grep '/doc' >/tmp/doc and so forth. Your Imagination and Creativityy Ma Vary (YIACMV). It is left as an exercise for the student on how to use this with their favorite (Ummm... ok - least hated) package method to generate a %files, pkg/PLIST, packinglist, etc. etc., for use in package generation. d) sample 'init', 'preremove', and 'postinstall' scripts. I have ruthlessly taken example scripts for FreeBSD, BSDI, and RedHat Linux and put them in the root directory so that people can see these scripts. e) If you want to see how to use these, look in the DISTRIBUTIONS directory. Here is the postinstall.freebsd.sh : - comments are marked with *** .... # FreeBSD Convenience Script for Source Install # -- START -- # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp # # If you are building a PORT, see the # DISTRIBUTIONS/Freebsd directory for a complete port # building package. # # This is the shell script that does the postinstall # dynamic fixup # It needs to be massaged with the information for # various paths. # If you are building a package, then you do NOT want # to have this executed - it will put the sample files # in place. You need to do this during the postinstall # step in the package installation. # echo RUNNING postinstall.freebsd.sh PACKAGE="$PACKAGE" MAKEINSTALL="$MAKEINSTALL" PREFIX="$PREFIX" cwd `pwd` **** you can remove this, but it sure helps when you are trying to **** figure out what is happening. **** - fix is used to put the /etc/lpd.conf, /etc/lpd.perms, and /etc/printcap **** or their variants into place. This is truly ugly, as there is **** no easy way to do this well. You first assume that you will have at **** build time a file with the name 'lpd.conf' (for example) in the **** current directory. If you have this, then you copy it brutally to **** the destination, $TARGET/lpd.conf.sample and, if there is not an existing **** $TARGET/lpd.conf file. **** **** Now we get into some ugly stuff. **** **** When doing a package install, you will want to copy the package version's **** of this file into the same place. But we do not want to overwrite the **** existing lpd.conf, as it will break existing printing. Note that this **** is exactly what happens with RPM - it clobbers the existing config file, **** and widdles by telling you about it. Right. Who reads all of the rpm output? **** **** So here is what we do. We will force a package to have only the **** lpd.conf.sample file, and we will COPY it to the right destination. **** **** The FreeBSD port/package system functions by having a pkg/PLIST file **** that contains all of the files we will put in the package. If you have **** done 'make install INSTALL_PREFIX=/var/tmp/LPRng' you will get all the **** files installed in the /var/tmp/LPRng, and now can simply use file to **** list them. For an example, see DISTRIBUTIONS/FreeBSD/Makefile and **** the 'make plist' target. I call this a 'chroot' image, cause it is **** (hopefully) the same as though you did a 'chroot' to the $INSTALL_PREFIX **** directory. **** **** Unfortunately, this simple picture breaks down when somebody decides **** to use the 'PREFIX' facility of the package/port installation facilty. **** So we add yet another wrinkle to this. Use: **** 'make install INSTALL_PREFIX=/var/tmp/LPRng PACKAGE=YES' **** when you are generating a 'chroot' image. Then you test for this in the **** script and put things in a nice place when you are making a package, **** and then forcefully reinstall them. fix () { v=`echo $1 | sed -e 's/[:;].*//'`; p=`echo $2 | sed -e 's/[:;].*//'`; d=`dirname $p`; if expr "$p" : "|" >/dev/null; then echo "$v destination is filter - '$p'" exit 0; fi echo "Checking for $p in $d" if [ ! -d "$d" ] ; then echo "Directory $d does not exist!" mkdir -p $d fi if [ -f $v.sample ] ; then if [ $v.sample != $p.sample ] ; then cp $v.sample $p.sample; fi elif [ -f $v ] ; then if [ $v != $p.sample ] ; then cp $v $p.sample; fi else echo "Do not have $v.sample or $v" fi if [ ! -f $p.sample ] ; then echo "Do not have $p.sample" elif [ ! -f $p ] ; then cp $p.sample $p; chmod 644 $p; fi; } # we use the /usr/local/etc/rc.d method to start lpd echo "Installing configuration files, cwd " `pwd` # we have to take them from one place and put in another if [ "X$PACKAGE" = "XYES" ] ; then # we put files into the destination **** when we make a package, we need to put the files in the **** ${PREFIX}/.... location to be FreeBSD standards compatible fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms" fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf" fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap" init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh echo "Setting up init script $init using init.freebsd" if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi; cp init.freebsd $init elif [ "X$MAKEINSTALL" = "XYES" ] ; then **** OK, now we are doing a make install - this could be a **** real install by the user, or the deadly 'make install' **** done by the port package Makefile generation. But **** we know what to do: install it in BOTH places. This will **** always end up with a copy in .../lpd.perms, and perhaps **** an extra copy as well in perhaps /usr/local/etc/lpd.perms fix lpd.perms "${INSTALL_PREFIX}${PREFIX}/etc/lpd.perms" fix lpd.conf "${INSTALL_PREFIX}${PREFIX}/etc/lpd.conf" fix printcap "${INSTALL_PREFIX}${PREFIX}/etc/printcap" fix lpd.perms "${INSTALL_PREFIX}${LPD_PERMS_PATH}" fix lpd.conf "${INSTALL_PREFIX}${LPD_CONF_PATH}" fix printcap "${INSTALL_PREFIX}${PRINTCAP_PATH}" init=${INSTALL_PREFIX}${PREFIX}/etc/rc.d/lprng.sh echo "Setting up init script $init using init.freebsd" if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi; cp init.freebsd $init chmod 744 $init echo "Stopping LPD" pid=`cat ${LOCKFILE}* 2>/dev/null`; if [ -n "$pid" ] ; then kill -INT "$pid" 2>/dev/null; fi if [ -n "${KILLALL}" ] ; then ${KILLALL} 2>/dev/null; fi # check the printcap information echo "Checking Printcap Info and fixing permissions" ${SBINDIR}/checkpc -f # restart the server echo "Restarting server" sh $init start else **** OK, this is done when we do a package install. You will **** be amazed to discover that the ./etc/lpd.perms file is now **** present here - so you can install this. Gahh... The reason **** for this seems to lie with the way that the package/port **** mechanism works. If this is changed, then it is back to the **** trenches to find out where and if the file location has **** changed. # when doing an install from a package we get the file from the package if [ -f etc/lpd.perms.sample ] ; then fix etc/lpd.perms "${LPD_PERMS_PATH}" fix etc/lpd.conf "${LPD_CONF_PATH}" fix etc/printcap "${PRINTCAP_PATH}" init=etc/rc.d/lprng.sh echo "Checking init script $init" if [ ! -f $init ] ; then echo "WARNING: $init missing!" exit 1 fi; cp $init /usr/local/$init chmod 744 $init else echo "WARNING: configuration files missing from package!" fi fi Here is the postinstall.linux.sh: # LINUX/RedHat Source Installation Convenience Script # -- START -- # CHANGES,v 1.1 2001/08/21 20:33:14 root Exp *** same as above fix () { *** same as above } echo "Installing configuration files" init=${INSTALL_PREFIX}/etc/rc.d/init.d/lprng if [ "X$MAKEINSTALL" = "XYES" ] ; then if [ ! -d `dirname $init` ] ; then mkdir -p `dirname $init ` ; fi; cp init.linux $init; chmod 744 $init fix lpd.perms "${LPD_PERMS_PATH}" fix lpd.conf "${LPD_CONF_PATH}" fix printcap "${PRINTCAP_PATH}" else *** this is tricky .... fix "${LPD_PERMS_PATH}" "${LPD_PERMS_PATH}" fix "${LPD_CONF_PATH}" "${LPD_CONF_PATH}" fix "${PRINTCAP_PATH}" "${PRINTCAP_PATH}" fi if [ "X$PACKAGE" != "XYES" ] ; then echo "Configuring startup scripts" if [ ! -f $init ] ; then echo "Missing $init"; fi if [ -f /etc/redhat-release -a -f /sbin/chkconfig ] ; then echo "RedHat Linux - running chkconfig" /sbin/chkconfig --del lpr /sbin/chkconfig --add lprng echo "Starting Printer" sh $init start else echo "Hand install the configuration files" fi; fi; Cleaned up the 'Make_passthrough' use by having a single 'Filter_file' routine. Problems of unclosed file descriptors disappeared. Sigh... Discovered that the 'generate banner' code was not working, and has probably not worked since 3.5.4. Shows how many people use this. Fixed. Discovered that the 'af=|/...' option caused 'orphaned' children which would hang around until the main lpd server process exited. Problem unsolvable on the systems where the problem exits. The :as and :ae provide better functionality for this case. If you have an OF filter and one of the other filters dies, then you invoke the final OF filter, even though the job will exit with an error. This allows you to do some cleanup in the OF filter. Implemented by modifying the common/printjob.c code so that it did a 'goto end_of_job' rather than 'goto error'. I wonder why I did not see this before. Fixed a really dumb idiot problem with portability. I simply do not allow lp=|/filter on systems without the 'socketpair' function. Sigh... There must be a way around this but I can't see one. Added a 'JSUSP' to the error codes. Sigh... Needed this to indicate that a filter had suspended itself correctly. Check the size of the status file before writing - this adds one fstat() call per write, but you don't update the status file very often. (Pointed out when his status file filled up the /var spool directory by: Dmitry Bely ) We don't steal, we borrow: the :sh flag in the printcap causes lpr to act like the -h (no header) flag was present. (Showing the tattered edges from cutting it out of the the FreeBSD lpr code, sent by: Garance A Drosihn ) pclbanner and psbanner now back in /bin/sh. Sigh. Some supported systems do not have Perl. (Grudgingly ported to /bin/sh scripts by: Patrick Powell ) The printcap 'x:' is now a real printcap. You use the default entry values for it. Strange how this one did not get caught earlier. The 'lpc client x' and 'lpc server x' now looks up the wildcard as well as the normal information. And finally, checkpc will squawk if you try to use a wildcard as a queue name, rather than an alias. You can now do run time load balancing using user specified program OR a built in filter. Printcap/configuration option: chooser=/path/to/program STDIN = list of queues to choose from, one per line STDOUT = single queue to use (if none, job is skipped) exit code: == 0 handle job and put it into specified queue if any != 0 treat job as though error code was returned for processing. Allows job to be held, etc. chooser_routine chooser_routine@ - default - do not use chooser routine chooser_routine - use chooser routine configure --with-chooser_routine=name --with-user_objs=objectfile.o defines the CHOOSER_ROUTINE compilation option to name includes the objectfile.o in the library. routine usage is described in common/user_objs.c Now you can have a very optimized routine that will do all sorts of horrible things. Enjoy. You can now do queue ordering using a user provided routine order_routine order_routine@ - default - do not use order routine order_routine - use order routine configure --with-order_routine=name --with-user_objs=objectfile.o defines the CHOOSER_ROUTINE compilation option to name includes the objectfile.o in the library. routine usage is described in common/user_objs.c Now you can have a very optimized routine that will do all sorts of horrible things. Enjoy. Note that the overhead for a filter was horribly high and I could not come up with a clean interface. Besides, if you are mucking around with this stuff, you better make sure you know what you are doing. See the user_objs.c and LPRng/src/common/getqueue/Make_sort_key() for details. When you did a redirect of a queue, would not move the jobs in the queue. This is now fixed. Updated the printcap.5 man page so it is a bit closer to reality. Finally got slammed with a 'blank page' of output once too often. The ':sf' (supress form feeds between job files) flag is now history. If you need a form feed between a job file, then use 'ff_separator'. Yet another version of the UTILS/accounting.pl file. The client -A option (use authentication) now selects the authentication type from the AUTH environment variable. Release LPRng 3.6.13 Fri Jan 28 08:03:07 PST 2000 MIT Kerberos support: added code to detect when sending job to server and the server name is 'localhost'. This requires a special ticket lookup to get the right ticket, as there is no lpd.localhost ticket, only lpd.servername. (Supplied by: Mike Whitson ) src/Makefile.in: ln ${STRIP} -> ln -s (Noticed by: Mike Whitson ) The filter $- specification did not handle $-/xxx and $-root/xxx correctly. (Spotted by: Simon Wilkinson ) When using 'user' or 'custom' authentication, lpr errors were not printed out. This was due to common/sendjob.c:Send_auth() not setting non-zero return status when there were error conditions. (Reported by: Patrick O'Brien" ) man/install-sh missing, and ifhp src/install-sh as well. (Reported by: Bill Kemp LPRng/Makefile.in referenced the wrong location for lpd.conf and lpd.perms sample files. (Spotted by: Marty Leisner ) LPD: now do accept in the main lpd process, and this time we brutally send a message to the remote end if we cannot fork the child process. Some linksupport.c routines modified to NOT close sockets on error condition. This allows us to try to read additional error information from the remote system. Tested the kerberos5 authentication with kerberos-1.0.5. Fixed sserver.c and sclient.c. LPRng-HOW corrected. Filters only get SIGINT and SIGCONT sent to them to kill them off. (Spotted by: Robin Sommer ) Authentication support code rewritten to support error message and status returns. Also, added error messages and status reports. lpd started too many servers. The Get_max_server() code returned the maximum number of server processes that should be running, and I would try to start this number. This would lock up the system until one had exited. Now I start up max_servers - 4 at most at startup time. This is still high, but seems to work. lpq.c: missing argument to plp_snprintf() (Patch by: Craig Small ) The environment variables passed to filters were not getting their escaped characters expanded. Thus, PATH=xx\072xx\072xx was getting passed instead of PATH=xx:xx:xx The default lpd.conf has been fixed so that it has escaped values for : instead of : in the file. Some filters require a killpg() AND a kill(SIGINT) AND a kill(SIGCONT) to die. Next it will have to be garlic and a stake... Sigh. (Noted by: Peter Scheurer ) The translate_format and translate_incoming_format options can now have '*f' entries - the * matches all formats. This would translate all file formats to f. The LPRM forward in common/lprm.c did not pass the user's name correctly. (Found by: John Perkins ) Reformatted LICENSE so that the words GPL are in the first lines so that people can tell right away. Updated dates to match Jan, 2000 LPQ and LPRM commands were not being forwarded correctly. RADICAL CHANGE IN CODE ORGANIZATION: In the next major release I will be restricting authentication to code modules only, and users will have to write (gasp!) C code to do this. This is due to the problems with adding various types of encryption, etc., which are not well supported by shell scripts, etc. (I won't discuss the legal issues, these are ugly.) The following restructuring of the Authentication API has now been done. a) Printcap, lpd.conf information The auth=xxx and auth_forward=yyy set the type of authentication to be used by the sender. The auth=xxx is used by the clients to communicate with the server and the auth_forward for server to server communication. b) for each authentication type there is an unlimited amount of configuration stuff available now. The configuration/printcap entries have the format xxx_key. The xxx_id entry is used by clients to identify the id of the remote server that they are to use for authentication type xxx. When the server accepts a connection, it will use the xxx_id value as its 'key' or whatever for the connection. Similarly, when doing server to server communication, the xxx_forward_id is the id of the remote server; the remote server will still use xxx_id. The reason for this has to do with printcap organization. You want to have both entries present in a printcap, one for a client to send to the server, and the other for the server to forward to another server. You should note that this will break down a little bit when you have bounce queues. Since there is only one xxx_forward_id available for all of the destinations, all of the destinations will need to use the same xxx_forward_id value. This problem will have to be solved at the authentication module level, probably by not using the xxx_id and xxx_forward_id for anything but advisory information. For backwards compatibility, kerberos can also use kerberos_server_principal and kerberos_forward_principal instead of kerberos_id and kerberos_forward_id respectively. c) for server to server authentication, use the 'auth_forward=type' to set the authentication type for forwarding. d) For example, to use kerberos authentication the client printcap entry would have: auth=kerberos kerberos_id=lpr/lpr@server.host OR kerberos_server_principal=lpr/lpr@server.host kerberos_service=lpr kerberos_life=... (this are usually not used) kerberos_renew=... (this are usually not used) The server printcap entry would have: (note no 'auth=' stuff used) forward_auth=kerberos (to use kerberos to forward) kerberos_id=lpr/lpr@server.host OR kerberos_server_principal=lpr/lpr@server.host kerberos_service=lpr kerberos_life=... (this are usually not used) kerberos_renew=... (this are usually not used) kerberos_keytab=/etc/krb5.keytab kerberos_forward_id=lpr/lpr@anotherserver.host In addition, you will find that PGP authentication has been more fully supported. CLIENTS: use environment variables PGPPASSFILE = location of a file with the PGP password PGPPASSFD = fd to read the password from (very very rarely used) Client Configuration: auth=pgp pgp_id = pgp id of the server, used to get server key from key ring pgp_path = /... - path to PGP executable on user system Server Configuration pgp_id = pgp id of the server, used to get server key from key ring pgp_path = /... - path to PGP executable on server system pgp_server_passphrasefile = file containing passphrase to be used by server to unlock key file Server keyring files are in the server user home directory, i.e. - if server runs as 'daemon' it is ~daemon/.pgp/pubring.pgp and ~daemon/.pgp/secring.pgp. Don't fight it. Note that user level authentication using shell scripts is still there, but I am making it hard to use. Don't use it. Evil. Bad. See the notes below on how to add C code to do this. And I have added some interesting code to use md5 authentication and shared secrets: CLIENTS: use environment variables MD5KEYFILE - file containing md5 keys format is: name=key. keys are currently 16 chars long - the ASCII values are used to set the 'key' value. Yes, yes, I know there are only approx 76**16 = 5 * 10*29 possible keys using this. Tough. A key for the user name (login name) and the md5_id need to be present Example: User Keyfile # from the configuration information: md5_id=key # we use 'key' to look up the host information # the entry has the format '[user_auth] salt' # if user_auth is present then it will be used as the # 'from' or 'client' information. The recipient will use # this value to look up the corresponding hash key value in # servers keyfile #key = user_auth salt lpr@h4=papowell-h4 xx01223750adfj9098789sdfadf lpr@h5=papowell-h5 asdfu189asdfasdfasdfasdfasd Server Keyfile (host h4) #key = user_auth salt # user key papowell-h4=xx01223750adfj9098789sdfadf # key for forward transfer to host h5 lpr@h5=lpr-h4 adfa9ipioasdfasdfjklsf # key for forward transfer from host h5 lpr-h5=adfa9ipioasdfasdfjklsf Server Keyfile (host h5) #key = user_auth salt # user key papowell-h5=asdfu189asdfasdfasdfasdfasd # key for forward transfer to host h4 lpr@h4=lpr-h5 adfa9ipioasdfasdfjklsf # key for forward transfer from host h4 lpr-h4=adfa9ipioasdfasdfjklsf Configuration: auth=md5 Just to make life interesting, I have also added a demonstration of how to do md5 signing and authentication. e) Code reorganization The LPRng/src/common/sendauth.c and LPRng/src/common/lpd_secure.c files have the following stuff added at the end. #define SENDING #include "user_auth.stub" struct security SendSecuritySupported[] = { /* name, config_tag, connect, send, receive */ { "kerberos4", "kerberos", Send_krb4_auth, 0, 0 }, { "kerberos*", "kerberos", 0, Krb5_send }, { "pgp", "pgp", 0, Pgp_send }, { "user", "user", 0, User_send }, #if defined(USER_SEND) USER_SEND #endif {0} }; This is an example of how you add user level stuff for encryption and not go to jail for international arms smuggling. The "user_auth.stub" file contains the source code for the various modules, or you can put the source code in another file and link it in. This is recommended when you want to use a dynmically loadable library and ship the library. (Note: yes, I looked at loadable modules a la Apache, but LPRng runs on systems that do not support this, so I gave up. This is the older method from other real time software that seems to work.) The data structure has the name of the authentication, used with the auth=xxx tag. The name field corresponds to the xxx value. The config_tag is used to do lookups in the various configuration and printcap files to get values. Why not make them the same? As you see in the example, we have kerberos4 and Kerberos 5, but we use different support routine with the same key values. Backwards compatibility is thus assured. Oh, yes. Note that you can use wildcards for the name value. The connect, send, and receive fields are the support routines that are used for handling encryption. connect: make a connection, fumble around and do authentication, and then return. Kind of like a 'connect' call, but does handshaking. Note that the data link and other stuff is handled by LPRng. Very lightweight and fast. send: this is an alternative to connect. The routine is handed a file that it packs up and then sends to the remote end. In response it gets data back that it will unpack and deliver to the user as status or error messages. receive: this routine is called when the LPD server gets an authentication request. If the 'connect' routine is used, 'connect' sends a magic string to the server that will cause it to call this routine. The routine will do the hand shaking, and then return. The normal LPD service routine will take over. If the 'send' routine is used, this routine will get the stuff sent by the remote end, unpack it, or what ever is appropriate, and then call the LPD service routine. By convention, it passes the routine a file to put its error messages, etc., into. When the routine returns, the file contents are packaged up and sent back to the server. Note: Kerberos4 : uses connect / receive Kerberos5 : uses send / receive PGP : uses send / receive MD5 'send': uses send / receive MD5 'con' : uses connect / receive The source code for PGP authentication is in LPRng/common/linelist.c (don't ask). You can get an idea of how to add more authentication by looking in LPRng/common/user_auth.stub for excruciatingly detailed discussions and examples. The #define SENDING controls what stuff in the user_auth.stub gets included. If you look in the sample file, you will find: #if defined(SENDING) extern int md5_send(); # define USER_SEND \ { "md5", "md5", md5_send, 0, md5_receive }, #endif This little bit of code causes the prototype md5_send() to be put in place, and then the USER_SEND to be defined. Note that in the original file (send_auth.c) that this is used in a table to insert the correct authentication stuff. Enjoy. Release LPRng 3.6.12 Tue Oct 26 16:59:35 PDT 1999 AIX does not like control files where Nxxx comes before data file lines. Added a 'nline_after_file' option to cause LPRng to put Nlines after data file lines. (Noticed by: Nik Conwell ) configure - kerberos libraries are now specified at the start of the library list (LIBS="-lkrb5 $LIBS") (Suggested by: John Perkins ) Typo caused LPD not to read the permissions file. (Noticed by EVERYBODY, but first by: Patrick O'Brien" ) Release LPRng 3.6.11 Sun Oct 24 13:37:44 PDT 1999 Permissions checking: SERVICE=* was not getting handled correctly. (Found by: Dejan Ilic ) Jobs with more than 26 files were quietly being mangled. (Found by: Derek Masseth ) lp simulation now returns a 'job identifier' consistent with Solaris 2.5 format. (Noticed by: Martin Mokrejs ) Added support for case sensitive key lookup in sorted lists. (General cleanup and tidy: Patrick Powell ) Set_linger() (setsockopt socket linger timeout) failure is now ignored, rather than treated as failure. This now handles the case where pipes are actually second class citizens and the operation fails. Note that this probably could be fixed by testing the file descriptor for type and then determining the exact socket type, but this is NOT portable. Set the default paper size for the IFHP-HOWTO to letter. The psutils package can be used to resize this for a4, which is slightly larger. Did horrible things to job reception to handle jobs with spaces and more bogus entries in the name fields. This is really strange. Note: still one quirk - if the server name has a space in it AND the job is originated on the server, THEN the originating host is set to 'localhost'... which is correct but may be odd when forwarding to another system. Compaq AKA DEC True 64 support added - configure.in now does odd things to detect correct libraries to be used to get gethostbyaddr() support. Portablility. configure --disable-strip will disable stripping of binaries. (Requested by: Marty Leisner ) Permissions, 'SERVICE=P', and job removal: if a print job gets through the 'R' (lpr job sumission) checking, and gets into the queue, there is another check ('P' or print time checking. This was done to subdue complaints from systems which could not handle a 'no permssions' error and would sit there endlessly trying to send the same job to the printer queue, and other users would not get their jobs through. When a job is ready to be printed and fails the 'SERVICE=P' permissions check, it is now removed and not printed, UNLESS the 'save_on_error' flag is set, in which case it is marked with a permissions error and left in the queue. Note 1: the lpd.perms file has been updated to reflect this behavior. Note 2: the HOWTO has been updated to reflect this behavior. Note 3: if you have a DEFAULT REJECT in your lpd.perms, this means that no jobs will get printed. :0). Enjoy. Set the 'SO_KEEPALIVE' option on sockets to force keepalives to be sent so that dead connections would be detected. Updated some code in the common/lpd_remove.c file to close a small timing race condition for job removal. Sometimes a job would get removed and the server process would not be killed. Note that the kill is done by sending SIGINT to the processes. Changed a int to double for file length in common/lpd_rcvjob.c. Modified UTILS/cheap_lpr and UTILS/LPRng.pm to handle more than one file in print jobs. Checked out a few problems with PGP and user specified authentication. (Spotted by: Patrick O'Brien" ) LPQ - use the file name information if no 'J' (job) line in control file, and finally "NULL" if no information. This prevents many scripts from breaking. getqueue.c:Get_datafile_info() was not getting the N,U, and format values correctly under all circumstances, i.e. - duplicates, out of order N lines, totally bogus or missing N information. What a mess. (Spotted and patch by: Edwin Lim ) (And lots of others, with comments, flames, and snickers as well.) Fixed a problem when you used a filter to get printcap information, and you did a recurive get, and you had a tc=xxx entry. (Spotted and debugged by: Simon Wilkinson ) configure --enable-priv_ports action was reversed... (Spotted by: Robert Montjoy ) Warning message about '@' in a printcap name was malformed. (Spotted by: Andreas Kahnt ) Added a 'tc_only' flag to allow printcaps to be explictly marked for 'tc=name' use only. This allows people using NIS, NIS++, and other database engines to put printcap information in database forms. Now 'checkpc -P printer' will only check specified printer. Handy for 'checkpc -f -P printer' type of operations when you add a new printer to a system. (Suggested by: Wilfried Gaensheimer ) Release LPRng 3.6.10 Sun Sep 12 19:46:33 PDT 1999 lpc.1 man page moved to lpc.8 man page (Suggested by: Craig Small ) PERMISSIONS CHECKING: The USER, HOST, IP, SAMEUSER, SAMEHOST, entries will now SUCCEED when checking permissions for an operation to be applied to a spool queue; when the individual jobs in the queue are checked the comparisons will then be done. This has the effect of allowing: ACCEPT SERVICE=C LPC=hold,release SAMEUSER SAMEHOST ACCEPT SERVICE=M SAMEUSER SAMEHOST to be specified and allows a user to hold, release, or delete their jobs. (Need pointed out by: Jens Noelle ) Updated the lpd.conf file generation to put in the types of options. NONE renamed to NONEP due to conflicts with some definitions. Added a $_ capability to filter options. (Patch by: Mike Whitson ) Added a configure option to set the :sh default to 1 (on). Release LPRng 3.6.9 Mon Aug 30 13:30:58 PDT 1999 reverse_priority_order flag - priority z-aZ-A, i.e. - A is lowest (Requested by: Dennis Bush ) LPD now does a chdir("/") so that it is in a well known location. (Requested by: Craig Small ) Time used to sort job is now the arrival time of the last byte of the job. Release LPRng 3.6.8 Fri Aug 27 17:06:10 PDT 1999 *** WARNING: configure strikes again *** *** printcap, lpd.conf, lpd.perms now default to: *** /usr/local/etc/{ printcap, lpd.conf, lpd.perms} *** You may want to do: ln -s /etc/printcap /usr/local/etc/printcap OR configure --with-printcap_path=/etc/printcap Please move your lpd.conf and lpd.perms files to /usr/local/etc/ Why? Because when trying to port this to XxxxBSD, BSDI, Solaris, SunOS, HPUX, DGUX, etc etc etc I have run into so many inconsistencies that I have just given up. You might as well assume that the following is true for a default install. Updated configuration to be a little more consistent with other packages default installation directories: ${prefix} is usually /usr/local ${bindir} is usually ${prefix}/bin, (/usr/local/bin) ${sbindir} is usually ${prefix}/sbin (/usr/local/sbin) ${libexecdir} is usually ${prefix}/libexec (/usr/local/libexec) ${sysconfdir} is usually ${prefix}/etc (/usr/local/etc) ${mandir} is usually ${prefix}/man (/usr/local/man) We install the executables in: (* indicates default SETUID Root install) ${bindir}/ lpr *, lprm *, lpq *, lpstat * ${sbindir}/lpc *, checkpc, lpd * ${libexecdir}/filters/ lpf, banner, etc ${sysconfdir}/ lpd.conf, lpd.perms, printcap ${mandir}/ man pages Suppose you wanted to put them in /usr/bin, /usr/sbin, and /etc: configure --prefix=/usr --sysconfdir=/etc Note the following explicit overrides: --disable-setuid disable setuid root client and server executables --enable-priv_ports require connections to be from privileged ports --disable-force_localhost force_localhost default to disabled --with-lpddir=DIR lpd executable directory (default ${sbindir}) --with-filterdir=DIR filter directory (default ${libexecdir}/filters) --with-lpd_conf_path=PATH path to lpd.conf (default: ${sysconfdir}/lpd.conf) --with-lpd_perms_path=PATH path to lpd.perms (default: ${sysconfdir}/lpd.perms) --with-printcap_path=PATH path to printcap (default ${sysconfdir}/printcap) Fixed up the INSTALL and HOWTO documentation as well. Note 1: you can make a symbolic link from /usr/local/etc/printcap to /etc/printcap and this will solve the issue as well. --- Job time is now recorded down to the millisecond a jobs sorted according to that time. This will slightly improve the situation due to multiple jobs arriving at at (approximately) the same time. Jobs are sorted accordingly. (Suggested by: Abramo Bagnara ) Release LPRng 3.6.7 LPRng now handles files larger than 2 gigabytes on systems where the max size_t is larger than 2 gigabytes. configure now checks to see that there is a prototype for lseek(). (Both inspired by somebody trying to print a 2G file: John Kimberley ) lpq -n linecount Limits number of status lines to linecount. Can be used when you want an exact number rather than using -llll. lpc now puts debug flags in () - Printer Printing Spooling Jobs Server Subserver Redirect Status/(Debug) t1@h4 enabled enabled 0 none none (4) There is a horrible problem with load balance queues, SIGCHLD, and missing SIGUSR1 signals on Solaris 2.4, 2.5, and 2.5.1. The code in lpd_jobs.c has been rewritten, silly things have been done and it now looks awful, but it works, is portable, and ugly. So much for elegance. Added more %U option to lpc, lprm to allow SAMBA to specify users. Release LPRng 3.6.6 Sun Aug 22 10:42:20 PDT 1999 LPD did not exit with non-zero success code when there was another lpd active. (Patch from: Stephen Fischer ) LPD bounce queues changed the 'N' data in the control file. Should not do this. (Noticed by: John Rothlisberger ) New timeout - exit_linger_timeout When an LPD server process exits, it needs to try to 'flush' data over the various pipes, sockets, etc, that are part of the IPC. The problem is that on some OS's, when a process exits the data in a pipe buffer may be discarded if the process exits due to a signal. Added 'exit_linger_timeout' to force all pipes/sockets to be 'lingered' on during cleanup. This is a totally bogus method. What is needed is a setsockopt() function similar to 'fflush' that would not return until all the data is flushed to the remote end. It turns out that the SO_LINGER with a 0 value should have done this, but the 0 value causes a 'default' value to be used. Grr... Needless to say this is a hack of the worst type, does not work on all systems. LPR was failing due to connnections closing due to lack of processes. When a connection is made to the LPD server, it used to do accept() and would then fork a process. This would lead to some ... interesting... denial of service attacks, and some very odd problems when you ran out of processes. The code now does the following: creates a pipe() forks a process = = child will now do an accept = child will then close the pipe parent WAITS until the child pipe is closed. This has the effect of making sure that the child process has done the accept, and will BLOCK until the accept is done. This makes sure that there is a process to handle the connection. Wierd, I tell you. Note that there is a way to do a DOS attack on some systems that signal a connection is available BEFORE the 3 way handshake completes, and should cause endless problems. You can also launch DOS attacks on inetd, ftp, etc. etc. on these systems as well. See CERT for more nasty details. LPQ now correctly reports all jobs, even ones from different machines with the same job numbers. Yeah, it looks confusing in the output to have two job 12's, but HEY! what do you want on 80 columns? LPQ now confuses people trying to figure out why there are duplicate jobs in the status listing. See above. Isn't this marvellous? lpd_jobs: when processing long queues a huge number of tempfiles would be created. Now these are removed each time the queue is scanned. Sigh... lpd_jobs: when you have a connection opened using lp=host%port, then lpd now do a shutdown(port,1) on the socket. Now we get into the really odd stuff. We first set the linger value to 'read_write_timeout' if nonzero otherwise the 'exit_linger_timeout'. IF the 'wait_for_eof' flag (default TRUE) is set, we try READING from the socket until we get an eof. We then close (with the linger) the socket. Here are the problems that this tries to solve. When you send a job to a printer over a socket connection, you stuff the files into a socket and then expect the OS to deliver the data. WRONG! The OS puts this in some buffers. It returns from the WRITE call with success. You now do a close(). At this point there are some interesting possibilities: a) your data is delivered, even after waiting 6 weeks for the other end to respond (BAD choice); b) the system attempts to deliver your data for, say, 120 seconds (default 'linger' time on some BSD systems); c) you can specify how long you want to have the system try to deliver the data. While this is going on of course, you cannot open a connection to the device, as it is still busy with the previous connection. You really want to treat the 'close' like a 'write' and wait for a reasonable (read_write_timeout) time for this to happen. When you do a write 'shutdown', the TCP/IP connection sending (write) capability is terminated, and the TCP/IP stack does a handshake with the other end telling it that no more data will be sent. The receiver will get an EOF when it tries to read more data, and will, in turn, close the connection. Note that this must be a 'shutdown' and not a 'close'. All close does is closes the process's copy of the file descriptor information. Shutdown is brutal and will terminate with predjudice the tcp/ip level communication (thank the Diety). How do you know that the receiving end has closed the connectio? You do a read from the socket until you get an EOF. Of course, you should be reading from the &*()*& socket at all times, as the printer will be sending status, error messages, etc. etc. back to you. But your filter should be doing this, right? Oh... you do not have a filter... well, you MUST have a filter that does the reading - this is what the IFHP filter was designed to do, and in fact goes overboard to solve this problem. Even when you say 'status@' it STILL tries to read from the file descriptor because there might just be stuff coming back. Sigh... Release LPRng 3.6.5 Sun Aug 1 16:46:31 PDT 1999 The date format in the status messages has been changed so that you can have a short or long format displayed. By default, the short format is displayed (short_status_date option is true). Note that this sillyness is partly forced on us by Y2K issues. New flag option: short_status_date - when set, status time/date displays only time. (Sigh... by: Patrick Powell ) Remote logging information now contains full date and time and process id. (Sigh... by: Patrick Powell ) Update LPRng HOWTO to specify that filter STDERR output is now merged with the status messages. This allows errors reported by the filter to appear on the lpq status. You can specify filter arguments as the form xxx 'yy yy' "zz zz" and they will get passed as a block. (Suggested by: Martin Forssen ) The lpstat -a code has been fixed so that it correctly searches for printer names. (Reported by: Martin Forssen ) Removed duplicate status information lines in status file. (Discovered by: Patrick Powell ) Added 'send_failure_action' information to status output to allow users of this very odd feature to figure out what is happening. Fixed up LPRng to handle a stupid RFC1179 idiocy. If you have a control file, then the order of N and data file lines is not defined. So you have to handle them in any order. Also, you can have the same data file line with DIFFERENT formats - sigh... this means that you can print it several times with different formats. The 'generate_banner' option, which was present in 3.5.1, has been restored. This is only operational when you have a 'normal' forwarding queue. It uses the 'ab' (always banner), bp (banner printer), bs (banner printer program for banner at start), and be (banner program for banner at end), hl (header or banner last) and the user banner information. The "cm" (comment) option has escapes processed. Now you can put ":" in the comment line by using "\072" (Wanted by: Johan Claesson ) Release LPRng 3.6.4 Sat Jul 24 14:29:09 PDT 1999 Cut and Paste-o observed in the configure.in file - LPD_CONF_PATH should be LPD_PERMS_PATH. (Reported and patched by: Tim Mooney ) FreeBSD Support: FreeBSD.ports.sysutils has the files for a Ports Install RedHat RPM: pkg has the files needed to build a RedHat RPM distribution. Release LPRng 3.6.3 Fri Jul 16 16:01:27 PDT 1999 CONFIGURE CHANGES Please note that the configure and 'make install' have been modified in order to deal with different installation locations and configuration setups. Here are the options to configure that you should be aware of: --with-cppopts=CPPFLAGS select compiler preprocessor command line options **** note: these flags will also be passed to CC, so set your options using **** this configuration option. --disable-setuid disable setuid default **** note: use this if you want to install without setuid --disable-priv_ports set default lpd.perms to reject connections from non-privileged ports **** note: if you disable priv-ports, you MUST install setuid. **** Thus, you can have --disable-setuid, --disable-priv_ports, but not both --disable-force_localhost disable force_localhost default --with-lpddir=DIR where to install the lpd binary. *** where you want LPD to be installed. --with-admindir=DIR where to install the administrative commands, like checkpc, lpc, etc. *** where you want the other stuff installed --with-filterdir=DIR where to install filter (default ${libdir}/filters) checkpc, lpc, etc. *** where you want the filters installed --with-lpd_conf_path=PATH where to install lpd.conf (default /etc/lpd.conf,/usr/etc/lpd.conf) --with-lpd_perms_path=PATH where to install lpd.conf (default /etc/lpd.perms,/usr/etc/lpd.perms) --with-printcap_path=PATH where to install printcap (default /etc/printcap,/usr/etc/printcap) --enable-nls use Native Language Support --with-included-gettext use the GNU gettext library included here --with-catgets use catgets functions if available MAKE INSTALL changes These tie into the changes with configure. You should be aware of them. You have been warned. Note 1: FreeBSD To put LPD in /usr/libexec/lpd, admin in /usr/sbin, and other stuff in /usr/bin configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin Note 2: RedHat Linux To put LPD in /usr/sbin/lpd, admin in /usr/sbin, and other stuff in /usr/bin configure -with-lpd_conf=/usr/libexec/lpd -with-admindir=/usr/sbin --prefix=bin Minor fix to configure, src/Makefile to link only lpq with terminal library (Supplied by: Roderich Schupp ) Set spool_dir_perms to 0600 instead of 042600. (Supplied by: Roderich Schupp ) Typos and More Typos in HOWTO (Spotted by the Eagle Eye of: Wolfgang Schludi ) Printcap 'oh=' was using wrong entry. (Reported by: Wolfgang Schludi ) lpd -D= did not tell you what you did wrong. (Reported by: Niklas Edmundsson ) Kerberos authentication forwarding was incorrect. (Fixed by: Mike Whitson ) Printcap includes were not being processed correctly. (Reported by: Don Badrak ) The spool queue control, status, and unspooler files (control.%P, status.%P, and unspooler.%P) are now specified by the queue_status_file and queue_control_file options. This allows you to relocate the files to another spool queue, or even use the file.%D option to have a date appended to the file name. (Reported by: Gary Cender ) When the lpd logger facility makes a connection to the receiver of the log information, it sends a dump of the system status. The dump consists of a set of lines, one line per print spool entry. The end of this dump information is indicated by a single END line, i.e: END\n. This enables a database management system to know that all of the queue information has arrived and can then undertake to do any consistency checks. (Need determined by: Patrick Powell ) When a 'lpc reread' is done, the logger process is killed and restarted. This forces the logger process to use the new printcap or configuration information. (Reported by: Gary Cender ) When an unspooler process is active, a SIGUSR1 signal is sent to it to force it to rescan the spool queue. The SIGUSR1 signal handler sets the Susr1 flag, and this flag is checked. There is a small window between the time that the flag is checked, the process decides that no new jobs have been put in the queue, and the process exits. This window has now been narrowed down even more by performing a final check just before the process exits. (Reported by: Gary Cender ) On a heavily loaded system where a large number of files are being created and/or destroyed, the spool queue scanning code would miss some jobs at the start or end of the queue. This was due to the fact that the scandir() routine does not lock the spool directory, and it can change as the directory is being read. In order to reduce this window to the smallest possible size, the directory is now scanned for files and then the files are processed. (Reported by: Gary Cender ) Updated HOWTO to reflect these changes. Updated MAN pages. Release LPRng 3.6.2 Sat Jun 12 16:44:15 PDT 1999 LPRng-HOWTO corrections. (Corrections by: Vladimir V Egorin ) Used the wrong process exit status variable in common/lpd_jobs.c (Noted by: Olav Kolbu ) Added STATE and LPC command execution tracing to the logger messages. This allows a remote system which is monitoring LPRng operation via the logger interface to monitor when a job is submitted and printed. Updated format of message sent by logger. UPDATE message now has a hf_image= and (optional) lpc= encoded portion QUEUE message now has a queue= and (optional) lpc= encoded portion The lpc identifies that the udpate was done by LPC operation rather than by LPD as part of normal operation. File locking had problems under SunOS 4.1.4. You can now have single letter printer names. (Sigh... noted by: Patrick Powell ) Accounting information now has options (correctly) quoted: start '-H...' '-c' '-JThis is a job' This is consistent with ifhp 3.3.2. Release LPRng 3.6.1 Mon Mar 22 09:42:07 PST 1999 This release is a major rewrite of the LPRng software and uses dynamic memory allocation and as few static and global variables as possible. This is intended to simplify the porting of the LPRng software to a multi-threaded environment. In addition, substantial cleanup of much of the code was done. Due to time constraints, some functionality that is present in other test versions was not put into this release. This includes setting user information by originating IP address. The 4.x.x release will have support for the new IPP print protocol, SNMP MIB, and a HTTP server interface. As far as possible, existing functionality has been preserved, with the following notable exceptions. These are divergent enough to cause a new major release number to be used, i.e. - 3.6.x License Due to various technical legal reasons, the License for this release of LPRng has been changed from the GNU Copyleft to the slightly different but similar in intent Artistic License. Load Balance Queues and Class types Assume: a load balance queue with several printers, say master -> S1, S2; You can now set the class types accepted by S1 and S2, and the Master Queue will check the job types against the class types before sending the job to the appropriate queue. What is this all about? If S1 has blue paper you can set the currently printing class to blue (lpc class blue). Now do lpr -Pmaster -Cblue and your job will be routed to printers which currently are printing class 'blue'. Clearly this can be extended to other things besides paper. Note that when you use this option you should set the master queues ignore_requested_user_priority flag so that the first letter of the class type is not used as the priority. ********************************* ******* force_localhost ********* distribution default is ON ********************************* The Most Frequently Reported Problem with 3.4.X and 3.5.X was the following: lpr is not sending jobs to my lpd server. Why? The reason is that other BSD based spoolers ASSUME that the lpd server will be running on localhost, and the clients (lpr, lpq, etc) will connect to the server. So the printcap files are written as: lp:sd=/usr/spool/whatever :rm=remoteserver:rp=remoteprinter Of course, lpr reads this as meaning 'connect to the remoteserver', and never sends the job to the server running on the localhost. The 'force_localhost' option will FORCE lpr, lpc, etc to connect to the localhost UNLESS lpr -Ppr@remoteserver is used, i.e.- a command line override. In LPRng 3.5.X, the default value of 'force_localhost' was OFF. In LPRng 3.6.X, the default value is ON. Bounce Queues, lpd_bounce, and LPR Side Filtering The lpd_bounce option REPLACES bq=xxx Example: -> pr:lp=pr@xxx pr:lpd_bounce :bq=far@server :lp=far@server This makes bounce queues consistent with remote print queues. The entire print job job is passed through the various filters, and the entire output is now sent as a single file to the next queue. The format of this file is set by the bq_output=X option. This now allows the full use of leaders, trailers, banner page generation, etc., to be used. Printcap tc=xxx:tc=yyy handling printcap includes (tc) are done BEFORE setting the values in the printcap entry, and in order. Thus: lp:s=X:tc=.t1,.t2:tc=.t3 .t1:s=Y .t2:z=W .t3:z=P would result (for lp) in: lp: :s=Y # from .t1 :z=W # from .t2 :z=P # from .t3 :s=X and a final result of lp:s=X:z=P (Requested by and faultless arguments by: the lprng mailing list...) Permissions List File: You can now say XXX=) LPD lock file: now defaults to /var/run/lpd (Pointed out by: Martin Forssen ) %D expansion, create_files flag If you have %D in a printcap value, it gets expanded to the current date in YYYY-MM-DD format. If you have the create_files flag set, then the files that normally get trimmed (max size specified) are created. This allow you to do: lf=log-%D Your log files now will have the pathname sd.../log-YYYY-MM-DD and you can now get rolling log files on a daily basis. The files that have this done are the log file, status file, and accounting file. PCLBANNER and PSBANNER - new banner printing programs using PERL produces pcl or PostScript banner page. lp:bp=/usr/local/.../pclbanner :of=.... :if=.... OR lp:bp=/usr/local/.../psbanner :of=.... :if=.... Bug fixes: Gadzillions. Many. Some were not bugs but simply inconsistencies with documentation. Sometimes documentation changed, sometimes the code. Default Server Print Queue: The default_printer_when_unknown configuration option allows you to specify a print queue that the server will use when it cannot find one in the printcap. This print queue should have the format: /etc/lpd.conf: default_printer_when_unknown=fallback /etc/printcap: fallback:server :sd=/usr/spool/lpd/%P :router=/..../router_for_misdirected_jobs The router should output the correct destination (see router documentation in LPRng-HOWTO), and exit with 0, or exit with JREMOVE to cause the job to be dropped in the bit bucket. Release LPRng 3.5.4 Mon Nov 9 10:07:42 PST 1998 Bug fixes: Bad link to site in LPRng.smgl documentation. (Reported by: Anthony Thyssen ) LPQ status was missing a space separator when reporting subserver name list. (Spotted by the Eagle Eyes of: John Callaghan ) The xt flag has been expurgated, totally. As was documented. (Spotted by: James P. Dugal ) LPR_bsd option added so that -m does BSD mail option. (Requested by various folks) Testers and bug fixers: (Compilation: Bernie Kirby ) Release LPRng 3.5.3 Mon Nov 9 10:07:42 PST 1998 Documentation Error: LPRng-HOWTO, Section 8, indicated that the lpd.conf file could be obtained using a filter. This is not correct. (Noticed by: David Stenglein ) Major Modification: removed the 'xu' (per spool queue permission file) after trying to make the semantics work. Now we have a single permission file for all printers Major Modification - Load Balance Queues: Some users reported very slow operation of the load balance queues. This was verified, and extensive modifications were made to the functionality. CHANGE: The subserver queues are only scanned at startup and when there is an explicit indication that a new job has been put into or removed from the queue (SIGUSR2 received) Major Modification - LPD Does Not Ignore LPR, LPC Requests Some users with either large numbers of spool queues or spool queues with large numbers of jobs noticed VERY slow LPD response. This has been improved considerably. CHANGE: LPD server would run through the Spool queues, looking for trash to be removed or jobs to be started. This polling is necessary due to the possibility of a race condition between the time that a job is put into the queue and the time that the unspooler checks the queue for entries. The operation has been modified so that only a SINGLE PROCESS runs down through the spool queues. When it finds work to do, it informs the LPD server, which now will start ANOTHER process to check other queues for work. Note that while these processes are working their little hearts out, chewing up swap space and reading directory entries like mad, the LPD server can accept requests for LPQ, etc. Major Modification - LPR speedup: The LPD server now accepts jobs for spooling WITHOUT extensively checking the spool queue. This eliminates problems with printing to queues with a large number of entries. Speed Improvement: A bit of time analysis showed that LPRng was spending a large amount of time during queue scanning in the fcmp() routine. This has been rewritten and is now a strcmp(). During queue scan, Get_controlfile() generates a 'cmp_str' value that represents the information needed to do sorting. This is is then used during queue sorting as the comparison value. The 'struct cmp_struct' in the include/sortorder.h is used to make sure that sufficiently long string buffers are allocated. The make_cmp_str() in common/sortorder.c can be replaced with a users version if they desire. Bug Fix: safestrncpy, mystrncpy, safestrncat, mystrncat now used for string copies where there is doubt on the buffer/string length. Note that these versions will always make sure the buffer is terminated with a 0 value. lpr -U xx is supposed only to work for ROOT. Check for root perms was not done correctly. (Patch by: Paul Szabo ) permissions checking: the C=value1,value2 permissions checking option wants a C (control file) line starting with character C and glob matching the indicated value1, value2, etc. For example, N=patrick*,powell* should match against line Npatrickwashere or Npowellwasthere. The check was done incorrectly. (Patch by: Paul Szabo ) LPD/lpd_rcvjob.c - removed limits on lengths of class and host names When using bounce queues and the generate_banner to cause a banner to be added to a job, the 'ab' (always banner) and the lpr -h (no header) flags now are used in the decision for banner generation. (Noticed by: Charles Karney ) Filters were not being passed -Knnn option. (Noticed by: Charles Karney ) Permissions: SERVER keyword was not used for X permissions. (Fix by: Patrick Powell ) File Permissions: spool_file_perms was being ignored due to the umask() not being (un)set before creating a file. (Discovered by: Albert Fluegel ) Accounting filter: when the filter returns 'JHOLD' the job will be held (as documented). (Patch by: Rainer Schoepf ) LPRM incorrectly gives the "clean" usage instead of "lprm" usage. (Fix by: Edan Idzerda ) The 'xt' and 'check_for_nonprintable' flags were in conflict. Removed the 'xt' flag. (Reported by: "Dugal James P." ) The LPD/lpd_remove.c code did not remove jobs correctly when a :destination=... entry was present (Patch by: john@cs.wisc.edu) Log files not being truncated. Well, they are now. (Fix by: Patrick Powell ) LPR not printing multiple copies (-K option) (Patch by: Keith Richardson ) LPD did not check spool queue just before exiting from printing loop. This opened a BIG race window on systems with lots of jobs in the spool queue. (Fix by: Patrick Powell ) Expand_command did not check for Do_dollar() returning 0, indicating a string overflow condition, which it then dereferenced and core dumped. (Reported by: (Walter Misar) ) Control file filters were not being invoked correctly. (Reported by: Tony Graham ) Memory trashing being done by different behaviour of strncat() on some systems. Replaced by mystrncat() and took the performance hit in return for reproducible behaviour and non-trashing copies. Sigh. (Fix by: Patrick Powell ) strncpy() and strcpy() does not handle overlapping strings correctly, or at least that is what the man page says. Replaced several of these calls by memcopy() and friends. (Fix by: Patrick Powell ) Release LPRng 3.5.2 Fri May 1 14:39:55 PDT 1998 Bug Fix: lpr -k did not pass the correct length (0) to the remote system. (Reported and patch by: Wolfgang Scherer ) common/pr_support/ checks Do_lock() for <= instead of < for failure condition. (Reported by: Wolfgang Scherer ) common/proctitle.c had a strdup() call - not supported under ULTRIX. (Reported by: "Todd C. Miller" ) force_localhost was being tested BEFORE it was set in the printcap entry. Now is checked AFTER the printcap entry is processed. (Reported by: Petri Kaukasoina ) LPD returns 'o connect permissions' instead of 'no connect ...' (Noted by: Reinhard Zierke ) LPD records filter name in error message correctly. LPQ now reports full class name in status message if 'class_in_status' flag set in printcap. (Requested by: Philip J. Nesser II ) common/sendlpc.c - missing Lp_device = 0 (Reported by: "Dugal James P." ) LPD reported the wrong host name in 'no permission' messages. (Noticed by: Patrick Powell) Release LPRng 3.5.1 Fri May 1 14:39:55 PDT 1998 Baseline Stable Release Release LPRng 3.4.12 Fri May 1 14:39:55 PDT 1998 Legacy support modification: control file now has printer information in: controlfile Ninfo Uinfo order. Some legacy printer spoolers require this order. (Reported by: Don Badrak ) Minor cleanups of: Get_printer() calls - some silly comments and orders common/fileopen.c/Init_tempfile() - clarified the use of the various directories and defaults. Force_localhost: now done in Get_printer(), where it should have been done in the first place; LPQ and LPRM now send requests to localhost unless explicitly overriden Force_fqdn will now brutally assume that the domain of the sender is the one reported by the FQDN of the originator of the connection. Release LPRng 3.4.11 Thu Apr 30 11:46:25 PDT 1998 Functionality Change: JABORT and stop_on_abort default value changed JNOPRINT filter exit status stops printing JFAILNORETRY filter exit status stops retries In previous versions, when a filter exited with unknown or JABORT status, the default action was halt processing of PENDING jobs. When a new job was sent to the queue, or a lpc start was performed, processing was restarted started. Under heavy load conditions, the effect of the JABORT was nullified by the arrival of new jobs. The LPRng behaviour has now been modified to handle JABORT conditions in a predictable manner, using the 'stop_on_abort' flag. 1. The default for 'stop_on_abort' is now FALSE. This means by default that the JABORT status will simply be treated as a 'do not retry this job' error status. If the 'save_on_error' flag is FALSE (default), the job will be removed from the queue. 2. If 'stop_on_abort' is set to TRUE, then when a filter exits with a JABORT on unknown status, further processing will stop, and NO pending jobs will be printed. If the 'save_on_error' flag is FALSE, the job will be removed from the queue. 3. If 'stop_on_abort' is set to TRUE, the abort condition is sticky, i.e. - it will persist until action is taken to clear it. Any of the LPC commands which cause printing to be restarted will clear it: LPC start, up, kill, topq, release, or redo 4. LPQ and LPC will report if there is an aborted job condition. Note that for most users, the default action is now the desired action, i.e. - to continue processing jobs. However, certain administrators will most likely need to assume that when a filter exits with JABORT that further printing on this queue will fail. The sites should set 'stop_on_abort' to TRUE. JNOPRINT: If a filter exits with JNOPRINT, then printing will be stopped; this will have the same effect as an LPC stop command. The job will NOT be treated as an error job and will remain pending in the print queue. This allows filters to detect conditions that would normally cause printing to fail before a job is started, and halt printing under these conditions. JFAILNORETRY: Under various arcane conditions, it is possible for a filter to determine that a job has failed, and should not be retried. Most filters would return a 'JREMOVE' error code, but for various arcane reasons (lots of Arcania here, folks), the 'save_on_error' flag might be set, and the adminstrator would like to have the job marked as erroneous, but NOT removed. If the filter exits with JFAILNORETRY, then the job is treated as though it had an error, but no retries are performed. Extended Functionality: 'mail_from' option Allows specification of the 'From:' user. If not specified default is to use the printer name. (Patch By: Rainer Schoepf ) Portability Extension: LPD_CONF_PATH compilation option The location of the LPRng configuration file is specified by the config_path value in the src/common/vars.c file. The compilation option -DLPD_CONF_PATH=path can be used to override the default locations. Example: make LPD_CONF_PATH=/usr/local/etc/lpd.conf all Nit Fix: spelling errors corrected. (Reported by: Don Badrak ) Incredible 9 Gigabyte Partition Fix: (Reported by: Don Badrak ) Apparently the common/freespace/plp_fs_free_bytes cannot handle a >4 gigabyte partition. The fix was to cast values to a double - this should be sufficient until we get 10**38 byte file systems. :-) Bug Fixes: LPD usage() had (erroneous) -i option. (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake))) get_max_servers did not get max servers. (Patch by: Don Badrak ) Release LPRng 3.4.10 Thu Apr 23 18:01:37 PDT 1998 Added Functionality: sync_lpr flag- this suppresses the closing of the lpr to lpd network connection until the LPR job is completely processed by the LPD server. This can, under various arcane and odd situations, result in the lpr processes 'hanging' until the LPD server queries DNS servers, looks up permissions, etc etc. However, if users are trying to figure out why LPR has returned and their job is not in the queue, or you have some desire to write shell scripts that create jobs and then remove them in order to see 'just how fast LPRng is', this flag will SLOW DOWN the operation by making it synchronous. Any little thing to make folks happy... :-) Modified Functionality: The 'force_localhost' flag has now been modified to (literally) force a connection to one of the 'localhost' addresses returned by a DNS lookup. This should have no effect on 'normal' users, but might have the result that the status returned by LPQ will now differ a little. For example, if you have a printcap pr:lp=pr@host2:force_localhost you will discover that lpq -Ppr will now print: Printer: pr@localhost ... status for localhost queue Printer: pr@host2 ... status for host2 queue This is correct and accurate reporting, compared to the previous lpq format. (Brought to my attention by: Tim Mooney ) Bug Fixes: Job_printable_status() did not report active jobs, so lpq and lpc job count was off by one. (Reported by: Al Marquardt ) Release LPRng 3.4.9 Mon Apr 20 12:42:55 PDT 1998 Enhanced Functionality: For those folks who want to 'masquerade' their servers, the 'report_server_as=hostname' will now report your printer@server as 'pr@hostname'. (Requested by: Tim Mooney ) EXTA/EXTB: ifdef'd for folks with REALLY vintage systems... (Requested by: David Coelho ) Added debugging code to determine when servers started. LPD now clears job 'move' indications so that a job can be saved (save_when_done) and then reprinted with out being moved to the destination again. lp -s (Silent) now does not print job id information. (Noticed by: David Coelho ) Jobs which do not have print permissions now get removed. (Reported by: Al Marquardt ) lpq -tN -c now will not core dump. Release LPRng 3.4.8 Sat Apr 18 15:23:22 PDT 1998 Portability Fix: AIX 4.1.5 has definition conflicts when doing #include a.out.h. (Reported and Fix by: Niklas Edmundsson ) Also, Solaris4.1.4 has conflicts with tgetent() definition. (Reported by: wcolburn@nmt.edu (William Colburn (aka Schlake))) Y2K checked - ISO conformant date format is used in log and other messages. :force_fqdn_hostname flag causes FQDN host name rather than short hostname to be put into control file. Bug Fixes: Accounting at end was failing do to closing output device too early in the algorithm. Device now closed AFTER last accounting script is called. (Reported by: Niklas Edmundsson ) Time_t strikes again. I just discovered that there were some places where I was using long instead of time_t for time values. This has been fixed. However, there is also now the problem of snprintf( "%d", time((void*)0)) being used for output and t = atoi("xxx") for input of time values. Sigh... will fix this later. "lpc lprm pr all" operation now works correctly (Reported by: Tim Mooney ) Release LPRng 3.4.7 Wed Apr 15 08:40:25 PDT 1998 Bug Fix: Stupid system implementor used snprintf() instead of plp_snprintf, causing headaches for unsuspecting folks on systems that did not have snprintf(). Better fix is to insist that systems have snprintf() :-) (Reported by: Helmut Jarausch ) Enhancements: The code for doing 'polling' of spool queues had a very high overhead in terms of process creation. This code has been modified to have a single process run down the queues and check for work. There is a bit of overhead, but much less than the overhead in creating a large number of processes. Bug Fix: when generating banners using :generate_banner, it did not work. System developer forgot to include banner... :-) (Reported by: Cecil R. Whitaker ) Jobs that did not get permission to print and were flagged with JREMOVE did not get removed. (Reported by: Al Marquardt ) When putting in a new 'From this host' line in a control file, did not remove the old one. Also 'Q' entry as well. (Reported by: Al Marquardt ) Multi-homed hosts that do not recognize interfaces need special coddling when trying to connect to them. Link_support.c gets yet another special case for connections. (Patches by: Giray Pultar ) listen(backlog=64) - used to be 10, which caused connections to be dropped under heavy loads. checkpc was adding a / to end of file names. (Noticed and fixed by: Tim Mooney ) Release LPRng 3.4.6 Tue Mar 31 18:10:59 PST 1998 Bug Fix or Nit Pick: When sending a job AND the :qq or :use_queuename flag is set AND the job arrives without a Q entry THEN the name of the queue it was spooled to is used. (Noticed by:Cortney Sampson ) Missing initialization in src/common/permissions.c Discoverer got the 'Gold Star with Flashy Sequins' bug hunting award. (Found by and Award to: Duncan McEwan ) Lpr -Z options now accumulate, rather than overwrite, if the Allow_duplicate_options flag is not set. This makes life easier for the user when specifying multiple -Z options. Allowed a LPR to LPD job transfer ending in a 'blank line' to be accepted. This is generated by some oddball LPR programs. (Reported by: Patrick Hildenbrand ) Release LPRng 3.4.5 Sun Mar 29 18:37:09 PST 1998 LPF: Cleaned up some minor nits with options. (Noticed by: Patrick Powell ) LPRng-HOWTO: A huge number of corrections from: (Tim Mooney mooney@dogbert.cc.ndsu.NoDak.edu) Enhancements: max_log_file_size, min_log_file_size Sometimes it is desireable to run a log file in order to try to find problems. But if you do not truncate the log file, it can grow to enormous lengths. The max_log_file_size#nnn (size in Kbytes, default = 0 or unlimited size) printcap/configuration variable will cause the LPD server to check for the size of the log file on opening it and if larger than max_log_file_size K bytes truncate it to min_log_file_size (default 0 specifies max_log_file_size/4) Kbytes. It preserves the last part of the file. Note that when the truncation operation occurs and there is heavy logging activity from multiple processes that the log file may get jumbled. Recommended value of max_log_file_size should be pretty large in order to make the truncation activity minimal - 10240 (10 Megabytes) is what I have been using with pretty reasonable success. Enhancements: The time of a job error is now logged in the hold file. This allows the time of the error to be determined. Bug Fixes: Modified reporting of subserver processes that have been killed off or have core dumped. This solved a problem with a system that would generate a SIGTERM signal. UTILS/accounting.pl fixed up. Also, psfilter and hpif now working correctly with the filter. (Patches, suggestions, and advice by: Gordon Haverland ) The LPD/lpd_jobs code for retrying has been redone to make it more robust when printing fails. The LPRng system will now agressively retry sending jobs. Needless to say, there are magic debugging flags to turn this off for testing purposes. (Noticed by: Jesse Off ) The bogus 'server starting' and 'server done' messages have been removed from the status file. Now send a trace/logging message before the job is finally put in the spool queue. Removes disturbing occurrence of 'success' messages being sent for a job that has not yet arrived according to log messages. More informative error messages and logging messages added at appropriate points. Release LPRng 3.4.4 Bug Fixes: termclear.c - tgetent() misdefined. Also, configure now checks for Solaris systems and tries to handle their brain damaged colliding definitions in term.h, curses.h, terminfo.h and termcap.h files. ignore_name_format_errors is now documented. Actually, it is really fix_bad_jobs. (Pointed out by: Bruce S. Marshall bmarsh@wwnet.com) Fixed a minor but annoying problem with hold files and very fast system. Better solution would be to have an indexed database, but it is almost more trouble than it is worth to implement. Fixed a problem with 'Destination' being a pointer to dynamically allocated memory, which would get deallocated by Set_job_status() calling Get_job_status(). Fixed a problem with control file names not being formatted correctly. (Reported by: John Perkins ) Fixed up LPRng-HOWTO, created new version. snprintf() used instead of plp_snprintf() (Reported by: lots and lots of folks, including "Reinhard Zierke" ) Release LPRng 3.4.3 Bug Fixes: Serial Port Configuration. Do_stty not called to set up serial ports. Reported by LOTs and LOTs of folks. Fixed the GetMaxServers() code to really find the maximum number of processes. (Fixes by: Don Badrak ) Memory Leaks From Hell Found them. Found the problem. Decided that fixing the problem was not worth it. Found an alternative method to the current one for starting processes that AVOIDS the memory leaks. In the new version of code, the LPD main() process will start subprocesses only when it needs to. Periodically, it will run down the list of print spools, starting (forking) a process. In the previous version, it would call the Setup_printer() code which would then in turn all the routines which would allocate (malloc) memory that would never get deleted. If there were jobs to be printed, the main() process would then fork and create a server process. In the current version, the main() process will create a pipe(), and then fork the child process, which will call the *&I*(&() Setup_printer() code, and then checks for work. If there is NO work, it exits (exit code 0), and as a side effect, the pipe is closed. The parent process will read 0 bytes, and say, 'Ah, No work'. As a side effect, it also gets the status. If there is work, the daughter will write a string to the pipe and THEN close the pipe. The parent will read the data, and say 'Ah, work to be done'. There are several elegant little side effects of this method. Firstly, the main() process will block until the child decides if there is work to be done. In effect, this will allows the child to proceed ASAP to the decision point. Secondly, the parent process has a VERY small amount of memory allocated, and does not grow at all large. This helps, as the children, when created, have very small memory needs and process creation is sped up tremendously. I am surprised to find just how much better this is... I probably should have done this before, but I was trying to avoid process creation problems, and ended up with large memory footprints. (Proddings, pokings, help, suggestions, and lots of tracking down by: Al Marquardt - who found the cause of the memory leak Branson Matheson - who came up with another memory leak If you ever want to debug memory leaks, please look at the malloc debugging package by Gary Watson. http://www.letters.com/dmalloc/ ) lpc move In the previous versions, lpc move only worked if the spool queue was active. This meant that you could not stop a spool queue and then move the jobs to a different queue. Now you can. However, if you redirect a queue, then it must be active for jobs to be redirected. C'est la Vie. (Reported by: Gary Cender ) Some logging numbers were not being reported correctly. They now should be. (Reported by: Gary Cender ) The QQ option was not working correctly due to a coding typo. (Reported by: Gary Cender , and others) LPR was doing translate_format, which was wrong. (Reported by: Chad Mynhier ) LPR does not use '-' as a flag to read from STDIN. Documentation changed to reflect this; easier than fixing LPRng... :-) (Reported by: "James P. Dugal" ) LPR now allows LOOOONG options to -Z. (Requested by: George Lindholm ) Race condition with job completion and testing for completion once again explored. Now err on the side of 'slow but correct' rather than 'fast but sloppy'. Only happens on FAST servers, and the alternative to run LPRng on slow servers was not taken well :-). (Reported by: Gary Cender ) OS/2 sends very odd control file format - now should parse this format correctly. (Reported by: "Patrick Hildenbrand") Release LPRng 3.4.2 Bug Fixes: Connect_timeout was not used uniformly or documented accurately. (Fixes by: Heinz-Ado Arnolds ) configure was too agressive in checking for -lresolv. Now includes -lresolv only if gethostbyname2 is not found. (Problem reported by: Uri Blumenthal ) It was observed that under heavy load conditions that some files were getting printed twice. This was due to a race condition. The race condition has been eliminated by introducing another field into the job control information specifying the subserver process id. Release LPRng 3.4.1 New Baseline Release - Stable version Enhancements: The configure script now supports setting the installation directories configure --with-lpddir=DIR --with-admindir=DIR - sets the install directory for lpd and lpc/checkpc respectively. (Patches by: Tim Mooney ) Added a 'retry_etimedout' flag as well to handle connections to devices that have a very long connection time due to slow network connections over dialup devices. The lpq status now will show 'stalled' when 'stalled_time' is non-zero and the job is active for more than stalled_time seconds. (Suggested by: lots of folks) The check_idle=program facility can now be used to check that a printer is idle before processing jobs. This is useful when you have multiple server queues. For example: lp:sv=lp1,lp2:... lp1:check_idle=/prog:... lp2:check_idle=/prog:... When the lp server starts up, it will check the lp1 and lp2 queues, and will only send jobs to the one whose check_idle program reports an idle condition. Bug Fixes: Updated LPRng-HOWTO. Fixed missing permission check checkpc. Also (correctly) implemented ${option} expansion in filter commands. This now gets expanded to the printcap option value, as documented. (Made by: Patrick Powell Release LPRng 3-3-7 Ports: Solaris 2.6. Also update README.install for new startup/shutdown script New functionality: reverse_lpq_format : reverse returned lpq status format when from specified host. There is a defect in some System V support for RFC1179 printers. The lpq facility will send a 'SHORT' status request when a 'LONG' is desired, and vice versa. This results in the wrong status format being returned. The reverse_lpq_format=(globhost|ip/mask)+ option allows you to specify that when a request is received from a host whose name or address matches an entry in the list, then SHORT/LONG format requests will be reversed. When the LPD is acting as an intermediate host, the reversed request will be sent to the next destination on the list. For example: reverse_lpq_format=*.eng.com,130.29.0.0/16 will select hosts whose FQDN ends in eng.com or in subnet 130.29 to have reversed lpq formats. return_short_status : return limited length status information short_status_length : number of lines to return Some users have expressed a desire to have the LPD server return short (i.e. - limited length) status to the requestor. The return_short_status=(globhost|ip/mask)+ option allows you to specify that when a request is received from a host whose name or address matches an entry in the list, then only short_status_length (default 3) Status: and Printer_status: lines returned. lpc redo command: this forces a job to be totally reprinted, if it has been held in the spool queue. This command has been added in order to allow the reprinting of jobs that have been printed and held in the spool queue, i.e. - the save_when_done printcap flag is set. routing filter 'priority N' output: the routing filter can set the destination, copies, and now the priority of jobs. If the routing filter output is: dest t1 CB priority B copies 2 end then two copies of the job will be routed to the destination with priority B, and the C line in the control file will be set to CB. safe_chars=nnn configuration file option. By default, LPRng detects and optionally eliminates suspicious characters from the control file; the fix_bad_job option will enable removal. The safe_chars=nnn specifies that in addition to the normal safe characters, the indicated ones can be used as well. For example, save_chars=#" will allow # and " to be used in the control file. Release LPRng 3-3-6 New functionality: Timeouts: send_job_rw_timeout, send_query_rw_timeout replace send_timeout The printcap send_job_rw_timeout and send_query_rw_status options now set timeouts on read/write operations when printing or sending jobs to a remote host or doing a status or query operation respectively. If the value is zero, there is no timeout on the operation. These timeout values and the associated read/write operations solve a problem when LPQ or LPR tries to attach to a printer or system which accepts a connection but then does not reply to the request in a reasonable amount of time. Note that the send_job_rw_timeout should be quite large (6000 or 100 minutes) in order to accommodate transient problems like paper outages on a printer. (Suggested by: Brad Rogers and Alek Komarnitsky ) lpc active, lpd, and reread commands The lpc active command will try to open a connection to the remote server. This allows non-LPRng remote servers to be polled to see if they are active. All of the active, lpd, and rereads now take a printer[@host] argument, allowing the specified server for the printer to be queried. (Deficiency noted by: James P. Dugal ) stop_on_abort printcap flag (default TRUE) If a filter aborts and this flag is TRUE then all further processing of the queue stops until restarted by some other action and the job will not be removed from the queue. max_connect_interval (default 60) maximum interval between attempts to send a job to a remote site. user_lpc configuration option, SERVICE=U, and lpc command There was a request to allow a selected set of lpc commands to be performed by users on their individual jobs in a queue. This has been accommodated using the following method. 1. A new user_lpc=cmd,cmd,... printcap operation enables the SERVICE=U permissions facility. The cmd can be: hold, release, move, topq, kill, and abort. 2. When the lpc command is checked for permissions by the LPD server, and the cmd is one of the specified in the user_lpc printcap, rejection is delayed until the point where individual jobs are checked for action. At this point a check for SERVICE=U is performed on the permission database. If, at this point the action is rejected OR the default action is to reject, the action will not be performed. 3. While users can perform a kill or abort operation, they can only do this while their job is active or at the top of the queue. Release LPRng 3-3-5 HOWTO and README: The HOWTO/LPRng-HOWTO has been extensively editted and extended. This will replace the README.* files in the distribution. Enhancements: configuration/printcap flag: force_localhost force_localhost forces client programs (lpq, lpr, lpc, lprm, etc) to connect to the server on the local host, as is done on the BSD LPR system. This option has an effect ONLY if you use the destination in the printcap information for the printer. If you explicitly specify a printer@host as the destination (-Pprinter@host) then the force_localhost flag is ignored. The default is force_localhost = TRUE. Question: why this flag? Answer: the Most Frequently Asked Question in the LPRng mailing list is from users asking why lpq/lpr/lprm does not send the job to the local server, and why they are sending them directly to the remote printer instead of spooling them. After having referenced folks to the documentation multiple times, I have thrown in the towel on this one and have put in this flag. Question: what does this change? Answer: If you are running a server on your system, jobs will be sent to the server and then spooled. You may need more spool queue space. If you want to use the "lpr_bounce" option, you will need to turn try_localhost and force_localhost OFF (:try_localhost@:force_localhost@:) to get the old behaviour and not have the job run through the filters by both LPR and LPD. Question: Wouldn't it be easier to ask people to read the documentation? Answer: No. I gave up asking. The LPRng behaviour was too different from the BSD LPD behaviour and folks who wanted a "rip out and replace" solution were too frustrated by the different behaviour. User Requested Status Information: lpr -mhost%port now causes LPD to open a UDP (by default) connection to port on host and send status updates for the job being processed. The form host%port,TCP will open a TCP port rather than a TCP port. Users can now use the monitor program (or a variant) to have job status reporting done. This has the side effect that mail addresses of the form host%port will not get mail sent to them. Routing Filters: During job reception, the :routing_filter: option specifies that the received job information is to be processed by a routing filter, which supplies additional destination information or modifications. STDIN of the filter is attached to the control file (read/write) and STDOUT of the filter should be the additional control/routing information. Note that routing filters that need to modify the control file can now do so by using FD 0 and making the modifications directly to the file. After processing by the routing filter, the control file will be re-read by the lpd server, and checked for correctness. See the HOWTO (/HOWTO/LPRng-HOWTO.html) for more information. Exit codes for routing filter: JSUCC (0) - processing continues; JHOLD - job will be held anything else - job will be removed (not accepted for printing) socket_linger#secs This option/flag has been added to solve a nasty problem involving closing network connections and process exit. When a process exits, the system will attempt to finish IO operations, flushing pending data to the destination. However, It has been observed that when the LPD process which is doing the actual printing exits, it will sometimes terminate and the last output is lost. Experiments have shown that when the SO_LINGER flag is set on these connections, the LPD process will not terminate until the last data has been transferred, which is the desired behavior. The 'socket_linger#nn' flag can be used to force setting the SO_LINGER timeout value. By default, this is now set to 10 seconds, which appears to be compatible with most TCP/IP connections. Note that the documentation is very blank on what happens when the connection is still "active" but no data is being transferred. If you are having problems with network connections and lost data at the end of jobs, try using: :socket_linger#120 in the printcap for the printer. LPRng executables default to SUID root at installation: By default, LPRng executables are now installed SUID root. This will reduce the number of problems encountered by folks who do not read the README.install instrucutions. (Noted by: Patrick Powell ) :remote_support=RMQVC (default) R = lpr, M = lprm, Q = lpq, V = verbose lpq, C = lpc : allowed operation This option specifies the allowed operations to a remote printer. This solves the problem of printer servers 'hanging on lpq', due to their inability to handle multiple requests. Note that the hang appears to be permanent - i.e. - the printer locks up. Thus, you should never do a lprm, lpq, or lpc operation to the printer. The :remote_support=R: setting will do this. :rg=group[,group] - allow clients to use printer only if user is a member of one of the specified groups. (Requested by: Oved Ben-Aroya ) Bug Fixes: After a LOOOONG study, the problem with non-LPRng servers terminating with 'out of space' error status has been resolved, and hopefully fixed. (Noted by: Patrick Powell ) Order of variables in sorted list was incorrect. (Noted by: Patrick Powell ) README.pgp_authentication referenced 'client_auth*' names; should be 'user_auth*' names. (Noted by: Patrick Powell ) The print job transfer (LPD/lpd_rcvjob.c) code has been reviewed, and the underlying method has been modified to accomodate reception of multiple jobs in a more consistent manner. 1. On start of job transmission, a 'lock file' is created. 2. Data and control files are placed in 'temporary files' during transfer. 3. At the end of job transfer, rename() is used to change temporary files to permanent ones. 4. The routing filter (if any) is invoked. Note that the data files are available for reference during this stage. 5. The control file is renamed to the final version. (Noted by: Patrick Powell ) The plp_waitpid() code has been extensively modified, together with the fdfork() code, the killchildren() support, and the Print_abort() code. Hopefully, this will now solve the problems of processes not being terminated and/or zombies accumulating. This has the (desirable!) side effect that child exits will not cause system calls to terminate with EINTR status. (Noted by: Patrick Powell ) By default, LPRng executables are now installed SUID root. This will reduce the number of problems encountered by folks who do not read the README.install instrucutions. (Noted by: Patrick Powell ) Race condition with Set_control_info fixed. Now file locking works correctly. (Noted by: Patrick Powell ) For HP configurations and no GCC, added a -Aa flag to CFLAGS (Suggested by: Brad Rogers ) The logger support was flawed somewhat. Previously, each process would open a socket (connection) to the logger - this would soon use up a lot of connections. Now the LPD server opens a connection at initialization, which is then inherited by the various processes. (Found by: Desmond Macauley ) By default, LPRng executables are now installed SUID root. This will reduce the number of problems encountered by folks who do not read the README.install instrucutions. (Noted by: Patrick Powell ) The SERVER permissions checking did not handle localhost correctly. (Noted by: Patrick Powell ) Passed the PRINTCAP_ENTRY to routing filters and control file filters. (Patch by: George Lindholm ) Only LPD now does killpg() otherwise this effects output from the lpq, lpc, etc., programs. (Noted by: Patrick Powell ) Jobs were being thrown away with Send_try#0 (Patch by: George Lindholm ) Release LPRng 3-3-4 Enhancements: When using routing_filters to cause jobs to be sent to multiple destinations, you might want LPQ to report the status of the destinations as well. The 'destinations=pr1,pr2,pr3' will now case LPQ to report the status of destination queues. (Work, patches, and slugging by: George Lindholm ) LPR and LPRM duplicate arguments: Some users would like LPR's and LPRM's arguments to be 'cumlative', i.e. - lpr -a x -a y would be identical to lpr -a The allow_duplicate_args configuration flag will now enable this behaviour. Also, by default the class name and the job priority are identical. The break_classname_priority_link flag breaks this link, and the class can be specified separately from the priority. Also, the maximum classname size specified by RFC1179 is 32 characters; the 'classname_length#nnn' (default 31) allows a longer classname to be used. (Patches supplied by: George Lindholm ) Bug Fixes: checkpc -p and -c options were not functioning as documented. (Noted by: Christophe Kalt ) README.bouncequeues indicated that exit status returned by the control_filter program was used to control job processing. README and common/fixcontrol.c updated to agree. When control_ filter exits with: JSUCC (0) - normal processing, JHOLD (37) job is held, JREMOVE, job removed, etc. (Noted by: George Lindholm ) Generate_banner did not put banner in correct position. (Reported by: Jost Krieger ) LPD/lpd_rcvjob.c - control file is now written to a temp file and then renamed as the control file. This elminates problems with locks. (Suggested by: George Lindholm ) Release LPRng 3-3-3 Updated the sample lpd.perm, README's to use the 'REMOTEUSER' rather than USER in the permissions value. (Spotted by: Chen Shiyuan ) Cleaned up filter and server killing code - added more robust exit and abort facilities. This was done in several places in order to try to make sure that processes created for filters would be killed off when the server process exited. Cleaned up logging and some minor error messages. Removed 'intl/po2tbl.sed' and 'po/POTFILES' from distribution. (Noted by: George Lindholm ) Release LPRng 3-3-2 Thu Oct 9 20:03:30 PDT 1997 lpr, lpq,... usage message formats fixed. (Patches by: Jan Barte ) Autohold support was accidentally removed from LPD/lpd_rcvjob.c Release LPRng 3-3-1 New Baseline Tue Oct 7 18:29:55 PDT 1997 Comments: README.account updated to show how to use psfilter and CTI-hpif filters and accounting scripts. Bug Fixes: Permissions checking patch did not work correctly. Patcher patched patch to make patchwork code work correctly. (Originator of patch: Simon Wilkinson ) Release LPRng 3-2-12 Bug Fixes: The sample lpd.conf file had ff=\\f which confused folks. Now it has correct syntax. The end of job and Print_abort code has been clean up and modified so that exit is now fast and brutal. When you do LPRM you now GET LPRM action fast and quick, and no processes hanging around. The code for reporting fatal 'filter errors' has been modified to put the termination conditions into the LPQ status report. This will simplify the job of finding out why your job died much easier. Jobs that now exceed their maximum number of print attempts are deleted by default instead of being retried indefinately. This can be be suppressed by setting retry to 0, as documented. The above bugs/changes were the result of a long standing report of the LPD server being slow to respond when printing bad jobs. (Added by: Patrick Powell ) Release LPRng 3-2-11 Enhancements: printcap/configuration 'network_connect_grace#nnn' variable is similar to the 'connect_grace' variable, but pauses for the specified time between connections to LPD or other servers. Useful when using LPD prototcol to network based printers that need some recovery time between jobs. (Suggested by: Christian Illinger ) Bug Fixes: all:all=p1,p2,p3 did not check correctly for separators. (Reported by: Bertrand Decouty ) configure.in - checks for random() defined in stdlib.h (Suggested by: Bernhard Rosenkraenzer ) Logging: the JOBNUMBER is now reported correctly. (Reported by: Gary Cender ) LPC move: the job is deleted from the queue after being moved, even if save_when_done is set. (Requested by: Gary Cender ) Release LPRng 3-2-10 Bug Fixes: In cleaning up the routing support in LPD/lpd_jobs.c and LPD/lpd_rcv.c, I cleaned it up so much that only the first routed job was printed. (Reported by: Gary Cender ) Release LPRng 3-2-9 Bug Fixes: Typo in src/common/linksupport.c caused very wierd error messages to be printed. (Reported by: lots and lots of people) Release LPRng 3-2-8 Bug Fixes: snprintf used instead of plp_snprintf() (Reported by: Dirk Wrocklage and Helmut Jarausch ) Max_servers code did not function correctly - there was a logic error in the design. As a result, it would lock up and refuse incoming jobs. (Reported by: Jim Stosick ) Poll_time: Under certain very odd conditions, a spool queue could have a job in it and the LPD server would not fork a process to serve the queue. The poll_time (default 6000 seconds) is a timer that will scan the print queues for a pending job and no server. The previous version had a race condition in it that would periodically spawn too many servers. The new code not only fixes this problem, but also enforces a true idle condition on the lpd server. If there is no activity and no jobs, then the server will not periodically wake up and check the spool queues. Force_poll: Some users have software that places jobs in the spool queues, and want LPRng to periodically poll the queues for these jobs. The 'force_poll' flag has been added to provide this functionality. Release LPRng 3-2-7 Major Revisions: Hold file names and creation: When the server creates a job in a job queue, it also creates a hold file along with the data and control file in the spool queue directory. During job processing the hold file is updated by various processes. As a result, this file must be locked and carefully updated. The implemented method of locking and holding locks for jobs was flawed, resulting in race conditions, etc. The routines responsible for reading and writing hold files are Lock_job_control, Get_job_control and Set_job_control. These have been modified as follows. 0. A Lock_job_control() routine now generates and locks a control file. 1. The Get_job_control() routine may now open the job file in a LOCKED or UNLOCKED mode. It will open the file UNLOCKED if not passed a file descriptor (FD) created by Lock_job_control(), reads the file and then closes the file if not locked. 2. The Set_job_control() file now updates the hold file as follows. a) It creates a temporary file (open, locked). This file has the name _fAnnn, while the lock file is cfAnnn. b) It writes the job file to the temporary file. c) It RENAMES the temporary file to the hold file. d) If it has been passed a FD created by Lock_job_control() it will close the passed FD and return the locked FD; the effect is to maintain the lock on the control file. e) if not passed an FD, it simply closes the FD, effectively releasing the lock. This functionality guarantees the following: 1. While there might be a race condition in time over a particular control file, the Get_job_control() routine will always open either a 0 length hold file (i.e. - file is in an initial state) or a VALID COMPLETE non-zero length hold file. 2. Get_job_control() (no lock) will always read correct status information or NO status information. 3. If a Write operation is needed, Set_job_control() does this correctly and indivisibly. 4. If a Read/Modify/Write is needed, Get_job_control() is requested to read and lock the file, and then Set_job_control is used to modify the information. Hold File Name Format: In order to guarantee that jobs placed into the hold file have unique job numbers, i.e. - so you can reference them by job number, the hold file name format is now hfAnnn. Note that this means the host name is now not used. The Find_unique_job_number() routine will attempt to find and create a hold file with a unique job number in the queue. Jobs Placed In Queues Always Get Unique Job Numbers: In the previous version of LPRng, when a job was placed in a queue with an existing job with the same control file name, the job overwrote the existing job. This had some interesting side effects, mostly concerned with duplicate jobs. If you have the 'Save Job After Printing' flag set, you may run out of job numbers. Full_time printcap/lpd.conf flag Specifies that you want to have a full year-mo-dy-hr:... time format in log and status message. Binding to random ports The RFC1179 specifies connections must originate from port 721-731; most BSD implementations relax this to 512-1023. There is a problem when trying to reuse a port and connecting to the same system; TCP/IP requires about a 10 minute timeout on a IP:port/IP:port pair. The code that tried to do connections originally tried the ports in sequential order, leading to long delays. Now it will try them in RANDOM order, and will try at most 'connect_try' ports at a time before admitting failure. Bug Fixes: Minor nit with lpc commands fussing about RemotePrinter values. (Reported and patch by: Martin Pahl ) File descriptors are lost if the remote system that we are trying to send a job to doesn't like the printer name we are trying to use. (Reported by: George Lindholm ) Permissions checking for PRINTER=host,@netgroup was done incorrectly. checking now done by match_pr(). (Reported by: Sergio Tessaris and Warren Marts ) Problems with Get_perms() when rereading the permissions database. The actual problem was trying to be too tricky and preallocate data structures. When this was done incorrectly, you had some very odd results when rereading the same database. LPR: when printing multiple files, data files were duplicated. i.e. - dfA..., dfB..., ..., dfZ..., dfA... Fixed LPR/lpr_cpyjobs.c so that now we have dfA... dfZ, dfa..., dfz (Reported by: Simon Wilkinson ) User detected a bug where the "-r" option to LPR (LPRng 3.2.6) actually removes files even if the job was not spooled successfully. my patch to fix this problem. Updated LPR man page to reflect the dreaded -r (remove after printing) option. (Reported and Fixed by: Garrett D'Amore" ) Permissions checks for group did not check the group id, just the user name. (Reported and Fixed by: Simon Wilkinson ) Race conditions src/LPD/lpd_jobs.c between printer server and worker process caused a null pointer reference. (Reported and Fixed by: George Lindholm ) Checkpc did not use correct lockfile format. (Reported by: Jan Barte ) When routing a file, the route Xnnnn information was not used. Updated Fix_control to use this information as per documentation. (Reported by: Patrick Powell ) Control file not reparsed after 'control_filter' processing. It is now reparsed, and only the new contents are sent to the destination. This includes the data files. The control file filter MUST remove excess data files. End of job accounting to a remote server was erroneously expecting an 'ACCEPT' reply. Fixed. (Reported by: Markus Fleck ) Release LPRng 3-2-6 README.accounting, lpd.8, printcap.5 man pages - accounting file is documented as not being created. (Reported by: Christophe Kalt ) LPRM/LPD did not forward remove commands correctly. (Reported by: Paul Zablosky ) Permissions: PRINTER attribute can now be a netgroup. This allows things like: ACCEPT SERVICE=R,P PRINTER=@PRIP_printers REMOTEGROUP=@PRIP_users REJECT SERVICE=X,R,P PRINTER=@PRIP_printers makes management of printers... easier... I suppose. Updated lpd.perms.5 as well. (Suggested by: John R Lane ) Removed mention of "co" flag (obsolete) from lpd.conf man page. (Reported by Klaus Steinberger ) HP/UX version 10.x needs to use termiox IOCTL call to set hardware handshaking on. (Reported and patches supplied by: Klaus Steinberger ) lpc printcap command now only needs STATUS (S) privileges. New DEFAULTQ protocol message added. This allows lpc to request the default queue used by LPD. fix_bad_job flag now ignores duplicate control lines, and replaces bad characters with blanks in control file. Release LPRng 3-2-5 configure: now checks to see if inet_ntop() is in resolver library (-lresolv), and includes it when doing checks for other functions. termclear now uses IS_LINUX instead of __linux__ (Reported and fixed by: Horst ) memory leak fix of 3-2-4 interacted with other code in unexpected manner - revised memory fix. (Reported and fixed by: Patrick Powell ) LPD/lpd_status.c - status display line length now controlled by max_status_line configuration/printcap variable, which allows the maximum line length to be exceeded if desired. Default is still 79. src/Makefile.in COMPILATION FLAG: STRICT_RFC1179 default originate_port value is now 512 - 1022, rather than RFC1179's 721 - 731. compiling with -DSTRICT_RFC1179 sets the default to 721 - 731. Release LPRng 3-2-4 LPD - pursued and found an extremely minor memory leak that was exercised only under a very unusual set of conditions. (Reported and fixed by: Patrick Powell ) Batch of patches and errors: Tom Bertelson include/portable.h - minor changes in SUNOS prototypes CHECKPC/checkpc_port.c - better check to see if setproctitle worked PAIR() macro has added guards for _PROTO_ problems rw_pipe() has a minor portability problem clean up. LPQ, LPR, LPRM option checks were done incorrectly. (Reported by: Scott Nelson ) umask(0177) should really be umask(0077) to allow correct directory permissions checking. (Reported and fixed by: Guy Geens ) lpd - the lpc reread function sends a signal to the LPD server, which then calls 'Read_pc' from a signal handler. This can cause problems. In addition, there was a memory leak in the Read_pc() routine. (Reported by: Rainer Schoepf ) Release LPRng 3-2-3 BUG FIXES: src/Makefile(Makefile.in), man/Makefile.in did not do 'make install prefix=/xxxx' operations correctly. (Reported by: Chris O'Regan ) Get_remote_hostbyaddr() used host_ent when it was undefine/null. (Reported by: Carson Gaspar ) Patch for HAVE_SIGLONGJMP did not include common/timeout.c and include/portable.h. (Reported and fixed by: Guy Geens ) Release LPRng 3-2-2 BUG FIXES: Not freeing memory allocated by Expand_value(). (Reported by: "Todd C. Miller" ) Added logging for non-job related operations. Added finer time resolution on job changes (Requested by: Chao-Wen Young ) Added LPDEST environment variable for printer as well as PRINTER and NGPRINTER (Suggested by: Garrett D'Amore ) Moved Print_flush() to Print_abort(). (Motivated by: Gerhard Schneider ) MONITOR/monitor.c had duplicate include references. This caused some portability problems with systems that did not have 'guards' in their include files for multiple inclusion. (Reported by: John Perkins ) lpstat format fixes. (Reported and Fixes: Carson Gaspar ) common/getqueue() rejects control files with duplicate remove lines - this is not a big problem, so added code to ignore them. (Reported and Fixes: Frank Terhaar-Yonkers ) Release LPRng 3-2-1 Baseline Release Release LPRng 3-1-13 Changed sleep() calls to plp_sleep(), which uses select mechanism, to avoid interactions with SIGALRM signal handler in Linux. In the waitchild() code, the signal(SIGCHLD,SIG_IGN) caused some systems to automatically perform a 'wait()' on child processes. The SIG_DFL only ignored the signal, and the waitpid() would then succeed. Note that this action is implied by the POSIX standard wording for _exit(). The code for job queue scanning will not report 0 length control files as errors until they are older than an hour. The LPD/lpq_status() now ignores jobs being transferred, and does not report their status. LPD/lpd_rcvjob() now allows multiple jobs to be transferred on a single connection. This is a violation of RFC1179 but it is now done. Expanded \xx entries in Banner line, so that very strange filters that insisted on these characters would get them. If a banner line had these characters, a \n is not appended. Bounce queue destinations no longer have to be printer@host, they can just be printer. The default destination is the server host. CHECKPC/checkpc.c - To_root() interferred with Test_code(); reordered code. (Reported by: Todd Rannow ) common/check_remotehost() - added checks for Is_server, moved some tests into LPD/lpd_status.c, LPD/lpd_remove.c (Reported by: Damon W Atkins ) Solaris 2.4 LPD server insists on sending REQ_START messages - and gets peeved when it gets an error. Now messages are NOOPs. (Reported and fix suggested by: Jussi Eloranta ) Read_fd_len_timeout() closed fd on timeout - this was not correct behaviour. (Reported by: Todd Rannow ) Clients (LPR, LPQ, LPC) were not expanding printcap %P, %H, etc., entries. (Reported by: Damon W Atkins ) Release LPRng 3-1-12 Check_remote modifications exposed logic error in various places- need checks for both RemotePrinter and RemoteHost, not just RemoteHost. Release LPRng 3-1-11 Missing check for Is_server in Check_remote() caused clients to not connect to LPD server. Release LPRng 3-1-10 LPR/lpr_cpyfiles() did not handle multiple copies of stdin correctly. (Reported and fixed by: Jens Thiel ) Problem with bad printer name detection. (Reported and fixed by: Martin Pahl ) setstatus() was not sending STATUS information to the logger. (Reported by: Chao-Wen Young ) Bad non-existent printer, printcap file misconfiguration code. (Reported and fixed by: Dirk Nitschke ) Documentation and man page editting - minor corrections, missing entries. (Comments and patches by: Florian La Roche ) Release LPRng 3-1-9 lpq -v format modified so Destination was printed correctly. Remove_job() did not remove all the data files or hold files. dofork() did not zero Tempfile->pathlen. LPR/lpr_cpyfiles() did not preallocate the job file array, leading to problems when realloc() was called. printcap(5) and lpd.conf(5) man page cleanup. (Done by: Florian La Roche ) Release LPRng 3-1-8 Print_job() did not use correct queue name. Man Pages did not get right version number. force_queuename not in printcap(5) man page. (Reported by: Guy Geens ) In LPC, Queue_name is not NULL when getprinter() is called. (Reported by: Jussi Eloranta ) The filter environment variable PRINTCAP_ENTRY now holds the printcap entry for the printer. In conflict with some filters using PRINTCAP to hold the pathname of the /etc/printcap file. (Reported by: Guy Geens ) waitchild() had an alternate wait3 implementation that turns out to be broken on some systems. Force use of the waitpid() version. Release LPRng 3-1-7 New Functionality: poll_time configuration variable There is a small, but almost impossible to eliminate, race condition when a job is put into a busy queue. If the server process checks to see if there is work to be done, and the job is put into the queue after that point, then there is a possiblity that the server may exit with a job in the queue. This can be solved by using semaphores, locks, etc., but is almost impossible to do in a portable and efficient manner. The 'poll_time#nnn' configuration entry has been added to allow the administrator to specify an interval at which the queues can be periodically checked for unprinted jobs. The default poll_time value is 6000, i.e. - 10 minutes. Bug Fixes: printcap.5 documents :mi: (spool directory space needed) as number but it is a string. Fixed documentation. (Reported by: Jeff Bacon ) Install.txt, Install.ps - lp=host%port misdocumented. (Reported by: Jeff Bacon ) printjob.c - check to see if there is a filter; if not, shove file directly out. (Reported by: Guy Geens ) src/Makefile - SUID_ROOT_PERMS= 04755 -oroot should be -o root (Reported by: Dave Goldhammer ) POSIX uses LOGNAME environment variable - check this first, then USER for user information. (Suggested by: Todd C. Miller ) lpc now allows printer@host specification. (Reported by: Doug White ) printer queue loop detection algorithm modified The code to detect print queue loops was too agressive, and gave false warnings about print queue loops. Now only checks for explicit loops. (Reported by: Yuji Shinozaki ) Start_all() code did not check for a limit on the number of processes that would be started by the server. Release LPRng 3-1-6 Bug Fixes: The :direct_read: flag now works for bounce queues. Tested with aps filter. The aps filter distribution of globals/GLOBALS.sh has been modified to have defaults for various options that allows even a (possibly) misconfigured filter to produce some sort of output instead of dying with a strange error message. setstatus() was not putting \n on end of lines, but only when used on Solaris 4.1.4 with Sun's ACC compiler. Compiler bug. Rather than fix the compiler, we (hopefully) modify the code. (Reported by: Reinhard Zierke ) LPSTAT simulation: Progress reporting too coarse. lpstat -s too verbose. lp now reports 'request id is ....' (Reported by: David Livingstone ) Release LPRng 3-1-5 New Functionality: PCNFSD compatibility PCNFSD - Public Domain version, from Geoff Arnold (Geoff.Arnold@Sun.COM, geoff@East.Sun.COM). Assumes that LPC will return list of printers, indented one space. (Fixed). Added README.pcnfsd as a guideline for users. LPRM now says 'dequeueing' (yech!) instead of 'removing' to make it consistent with lprm and PCNFSD implementations. PCNFSD distribution put into LPRng collection. Bug Fixes: cleanup() was causing early exits due to use of killpg(); commands such as lpq |more would not work correctly. Fix was to suppress top level process from killing itself. autoconf bizzarness - src/Makefile.in now has ${prefix} entries to match the INSTALL documentation. You can now do make prefix=xxx and software will be installed in xxx/bin Default directories made to conform with existing LPRng ones, not Linux/GNU ones. LPD/lpd_jobs: when a job is aborted, the return status is clobbered. Now it is not clobbered. Release LPRng 3-1-4 New Functionality - :oh: entry does globmatch on FQDN host name. The :oh=*val*: entry can now be used to do matching on the FQDN host name. This allows such things as defining classes of printers, i.e.: lp:oh=*lab1*:lp=pr1@server lp:oh=*lab2*:lp=pr2@server (Inspired by: Nathan Neulinger ) Bug Fixes: Debugging stuff added to Is_printable(); LPR/lpr.c and company had the control file generation fixed up so that lpr -K worked correctly when taking input from stdin; also when using it with lpr_bounce. (Reported by: Andrew Leahy ) autoconf Version 2-12 has a bug and was not generating configuration files correctly; fixed this and now the --exec_prefix option appears to work correctly. To regenerate configure from configure.in, the following acgeneral.m4 file lines must be changed: .... original ..... test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' .... correct ...... test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" Permissions checking in Is_printable() was erroneous. (Reported by: Dirk Nitschke ) Find_non_colliding_job_number() did not check to see if job priority was available, and was generating bogus hold file names. This only occurs when data files are sent first. Release LPRng 3-1-3 New Functionality - Kerberos authentication uses encryption Send encrypted and authenticated information by default. (Greateful thanks to: Ken Hornstein ) Bug Fixes: Fix_str(): missing null pointer check (Reported by: Christian Kuehnke" ) Release LPRng 3-1-2 New Functionality - glob matches for printer names: At USENIX97, somebody mentioned that they wanted to have a 'wildcard' entry that would allow them to 'trap' all sorts of printers, and then do formatting based on the printer name. I puzzled over this, until I realized that the combination of the :qq: (put queue name in job) and a wildcard match would do exactly what this person wanted. The more I thought about it, more functionality seemed to be provided by this - you could match various arcane printer names against patterns, etc. Now when a job arrives and the LPD server is searching for the queue name, the search is done using a glob match. Note that you cannot have a primary printer name with a GLOB character, but it is allowed to have an alias with one. For example: pr1|pr*|all printers which start with pr :lp=pr1@host :qq pr2|*|wildcard match :lp=pr2@host :qq New Functionality - munging control files: There is now a 'control_filter' option that will cause the control file to be passed through a filter. This takes place only when a job is transferred to a remote printer. It was intended to be used by bounce queues whose destination required extremely whacko formats for their control files. See README.bouncequeues for details. New Functionality - generating banner pages for remote printers: The :generate_banner: printcap option will now generate a banner page for remote print jobs and/or when using LPR and :lpr_bounce: is set. The banner is generated by the banner printer specified by :bp: or the default banner printer. If the :hl: (header or banner last) flag is set, it will be the last part of the job printed. New Functionality - spreading job numbers to avoid collisions: Some users have been encountering job number collisions when using the routing facility and making multiple copies. The "spread_jobs" printcap and configuration variable now allows you to spread out job numbers by the indicated factor. The job number is based on the process id; jobnumber = processid * spread_jobs; Under heavy use, this value should be set to the expected maximum number of jobs copies that will be made. Fixes and Extensions: fixcontrol.c - badly formatted DEBUG message. (Reported by: Reinhard Zierke ) configure - cray-unicos is now just unicos in the system targets. In addition, HAVE_SYS_SIGLIST botches have been fixed. fix_create_dir() segment faulted (Reported by: Reinhard Zierke ) LINUX has undocumented (and in my opinion broken) gethostbyname() and gethostbyaddr() interactions. The code that does lookup now performs extremely picky checks, copies, etc., to avoid problems with this. (Reported by: just about every LINUX user...) Makefile: install was missing a value. (Reported by: Doug White ) :bk: (Backwards compatible) now forces short job names and short job numbers as well. LPC - lpq command now takes the last printer specified as its default. (Suggested by: Jeff Bacon ) IRIX and UNICOS compilation mods. (Suggested by: Paul Burry ) Aborted LPR caused 0 length files to be left in spool directory Multiple copies and routing interact (Andrew Leahy ) config.sub now recognizes i686 as a proper machine type. (Reported by: Michel Robitaille ) Release LPRng 3-1-1 New Functionality: Support for client to server and server to server authentication. See README.authentication and lpd(8) man page, as well as README.pgp_authentication. Currently, pgp is supported for client to server and server to server authentication; Kerberos is supported for client to server authentication. Printcap entries can contain the following: %a - architecture %H - fully qualified domain name of host %h - shost host name %P - printer (when in printcap entry) %R - remote printer (when in printcap entry) %M - remote host (when in printcap entry) This is the same as for the configuration information. Note that these keys are marked by %; keys marked with $ such as $P are expanded only when used by filters. Currently only the :sd: (spool directory), :server_user:, and :remote_user: (for authentication) are expanded. Support for lp(1) simulation (Solaris SystemV R4) print facilities now built in. This is done by checking the name that the program is invoked with: lpr invoked as lp - simulates lp operation lpq invoked as lpstat - simulates lpstat operation lprm invoked as cancel - simulates cancel operation Note that this is not full functionality, but it will provide a usable interface for programs that need lp, lpstat, and clean. man pages updated and rewritten to reflect latest changes. IPV6 awareness is being planned for. The permissions checking is now done assuming that information returned by gethostbyname() and/or gethostbyaddr() may be for IPV6. Host names checking is done not only on the cannonical (main) host name, but also for aliases; the IFIP permissions check has been added to allow access to the IP address reported by the accept() system call that reported a connection. See README.lpd.perms for details. A new printcap flag, :direct_write: now passes a file descriptor to print filters. This is backwards compatible with the old BSD filters, but you lose the ability to monitor the printing process. In addition, you are stuck with 'send_timeout' seconds for printing a job, which may not be suitable if a job hangs up on a printer. Makefiles compatible with the BSD make are now provided; these are generated from the basic Makefiles using a simple conversion script. Of course, the Makefiles were redone in order to make this feasible... LPR now can do filtering if the :lpr_bounce: flag is set. LPR Protocol Extensions: REQ_SECURE: an authenticated transfer of job and control information. See the details in the README.authenticate and lpd.8 man page. REQ_VERBOSE: provides a hideously detailed set of information about the print queues and their status. This is of interest to persons who are trying to provide tracking for jobs and other information and need more than the status provided by the high level LPQ dumps. The LPQ -v format now will generate this. LPQ and Status Generation LPQ now prints each queue status once. In addition, when getting status, LPD makes a valiant effort to avoid forking and creating processes. This makes things much more easy on the system load. Source Code Reorganization: A major source code reorganization was done in order to support configuration management tools in a more effective way. System configuration and printcap initialization is now done by the values in the lpd.conf file, which can contain printcap flags as well as configuration information. This allows defaults to be set in a much simpler manner. Beta Testers: Pseudo Anonymous, Bertrand Decouty-INRIA Rennes-France Dirk Nitschke Paul Burry Thierry.Besancon@lps.ens.fr (Thierry BESANCON) Fixes and Extensions: configure and Makefile support for CRAY (by Paul Burry ) using the lpc class facilities now prevents held class jobs from being printed. (Reported by: Chao-Wen Young ) gethostbyname() has a possible problem. Added checks for parameters. (Reported by: Jens Thiel ) printcap '@' operator did not set clear entries. (Reported by: Park Jae-hyon ) filter error code 'JFAIL' now causes job removal. (Reported by: Norman R. McBride ) LPD now checks for the number of servers it has active; Max_servers_active configuration variable sets this. In addition, uses the getrlimit() to determine real value if available. This should throttle back problems when a lot of LPR connections are being made and the server proceeds to die or lose jobs. getconnection() now tries to open a connection with different originating ports. This solves a problem with some systems that did not like LPRng originating connections from the same reserved ports. Users encountering this difficulty might have to use a wider port range; this can be done now by modifying the printcap entry for the printer. checkpc now has Is_server set to 1, so it should do the full server compatibility checks. Queuename not being set correctly. (Reported by: Thierry.Besancon ) LPC now calls 'lpq' via a bombproofed system() call (Suggested by Paul Burry ). LPR now generates correct job names for more than 26 files. (Reported by: Guy Geens ) Release LPRng 2-4-3 New Functionality: Printcap Files The printcap reading and configuration file reading code now supports the following: 1. you can have multiple :tc=name: references. 2. printcap entries whose main name starts with a punctuation character is not used as a printer. However, it can be referenced by :tc=: entries. For example, the following shows how to use this facility. @filter:if=/bin/whatever:of=/bin/whatever @banner:sh:sb @spool:sd=/var/spool/%P p1:tc=@filter:tc=@banner:@spool In addition, the following printcap entries have %P (printer), %h (short host name), and %H (Fully qualfied domain name of host) replaced by the current values before jobs are processed; other values are ignored and replaced by which space. A %% is replaced by a single '%'. The variables which are expanded are controlled by the flags value of the src/printcap.c/Pc_var_list[] array; currently the following are expanded: :sd=: (spool directory) Device Locking: This code was originally put in place for systems where you might have multiple people trying to use a printing device. The 'lk' flag now controls if you want to lock the IO device. Default is no locking. Portability Fixes: Quicksort is not a stable sorting algorithm - if two entries are identical, then their position can be reversed. The order of entries is important and needs to be preserved when reading information, so mergesort() is now used. The organization of the include files was causing problems with testing packages. There is now one include file for each major functional component. Global variables are now in a single file, and are the same for all packages. The difference in size of the executables was minor. Bug Fixes: Printcap reading code: now handles forward references correctly. (Reported by: Klaus Steinberger ) Ruthless purging of metacharacters passed to filters. This includes quotes, backslashes, and all other even vaugely funny characters. (Reported by:Bertrand Decouty-INRIA Rennes-France ) Release LPRng 2-4-2 Missing REMOTEGROUP check in permissions.c (Reported: Michel Robitaille ) configure.in: Added more robust check for undefined functions on various systems, added checks in source code for various variants: termclear.c, gethostinfo.c (Reported by: Doug White , Sven Rudolph ) LPQ: status line now too long, truncated it to 79 chars. LPD: time of day format changed to YY/MM/DD/HH:MM:SS LPC: autohold and noautohold command changed to 'holdall' and 'noholdall'; LPQ: autohold and holdall status reporting added. lockfile.c: Added #if !defined(LOCKDEV) code to not do locking on serial devices. (Reported by: bennett@nomolog.nagoya-u.ac.jp (Bennett)) Printcap printer names: primary printer names starting with punctuation are now treated as simply entries and not valid names. This means that they can be referenced as tc=@name, i.e. @name:if=/whatever prname:tc=@name Multiple Server Queues: ss/sv code reworked again - got rid of several race conditions, lost files. Routing filters: added code to handle dropped jobs better. Release LPRng 2-4-1 minor problems with Makefiles, portability fixes. (Reported by: Michel Robitaille ) malloclist.c error message format wrong. (Reported by: Jens Thiel ) Release LPRng 2-3-14 New Functionality: Jobs are now sorted by priority. (Reported by: syl@ecmwf.int (Lennart Sorth)) LPC CLASS option added. Classes of jobs can now be held and/or released. lpc class printer A,B,C would release jobs with classes A,B,C; lpc class printer J=*form1* would release jobs whose job name contained the form1 string. (Requested by: garyc@eng.dowjones.com (Gary Cender)) Printcap and Configuration :send_failure_action: when a job fails to be printed or transferred, it is automatically retried :rt: (:send_try: or configuration send_try) times. A 0 :rt: means infinite retries. It may be desirable under various circumstances to have a method of dynmaically deciding if an error threshold is exceeded or some other action is needed. The :send_failure_action: printcap and/or configuration variable specifies the default action when :rt: is exceeded. It can have the following form: 1. The string "success", "abort", "retry", "ignore", "hold" which will cause the job/spooler to treat as successful, abort, retry, ignore, or hold the job respectively. 2. A filter of the form: |/filtername. The filter is executed with the default set of filter options, and the number of attempts is printed to its standard input. It can print error messages to standard error, which are placed in the spool error log. The exit codes JSUCC (0), JFAIL (1 or 32), JABORT (2 or 33), and JREMOVE (3 or 34), JIGNORE (5 or 36), etc. will force removal as if successful, retry, etc. as for the text form. README.nis: new script for creating NIS (YP) databases. (Contributed by: Sven Rudolph ) LPF: modified the -T option, added -D (debug level option) (Contributed by: Sven Rudolph ) LPD cannot be started from inetd. This functionality puts a very heavy load on the system and trying to make it function correctly was very difficult. Makefile: PREFIX variable defined, to allow overriding default prefix value. (Suggested by: Sven Rudolph ) Major Fixes: File Locking: The code for dealing with file locking and job name collision was not sufficient to handle the case where multiple jobs were being submitted simultaneously. The new code uses the hold file for locking jobs, in addition to locking the control file. When a job is submitted via LPR or forwarding, the hold file is created, written with the receiving process PID, and is then released. When other processes try to submit a job, they will lock the hold file, check for the running process, and then try anther job if the process is still delivering the job files. When all of the job files are delivered, the process will then write the hold file with -1, i.e. - a signal that all files have been delivered. If a job is submitted by other means, i.e.- copied directly to the spool directory, there is no guarantee that collisions can be avoided. Note that sometimes hold files will be left in the spool queue, but these can be clean up periodically by using checkpc for example. Bug Fixes and/or Deficiencies: Added Hold_all variable that is controlled by LPC command - :ah: printcap entry cannot be overridden now. (Reported by: garyc@eng.dowjones.com (Gary Cender)) LPD/lpd_control.c: STOP was killing off server; now it prevents next job from being started. common/printjob.c/Fix_string() - missing check for 0 length string. (Zygo Blaxell ) Printing filter exit codes 1->5 are translated to JFAIL->JABORT This makes vintage filters compatible with LPRng. Find_key() can return a 0 value under extreme circumstances - 0 check added. (Reported by: Ron Roskens ) lpr -l or lpr -b did not get IF filter invoked with -c option. (Reported by:Bertrand Decouty-INRIA Rennes-France ) trailers are not sent to printers; caused by premature close of output. (Reported and Fix by: Helmut Jarausch ) permissions checking once again has a problem - if no match is found incorrect use of defaults. (Reported by: QingLong ) LPQ: queue status not reported correctly. Caused by a memory leak, and also incorrect buffer length specified to allocation routine. (Reported by: Bertrand Decouty-INRIA Rennes-France ) Release LPRng 2-3-13 Linux has inconsistent ncurses (curses.h) and termlib (termlib.h) definitions for tgetent(). Use only one. (Reported by Elliot Lee ) The 'printed 10% of 1000 bytes" message gets scambled when processed by other systems where the % is interpreted as a format character by printf. Changed to 'percent' instead. (From: Bertrand Decouty-INRIA Rennes-France ) Release LPRng 2-3-12 waitchild.c does not enable the SIGCHLD signal. This was causing problems when a child would die during a read/write operation and interrupt the read/write operation. checkpc - now checks to see if the LPD lockfile directory exists, and creates it if necessary. getopt.c - strdup() changed. (Reported by Brad Greer ) src/Makefile.in - LOCK_DEV_CFLAGS -> LOCK_DEVS_CFLAGS (Reported by Klaus Guntermann ) LPD, lpr -p and :pr: filtering. Documentation claims that LPD will filter 'p' format jobs through :pr: filter and :if: filter. It was not doing it, and now does. However, when using a bounce queue, it will not filter :pr: formats unless a :pf: filter is present. (Reported by Scott Sutherland ) :translate_format: printcap variable, and functionality added for bounce queues. A bounce queue can now also modify the job file format using the :translate_format: printcap entry. For example, :translate_format=mfpl: would change m to f and p to l format job files. Release LPRng 2-3-11 MAJOR ADDITIONAL FUNCTIONALITY: Logger: filter error output is now written to the logger as well as status information. lpr -p and LPD: the pr filter support was not updated. It now invokes the traditional 'pr' program correctly. (Reported by: K.D. Meyer" ) LPR: exits with a nonzero error when 0 length job or invalid queue. (Paul Haldane) lpbanner.1 and lpraccnt.1 man pages created. (Carl Hilton ) lpq -Pall - sendstatus() returned wrong status. Release LPRng 2-3-10 MAJOR ADDITIONAL FUNCTIONALITY: routing to multiple destinations, multiple copies, via a bounce queue A bounce queue can now route jobs to multiple destinations and/or make multiple copies of a job. This action is controlled by the printcap/configuration variable router=filter. See README.routing and the LPD.8 manual page for details. Identifiers: The 'A' control file line is now used to store a 'unique' job identifier. This follows a job through the system, and is used to identify a job. It can also be used in LPRM and LPC messages. The :use_identifier: printcap and configuration variable controls the addition of this information to the control file. Job ID Wildcards: LPRM, LPC now take wildcard entries as well use job numbers and user IDs for jobs. (Updated LPRM, LPC man pages). Logger: Added code to record the actions of jobs passing through the system. SetStatus messages now sent to a logger process as well as recorded in a status file. Added: printcap/configuration: logger_destination = host[%port][,(TCP|UDP)] host%port is destination host%port combination. configuration: default_logger_port = 560 - default port for logging default_logger_protocol = UPD - default protocol for logging lpd_rcvjob.c - error message has a missing '%s' entry. (Brad Greer ) Link_read() in link_support.c - minor error - zero length read reported as error, not EOF condition. lpd: multiple copies (lpr -K option) were causing malformed job control files to be generated by LPD when it checked them. Off by one problem with pointers fixed. (Reported by: Andrew Leahy , details of problem by Dirk Wrocklage ) cleanup() - exited with erroneous error code when NOT sent a signal. (Reported by Ed Santiago and Sven Rudolph ) HOST and REMOTEHOST permissions now can be netgroups, i.e. - HOST=@netgroup or REMOTEHOST=@netgroup will check to see if a host in in the netgroup. permissions.c - Mods by Geoff Ballinger These modifications fixed a problem with checking for user permissions, and now the permissions 'user' or 'remoteuser' is checked according to documentation. REMOTEUSER, REMOTEGROUP added to permissions checking. Permissions checking now done in much more rigorous way. LPD/lpd_rcvjob.c - fixed up hold file removal on bad job submission. Setup_waitchild() - moved to Initialize(), done for all programs Release LPRng 2-3-9 killchild.c - minor bug on cleanup. If cleanup called with 0 argument, never killed off children. Under very rare circumstances, this resulted in a OF filter process hanging up, and never exiting. LPR: the -s option is now silently ignored. (Jon E. Ferguson" ) ULTRIX has a sys/syslog.h and a syslog.h file, need to use sys/syslog.h (Per Foreby ) Accounting Filters: the :as: (accounting start) filter returning JREMOVE did not cause the job to be removed. Fixed. (Reported by Panos Dimakopoulos ) Release LPRng 2-3-8 lpr_makejob.c - not handling -w and -0 (font options) correctly. (Reported by Jens Thiel ) Comments in sendjob.c updated to reflect reality. (George Lindholm ) Release LPRng 2-3-7 lpd.conf default file - updated example configuration values Documentation miswordings, downright errors, and missing information corrections and comments added. (Bertrand Decouty-INRIA Rennes-France ) struct fd_set declarations changed to fd_set to make it compatible with POSIX. (Reported by Alan Shutko ) use_shorthost flag not working - fixed. (Bertrand Decouty-INRIA Rennes-France ) setup_filter.c - %h in an option string is now expanded to the short form of the host name. ROOT perms for filters - added the ROOT_PERMS_TO_FILTER_SECURITY_LOOPHOLE definition to the src/Makefile, modified common/setup_filter.c. Added comments to man/lpd.8. Comments by Patrick Powell, mods by (Jens Thiel ) Release LPRng 2-3-6 LPR/lpd_rcvjob.c - snprint() replaced by plp_snprintf() src/common/defaults.c - erroneous LD_LIBRARY_PATH= and PATH= values in configuration variables. (Reported by Jens Thiel ) LPRng 2-3-5 printcap.c - when lpd-perms array gets longer than 40kB or so, lpd crashes with an segmentation fault when it's getting started. fixed by: Dirk Wrocklage permissions.c, globmatch.c - updated error reporting, and added check for user's default group when checking GROUP permissions. (Stefan Monnier" and Ron Roskens ) Also, changed strcmp to strcasecmp to make comparisons case insensitive. LPD/lpd_control.c - modified error message to better indicate failure. long job numbers - lpd_rcvjobs.c, cleantext.c, lpr_makejob.c, printcap.c added the capability to have long (6 digit) job numbers. This is done by reformatting the job control file and the job file names. printcap :longnumber: and configuration longnumber=yes enables this. Note that :bk: (Backwards compatibility) overrides long numbers. If a queue is marked :bk: then it will attempt to shorten long numbers to produce a short number file. This can be used with a bounce queue to produce files compatible with the older vintage systems. As a side effect, tightened up format checking of unlink entries, and other issues reported by the following folks. (Lennart.Sorth@ecmwf.int, Desmond Macauley ) lprm - fixed the removal algorithm so that multiple tags select multiple jobs. i.e. - lprm 1 2 3 removes jobs with numbers 1, 2, and 3. If you do lprm user, all jobs with the tag 'user' are deleted. This allows much easier job purging, which is usually why you are using lprm... use_info_cache flag - printcap.c(Free_pc()) routine brutally wipes out all data now. This will either force the reread or crash the process. (reported by Dirk Wrocklage ) configuration variables: added default_format, default_priority to configuration as well as printcap variables. lpd.conf.5 and printcap.5 man pages have been updated. Apparently they were never documented in man pages. (reported by Stefan Monnier ) common/sendjob.c: error reporting for DATAFILE was incorrect. (reported Brad Greer ) :send_data_first: printcap and configuration variable added. causes data files to be sent to the destination first, before control files. (Supports horrible spoolers that violates RFC1179) (suggested Brad Greer ) :connect_grace#nn: printcap and configuration variable added. Klaus Steingerger reports that some printers require a grace period between connection attempts. This variable provides a suitable delay. Also, the Clear_timeout() routine now restores the ORIGINAL signal handler. This means you can only have one timeout pending at a time - which makes sense in this implementation. (reported and mods by Klaus Steinberger ) globmatch.c - a bug with checking for upper and lower case chars. (reported by Per Foreby ) Release LPRng 2-3-4 typos in the documentation - fixed Release LPRng 2-3-3 getcfng.c - "use_info_cache" entry out of order. (Alan F Lundin ) Release LPRng 2-3-3 LPR and :qq: printcap entry, use_queuename configuration information Added 'use_queuename = no' to the common/default.c file - the use_queuename will force control files to have the 'Qqueuename' entry placed into them. The :bk: (backwards compatible) entry can be used to override this when sending to non-LPRng systems. When receiving a job and use_queuename is TRUE, then LPD will add the name of the spool queue to the control file. Release LPRng 2-3-2 common/defaults.c - removed :xt: from the printcap defaults. common/getcnfinfo.c - added "true", "all", "false" keywords for flags. common/termclear.c - for LINUX, added include (Avery Earle ) Release LPRng 2-3-1 printcap.5 :xt: entry updated bk, qq, and bounce queue filter interaction: printjob.c modified to add Queuename information for filters if :qq: option or Q entry in job file. Release LPRng 2-3-0 Minor rewording on printcap.5 man page. common/termclear.c - defined(solaris) changed to defined(SOLARIS) (Andrew Richards ) common/printcap.c, CHECKPC/checkpc.c - subtle bug when reading printcap information from a filter AND the 'oh=host' specified AND the host is not the current host. Fixed. In addition, checkpc will not create queue entries for queues not used/defined on the current host. (Dirk Wrocklage ) Release LPRng 2-2-9 printcap.c - malformatted printcap entries ending with a \ at the end of the file are now accepted. Release LPRng 2-2-8 LPR now uses a reasonable size buffer when copying files. Release LPRng 2-2-7 lpq: back to the previous format! lpq -s - does the very short format lpq - prints short form of detailed information lpq -llll... - each l doubles status information lpq.1 - man page updated. printcap, lpd.conf: send_failure_action - added a 'hold' keyword that will hold the job on error rather than deleting it. updated printcap.5, lpd.conf.5 man pages lpd_jobs.c - added checks for filter non-zero status exit. configure.in - printf("%s",sys_siglist[0]) added () Release LPRng 2-2-7 lpq: by default, a very very short format- pr@host:(status stuff) NN jobs lpq -l - short, verbose format lpq -l -l or lpq -ll - longer format lprm: was not removing all jobs when 'lprm all' specified. lpr.1 man page: priority of jobs is A (highest) to Z (lowest) Release LPRng 2-2-6 lpr: -K option did not have ':' in getopt options string. (Klaus Steinberger ) lpr: -# has been readded, in spite of my better judgement, to be compatible with antique LPR systems. lpd: 'sending job to...' message error (Dwaine C. Gonyier ) printcap.c, getcnfginfo.c - ordering of parameters not alphabetical. (Ron Roskens ) lpr, configuration - check_for_nonprintable code got mushed, fixed now; the :xt: (check text) printcap flag added as well. man page fixed. (Ole Benner ) configure.in- library check fixed, added additional library check (Harlan.Stenn@pfcs.com) lpc - the 'lpc lpd xx' operation set the current printer to xx. Fixed. (Jos Backus ) Release LPRng 2-2-5 ** changed the bqfilter flag to bq=destination_queue This now forces all input to be passed through the filter. Changes in the bq filter information as well. Bounce_filter: removes temporary bounce queue file on exit unless debugging is high level. bounce queue file name is bfAnnnHost, i.e.- has same format as a job file. This makes job related processing easier to debug. lpc - Updated queue status display lpc status now shows autohold status lpc noautohold now restarts printer on 'NOAUTOHOLD' command lprm with no options removes first removable job in queue This is compatible with BSD lprm functionality configure - GCC version checks moved to start of configuration added checks for sys/utsname.h, utsname.h common/gethostinfo.c - uses sys/utsname.h configure.in has check added for utsname.h lpd - printjob now checks for exit status of filters - should terminate now if filter has bad exit status. (Note: this may not be bombproof in all situations.) printcap and configuration - connect_retry was defined as connect_try documentation fixed as well. CHECKPC- checkpc -r -A nD now removes all job related files older than n Days. This can be put into crontab and run periodically. printcap :ah: (autohold) now operational. Note that LPC will override printcap default. lpc status now indicates if autohold is on. Release LPRng 2-2-4 :bk: (backwards compatible) flag now causes removal of non-BSD compatible control file entries as well as modifying the order. :qq: (Queuename in control file) flag is now overridden by :bk: flag. This will now generate Berkeley compatible job files. lpr - improved 'connnection failed' message format. accounting_server and accounting_check added for accounting. printcap.5, README.accounting, and other documentation updated. Release LPRng 2-2-3 Once more the portability/bugfix Gods need yet another sacrifice. BSDI V2.1 setreuid() returns erroneous error codes - setuid.c fixed yet again... I suspect other BSD derivatives to have same problem. Sigh... cleanup() now unblocks signals before exiting. Print_open() - better status messages on open failure. Release LPRng 2-2-2 TESTSUPPORT: removed lpf generation Perms_check(): missing ntohl(HostIP), needed for host order of addresses. Lock_fd(): - saves errno error codes and returns them correctly Prefix_line in malloclist(): - copy now done in correct order fixes print queue bug. Accounting Filters: 1. the filter command is not passed as an argument to the accounting filter. This solves some problems with shell script filters, as the last filter command would have the form: filter -H... -a|filter |filter 2. Accounting information now logged at start and end of job. GROUP Permissions: permissions.c now checks to see if a specified group exists first, using getgrnam(), then tries wildcard search next. Permissions: IP=host/netmask format updated- allow /n to be n bit mask i.e. - 130.191.163.12/16 -> 130.191.163.12/255.255.0.0 Release LPRng 2-2-1 LPF filter: added source code to the LPRng main distribution. This provides a passthrough filter for most applications. README.printcap: updated to reflect use of lpf filter and banner printing LPRM/LPD: lpd restarts printing if the active job is removed. LPQ: more robust handling of bad printcap entries LPD: attempt to solve problems of filters which print to serial devices hanging because the device has pending output, has been sent a ^Q to stop output, and has not received a ^S to restart. Uses tcflush() to flush serial devices. LPR: added a 'use_shorthost' configuration and printcap variable to force the use of short host names for print job control and data files. The code was present in LPR, but not enabled. Update lpd.conf.5 and printcap.5 man pages. Debugging Flags: added keyword and flag capability. For example: -Dthis,that@ can be used to set the 'this' flag and clear the that flag. see common/parsedebug.c for details. NGPRINTER environment variable added. Used to override PRINTER environment variable. Allows one format for PLP/LPR/Solaris, one for LPRng. (marty leisner@sdsp.mc.xerox.com) LPC: command of form 'status printer@host' was not formatted correctly. (Jarrod Douglas ) man/printcat.5 - added a functional listing as well as alphabetical. (Sherwood Botsford ) LPD, LPQ: added termination error messages to status output. Details for job failure now available. printcap :qq: and lpr -Q option now fully operational. lpr -Q or :qq: printcap field sets Qqueuename in job file; lpd bounce queue will add Qqueuename line to the control file. Release LPRng 2-2-0 Updated README files. README.1st - overview README.install - much more complete README.lpd.conf - explains lpd.conf README.lpd.perms - lpd permissions structure listed man/lpr.1 - missing -k information added. man/lprm.1 - fixed typos man/lpd.perms.5 - lpd.conf documented DOC/Tutorial - added additional information DOC/Install - extended to include more testing and installation details. strdup() changed to plp_strdup() to avoid problems with C library. configure.in - check for sys_siglist[] improved. src/commmon/decodestatus.c - fixed problem with Solaris 2.5 and sys_siglist[] Makefile - added default target to install default lpd.conf and lpd.perms files; prototype files added as well. man/lpd.conf.5 man page added src/common/permission.c: added a SERVER key, to allow restriction to users on the server. checkpc - truncation now done on log, accounting, and status files. LP_SIMULATION - SVR4 simulation with lp.sh and lpstat.pl scripts Release LPRng 2-1-3 waitchild.c - race condition with malloc() in the SIGCHLD handler would result in rare, very very rare problems. Data structures are now pre-allocated. LPD/lpd_jobs.c - WIFSTOPPED and WIFSIGNAL checks done improperly. Shows up in OSF1 based systems. The test is now done correctly. AIX portability - added sys/select.h to include list LPQ status display modified to be consistent- Filter status: -> Filter_status: Now all the comment and information lines have a : at the end of the first field. This makes parsing by perl/awk, etc. simple Note that the Rank Owner ... line still does not have a colon joost@cadlab.de - minor fixes for Apollo DN4500 and portability TESTSUPPORT/Makefile.in, as well as minor fixes in portable.h Release LPRng 2-1-2 STATVFS typeo corrected in in configure.in, portable.h, freespace.c (curt@ltpmail.gsfc.nasa.gov (Curt Tilmes)) Missing VARARGS declaration for setstatus() in lp.h (Marc Baudoin ) Makefile.in (in general) - fixed realclean mostlyclean targets (Paul Eggert ) setproctitle() - check made in configure, and if not present the proctitle.c code is used. (Marc Baudoin ) Makefiles - realclean and distclean targets did not remove Makefile (Paul Eggert ) Missing read permissions on various files (Paul Eggert ) configure.in (CFLAGS): Use a more accurate test to decide whether we are using GCC version 2.4.5 or earlier. The old test didn't handle GCC snapshots correctly. (Paul Eggert ) Release LPRng 2-1-1 CHECKPC- added test for the printcap 'ps' - printer status file - fixed up test for printer device, now ignores remote and filters - added 'checkpc -s' option to not create/check printer status file common/sendjob.c - Bounce Queue Filters are only invoked by the server; added a check for Interactive and printcap :bqfilter: flag BOTH set before invoking filter. This prevents clients from invoking filters. Release LPRng 2-1-0 Added 'rs' (time between spool queue rescans) printcap entry Added 'oh' (option for host) printcap entry Added check for NULL printcap pointers. Printcap files entirely consisting of comments and empty lines are now handled correctly. Added ntohl() and htonl() calls to fix IP addresses for permissions checking. This showed up on X86 systems. Release LPRng 2-0-9 Patch to make sigsetjmp() work correctly on Solaris. Sigh... Release LPRng 2-0-8 Solaris 2.5 requires sigsetjmp() and siglongjmp() for alarms and timeouts to work reliably. Note that GCC now does not put out warnings about 'variables may not be restored after longjmp' C'est la vie, c`est le guerre... Documented getting permission database with a filters, allowing dynamic checking of a database. Release LPRng 2-0-7 Fixed up the setuid() code yet again - portablility issues on BSDI and FreeBSD - need to do a setuid() operation first. Release LPRng 2-0-6 Removed default non-blocking open() operations; added printcap 'nb' (Nonblocking_open) variable to allow nonblocking open for specific devices Updated man pages and DOC files to reflect new open() capabilities Release LPRng 2-0-5 getuserinfo() was not using the original RUID value. Fixed device locking again, this time to do a fallback to fcntl() based locking if TIOCEXCL is not functioning Removed MFLAGS from Makefiles, also put in cleaner test for GNU Make The sleep() implementation on linux is defective; replaced by a plp_sleep() using select(). Release LPRng 2-0-4 src/cleantext.c - Check_format() was too strict in checking hostnames - now allow '-' as well as . and _ in name. configure.in - SGI IRIX configuration needs SVR4 definition forced. added more specifics for solaris Release LPRng 2-0-3 - mostly portability fixes man/Makefile.in - removed $(FILES) targets did updates in a 'sane' manner Fixed missing declarations of functions for fussy compilers. Fixed CHECKPC/checkpc_port.c - SunOS4.1.4 has two versions of stty - /bin/stty and /usr/5bin/stty forced use of /bin/stty configure.in - added gcc version check, fixed up CFLAGS HPUX portability kludges - 1. O_NDELAY and O_NONBLOCK interact - removed one of them 2. Need to use fcntl() after open to fix the non-blocking read operation. device locking now works on Solaris 5.4 checkpc- added a couple of sanity check functions for internal tables - Check_pc_list() and Check_config_list() discovered a couple of entries in wrong order (bp was one) that prevented use of banner printing. Release LPRng 2-0-2 Modified configure to use config.guess; fixed config.guess as well. - config.guess did not recognized BSDI systems, and exited with an error. Fixed configure.in to force library order if necessary. Ripped out several SVR4 dependencies; src/killchild.c Filters + Bounce Queues - added filtering capability printcap variables - bqfilter (flag) If a bounce queue (one that sends files to a remote printer/host) has filters speicified, and the :pqfilter: printcap flag is set, the data files will be passed through a filter, if there is a filter for that format. Updated printcap.5, lpd.8 documentation, as well as DOC/Intro. Release LPRng 2-0-1 configure.in - WARNING ** gcc version 2.4.5 and below The -O option produces erroneous code several places. configure.in has been modified to remove the -O option. configure.in - added explicit check for elf.h - now defines SVR4 if the file is present (see autoconf documentation for test). Compatibilty check. Updated CFLAGS with define for HPUX and uses the @CFLAGS@ edit in Makefiles. This solves a problem when configure sets CFLAGS and the default GNU Make .o.c rule set needs to be used. LPRM: If a user has LPC CONTROL permissions, he can now remove jobs from a queue. Makefile.in, Makefile - Added various GNU compatible targets such as clean, dist, reallyclean, etc. Fixed the man/Makefile to better update the man pages when installing them. checkpc -T line : fixed up the STTY reporting to be more robust should work with SVR4 better. LPR: added locale initialization; printable checks now use 8 bit characters if the locale has been enabled. O_NONBLOCK|O_NBLOCK - these both must be set on a SVR4 system to do a non-blocking open. This might be considered a documentation feature in some circles. FreeBSD defines: various files have had #ifdefs for FreeBSD added. Accounting: modified the default accounting string to add the control file name; allowed the accounting filter to exit with error status and write an error message. Release LPRng 2-0-0 Baseline Release Version Release LPRng 1-2-6 PERMISSIONS: permissions checking was defective- correct values now used. LPC: usage message updated Error reporting: connection permission errors reported to connecting system now. LPR: now reports server error msgs to user on STDERR. Release LPRng 1-2-5 PERMISSIONS: lpc operations split, 'C' are control, 'S' are status this allows 'lpc status' command to be used by non-privileged users Updated documentation to reflect this change as well. Updated lpq, lpc, lprm -V option to be less verbose by default; -V -V will show copyright information. ("Marty Leisner" ) Control file format: allowed first 'N' line to appear before data file information, and stuck in middle of control file. This makes it compatible with other LPR implementations. Sigh. If a filter is not available, this is logged in status and the job is discarded. This prevents a job with bad format information locking up the printer queue. Filter program lookup in printcap entry has been fixed to be a little more effective. Fixed checkpc and setproctitle() to work with FreeBSD (Richard Letts R.J.Letts@salford.ac.uk University of Salford) Release LPRng 1-2-4 Harlan Stenn termclear.c - there is an interesting problem with termcap.h, curses.h, terminfo.h. On some systems you do not want to include curses.h, but not terminfo.h and termcap.h. I recommend putting guards in the terminfo.h include file so you can include it multiple times without redefinition problems. curt@ltpmail.gsfc.nasa.gov (Curt Tilmes) - removed O_NDELAY from various open statements Makefile.in - removed ${SRC}/src, etc. to allow compilation in separate directories. Release LPRng 1-2-3 Fixed lprm -a flag; documentation error as well common/jobcontrol.c - erroneous error field update miscellaneous errors reported by users. SVR4 - added sys/systeminfo.h, sysinfo() call replace gethostinfo() printcap - added 'qq' (save queue name in job file) Release LPRng 1-2-2 This sounds ridiculous, but there is yet ANOTHER problem with implementing portable file locking. It turns out that some systems allow file locking only if the files are opened R/W, no APPEND. This is only a problem in pr_support.c; the permutations and combinations of files, devices, etc., are too much to deal with algorithmically. An new printcap flag 'lk' (lock LP device) is introduced to handle this. By default, no file or device locking is done. Release LPRng 1-2-1 Martin Forssen: maf@dtek.chalmers.se or maf@math.chalmers.se - fixed an erroneous test in checkremote.c - missing data initialization in LPD/lpd_jobs.c, LPD/lpd_status.c - common/getqueue.c off by one error - LPD/lpd_remove.c - cfpp uninitialized in Get_queue_remove() hagberg@mail.med.cornell.edu (Eric Hagberg) A/UX portability fixes in portable.h Fixed lpr, lprm MAN pages; fixed usage messages. Added CONTROL permission checking for LPRM operation; i.e. - if you have CONTROL permission you also can remove files. Release LPRng 1-2-0 Documentation - DOC/Intro and DOC/Install Filters: CTI-ifhp-1.1.1 lp-pipe-1.0.0 lp-support-1.0.0 psfilter-1.0.2 Fixed a minor bug in LPD/lpd.c - geteuid() missing Release LPRng 1-1-2 Documentation (Introduction, and Installation) added psfilter-1.0.1 added to FILTERS Added test for signal.h to configure.in. reported by Martin Forssen fixed missing bounds check in common/printcap.c, put install-sh in directories needed (autoconf does not fix up $(INSTALL) correctly) lookup loop for remote hosts in common/checkremote.c Link_listened(void) missing in include/lp.h Release LPRng 1-1-1 Added lp,lpsched, lp-pipes support Fixed a bug in the job renumbering code in lpd_rcvjob.c; always started with 0, instead of next job in sequence. Fixed a bug in lpd_rcvjob.c, additional 0 ACKS being sent. Fixed a bug with the filter options; added $0, $-, $' Fixed the default filter parameter list - accounting file at end Release LPRng 1-1-0 Cleaned up all sorts of minor problems with duplicate variables being declared in two places. Hopefully cleaned up the problems with Errormsg() not getting sys_nerr; sigh. Fixed accounting. Again. Sigh. Added (fixed) support for host%port Added install/test documentation. Added even more portability tests to checkpc. - device locking, stty, file locking. Release LPRng 1Alpha9 Accounting has been added. Fixed up a very very very rare problem with file locking by redoing some tests. Added the checkpc -T serial_line option This performs a whole series of portability tests, all of which need to pass. Include file problems strick again: fixed up the right set. Release LPRng 1Alpha8 Sun Aug 6 11:07:51 PDT 1995 Patrick Powell Renamed files with pathnames greater than 14 chars to shorter ones; Antique file systems strike again. Added 'form' and 'hold queue' capability; modified the control and job files; Renamed the release name to be consistent with GNU standards. Fixed problem with compatibility between SUN and other systems. Added LPR -Q flag, LPR -k flag to make it work. Sun Jul 30 09:09:49 PDT 1995 Patrick Powell Discovered some problems with the job printing code in LPD/lpd_jobs.c, re-editted it and put in some stronger checks. Modified the spool control file format slightly. This did not work as well as I thought it would in the overall design; now the spool control file can have any number of different types of entries for future expansion, i.e. printing_disabled 1 redirect printer@host Several rather silly coding errors in various places that turned up when a code checkout program was run: if/then not being executed, etc. etc. Fixed up the configure.in file to use the old dnl, socket, etc. libraries. man/Makefile and src/Makefile modified to use INCLUDE=.. so that configure can be run from another directory. This is very very strange autoconf dependency, but who cares, as long as it works. Fixed up a whole minor mess of writes and timeout interactions. Who would have guessed at this interaction? Created a couple of utility functions (Write_fd_str(), Write_fd_len()), and timeout (Set_timeout(), Clear_timeout()) routines. These assume that writes will be done with timeouts; all places where writes are done have been surrounded by Set_timeout, Clear_timeout. Release LPRng 1Alpha7 Mon Jul 24 09:29:15 PDT 1995 Patrick Powell Changed the Makefile 'TARGET' name to avoid conflicts with other Makefiles... sigh... In link_support.c/Link_send(), the original code was using several writes to send a line; this has been modified to use a single write where possible. Apparently some implementations of LPD code expect the command lines to be sent as a single TCP write operation, and do not look for the \n terminator. Removed the 'lorder/tsort' from Makefile, and hardcoded the library file order. This provides a simple form of portability, but will require updates to the Makefile if a new library file is added. Added better tests for sys_errlist and sys_siglist definitions. Moved all of the configuration information to the root level; this fixes a bug with the autoconf code that cannot handle more than one level of directory structure. You can now compile the LPRng software in another directory by using: cd LPRng.; SRC=`pwd`; \ cp configure $DEST; cd $DEST; configure --srcdir=$SRC; \ make all Modified the top level Makefile to use the GNU Make -C directory capability. Fixed Send_job() to make it more robust in the face of protocol errors. The numbers of times a job is retried is set by the Connection_retry value. Modified the LPC status reporting to make it clearer. Removed a redundant error message. Release LPRng 1Alpha6 Thu Jul 20 19:23:03 PDT 1995 Patrick Powell Reorganized the auto configuration code so that it is at the top level of the distribution. Added top level MAKEFILE with directory recursion. Separated out default printcap and configuration initialization, put them in src/default.c Fixed up some minor 'lint' level errors. Update man pages. Fix up installation so that VERSION information is put in the MAN page source. Editted MAN pages heavily in light of comments from people. Clean up some code in printcap.h, printcap.c, lp_config.h, getconfig.c Fixed a missing check for null string with STRCMP in src/getqueue.c. Considered using safestrcmp() for this reason; checked most places; safe or appear to be safe. Modified the format for LPQ status information, added more detail about the printer status. Added -Pprinter option to LPD to simply start and run a spool queue server. This allows debugging of filters much easier. Added bk-of-filter-options and bk-filter-options to provide compatibility with old style filters. Fixed up a lot of minor portability issues with Solaris2.4, using the SUN Soft C compiler. Fixed fumble in gethostinfo.c - will die if it cannot find the local host name; this is very bad and should be immediately fatal instead of dying later. Fixup the the TESTSUPPORT/Makefile to be a little more intelligent. Also, put in guards to make sure that you have GNU Make. This appears to be essential for sanity reasons alone. Release LPRng 1Alpha5 Mon Jul 17 10:57:49 PDT 1995 Patrick Powell ********* BSDI ************* Literally hundreds of questionable items were reviewed, fixed or modified. The 'snprintf' function was renamed to 'plp_snprintf' in order to avoid conflict with the BSDI/GCC snprintf functions. Fixed up some questionable uses of snprintf, changed to sprintf. Discovered an incredibly vulgar behaviour in strncat(), and fixed up its uses. Strncpy will clobber all information in string; double checked its uses where possible. Fri Jul 14 08:22:03 PDT 1995 Patrick Powell Fixed up configuration file reading. Was always using default values. Fri Jul 14 08:23:06 PDT 1995 Patrick Powell LPD status reporting did not read the printcap 'st' status file. Now reads the file and reports information using short form or long form as needed. lprng-3.8.B/Makefile.in0000644000131400013140000005401311531672273011656 00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(top_srcdir)/configure ChangeLog INSTALL NEWS TODO depcomp \ install-sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d $(distdir) \ || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr $(distdir); }; } DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHGRP = @CHGRP@ CHOWN = @CHOWN@ CLEAR = @CLEAR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_LIBS = @DL_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FILTER_LD_PATH = @FILTER_LD_PATH@ FILTER_PATH = @FILTER_PATH@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ INCLUDELPDCONFLOCAL = @INCLUDELPDCONFLOCAL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_MAN = @INSTALL_MAN@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KERBEROS = @KERBEROS@ KRB5CONFIG = @KRB5CONFIG@ KRB_LIBS = @KRB_LIBS@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCKFILE = @LOCKFILE@ LPD_CONF_PATH = @LPD_CONF_PATH@ LPD_LISTEN_PORT = @LPD_LISTEN_PORT@ LPD_PERMS_PATH = @LPD_PERMS_PATH@ LPD_PRINTCAP_PATH = @LPD_PRINTCAP_PATH@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NOREMOTE = @NOREMOTE@ OBJEXT = @OBJEXT@ OPENSSL = @OPENSSL@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PLUGINUSER_LDFLAGS = @PLUGINUSER_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PRINTCAP_PATH = @PRINTCAP_PATH@ PRIV_PORTS = @PRIV_PORTS@ PRUTIL = @PRUTIL@ SD_DEFAULT = @SD_DEFAULT@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSL_CA_FILE = @SSL_CA_FILE@ SSL_CA_KEY = @SSL_CA_KEY@ SSL_CERTS_DIR = @SSL_CERTS_DIR@ SSL_CRL_FILE = @SSL_CRL_FILE@ SSL_LDADD = @SSL_LDADD@ SSL_SERVER_CERT = @SSL_SERVER_CERT@ SSL_SERVER_PASSWORD_FILE = @SSL_SERVER_PASSWORD_FILE@ STRIP = @STRIP@ UNIXSOCKETPATH = @UNIXSOCKETPATH@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ filterdir = @filterdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lpdbindir = @lpdbindir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # still to include: TESTSUPPORT DISTRIBUTIONS SUBDIRS = UTILS po src man conf CLEANFILES = a.out *.bak ? ?.* core *.old *~ autom4te DISTCLEANFILES = *.orig configure.lineno config.cache config.log config.status MAINTAINERCLEANFILES = configure Makefile.in \ config.rpath config.guess config.sub \ aclocal.m4 config.h.in \ depcomp install-sh ltmain.sh missing mkinstalldirs EXTRA_DIST = ABOUT-NLS.LPRng CHANGES autogen.sh\ KERBEROS_configuration STANDARD_configuration MIT_configure \ CONTRIBUTORS COPYRIGHT LICENSE README.SSL.SECURITY all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \ cd $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_srcdir) && $(AUTOHEADER) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) $(am__remove_distdir) test -d $(distdir) || mkdir $(distdir) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ distdir=`$(am__cd) $(distdir) && pwd`; \ top_distdir=`$(am__cd) $(top_distdir) && pwd`; \ (cd $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$top_distdir" \ distdir="$$distdir/$$subdir" \ am__remove_distdir=: \ am__skip_length_check=: \ distdir) \ || exit 1; \ fi; \ done -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && cd $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @cd $(distuninstallcheck_dir) \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile config.h installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-exec-am: install-html: install-html-recursive install-info: install-info-recursive install-man: install-pdf: install-pdf-recursive install-ps: install-ps-recursive installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) install-am \ install-strip .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-am clean clean-generic \ ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ dist-lzma dist-shar dist-tarZ dist-zip distcheck distclean \ distclean-generic distclean-hdr distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am tags tags-recursive uninstall uninstall-am update-po: (cd po && $(MAKE) $(AM_MAKEFLAGS) update-po) || exit 1 # ############################################################################### # # Update the patch level when you make a new version # # do this before you start changes # # Don't even think about making this configurable, it is for # # distribution and update purposes only! # # Patrick Powell # ############################################################################### # # update: # rm -f src/include/license.h src/include/copyright.h # sed -e 's/"/\\"/g' -e 's/.*/"&",/' LICENSE >src/include/license.h # sed -e 's/"/\\"/g' -e 's/.*/"&",/' COPYRIGHT >src/include/copyright.h # for i in VERSION ./src/include/patchlevel.h configure.in ; do \ # rcs -l $$i; chmod +w $$i; \ # done; # if [ -x /bin/pwd ] ; then DIR=`/bin/pwd`; fi ; \ # if [ -x /usr/bin/pwd ] ; then DIR=`/usr/bin/pwd`; fi ; \ # DIR=`echo $${DIR} | sed 's,.*/,,'`; \ # DIRVER=` echo $${DIR} | sed 's,.*-,,'`; \ # echo DIR $${DIR}, DIRVER $${DIRVER}; \ # echo "#define PATCHLEVEL \"$${DIR}\"" >./src/include/patchlevel.h; \ # echo $${DIR} >VERSION; \ # S=`echo *.sh | sed -e 's/\.sh//g'`; \ # perl -spi -e "s,=.*,=$${DIRVER}, if(/^VERSION=/ or /^#.* VERSION=/); \ # s,^DISTNAME=.*,DISTNAME=$${DIR},; \ # s,^PORTNAME=.*,PORTNAME=$(PACKAGE),; \ # s,^PORTVERSION=.*,PORTVERSION=$${DIRVER},; \ # s,package name \".*\",package name \"$${DIR}\",; \ # s,^SCRIPTS=.*,SCRIPTS=$$S,;" \ # configure.in lpd.perms.in \ # DISTRIBUTIONS/*/Makefile \ # po/Makefile.in.in printcap # perl -spi -e 's,.*,"Project-Id-Version: $(PACKAGE) $(VERSION)\\n", if(/^"Project-Id/);' \ # po/*.po # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lprng-3.8.B/MIT_configure0000644000131400013140000000055711531672126012227 00000000000000#!/bin/sh # This is used to configure LPRng with Kerberos5 support for MIT #./configure --prefix=/usr --sysconfdir=/etc \ # --with-ldopts="-L/usr/local/lib" --with-cppopts="-I/usr/local/include" \ ./configure --prefix=/usr --sysconfdir=/etc \ --with-ldopts="-L/usr/kerberos/lib" --with-cppopts="-I/usr/kerberos/include" \ --enable-kerberos # --enable-mit_kerberos4 lprng-3.8.B/STANDARD_configuration0000644000131400013140000000071211531672126013655 00000000000000#!/bin/sh set -x if [ -d /usr/share/man ] ; then mandir="--mandir=/usr/share/man" fi sh ./configure --prefix=/usr --sysconfdir=/etc $mandir \ --disable-kerberos --enable-ssl --enable-force_localhost \ LDFLAGS="$LDFLAGS" CPPFLAGS="$CPPFLAGS" # Here are some more flags you may want: # # -L/usr/local/lib" CPPFLAGS="$CPPFLAGS -I/usr/local/include" \ # --enable-nls \ # --enable-kerberos --enable-mit_kerberos4 \ # --disable-ssl # --disable-tcpwrappers lprng-3.8.B/LICENSE0000644000131400013140000006117011531672125010614 00000000000000 *LPRng, IFHP, and LPRngTool LICENSE* GNU GPL and Artistic License (Version 5, 28 Aug 2003) Copyright Patrick Powell, Astart Technologies All rights reserved. You may use "LPRng" or "IFHP" under either the terms of the GNU GPL License or the Artistc License. These licenses are included below. The licenses were obtained from the http://www.opensource.org web site on 28 Aug 2003. These Licenses apply to the computer software packages known as "LPRng", "IFHP", and associated files. The "Package" or "Program" below refers to the programs, files, and associated software which are distributed as the package. The "LPRng" Software Package is a copyrighted work whose copyright is held by Patrick Powell. The "IFHP" Software Package is a copyrighted work whose copyright is held by Patrick Powell. The "LPRngTool" Software Package is a copyrighted work whose copyright is held by Patrick Powell. BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM. ----------------------------------------------------------------------- Addendum Fri Jun 21 17:06:33 PDT 2002 If you wish to distribute the LPRng source code or binaries of any of the programs in the LPRng packages under terms of the GNU license, then when any package or portion of the LPRng is configured to use any facility or utility of the OpenSSL distribution, the additional following clause will be applied, as recommended in the OpenSSL 0.9.6c release FAQ: "This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed." ----------------------------------------------------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. -------------------------------------------------------------------------------------------- From http://www.opensource.org - The Artistic License Version as of 28 Aug, 2003 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. "Copyright Holder" is whoever is named in the copyright or copyrights for the package. "You" is you, if you're thinking about copying or distributing this Package. "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. lprng-3.8.B/src/0000777000131400013140000000000011531672401010452 500000000000000lprng-3.8.B/src/lprng_certs.sh0000755000131400013140000006021611531672133013256 00000000000000#!/bin/sh # Set up LPRng Certificate Authority # Set up LPRng Server Certificate # Set up LPRng Client Certificates # # Requires: OpenSSL (http://www.openssl.org) # Based on openssl-0.9.6c, but probably works with an # # This script was stolen^H^H^H^H^H^H derived from the CA.sh script in the # ssleay/openssl distribution, and the cca.sh and sign.sh scripts in the # mod_ssl 2.8.8 distribution. # As noted: ## CCA -- Trivial Client CA management for testing purposes ## Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved. ## sign.sh -- Sign a SSL Certificate Request (CSR) ## Copyright (c) 1998-2001 Ralf S. Engelschall, All Rights Reserved. # # The LPRng SSL authentication uses the same general setup as does Apache # and other systems: # # $sysconfdir default: /etc/lpd/ # - a directory where you have the SSL stuff # SSL_CA_FILE "/etc/lpd/ssl.ca/ca.crt" # ${sysconfdir}/lpd/ssl.ca/ca.crt # - CA file, i.e. - one file with lots of certs, # but we are going to assume that this is our signing cert # SSL_CA_KEY "/etc/lpd/ssl.ca/${CA_KEY}" # ${sysconfdir}/lpd/ssl.ca/${CA_KEY} # - private key for CA file, used to sign certs # SSL_SERVER_CERT "/etc/lpd/ssl.server/server.cert" # ${sysconfdir}/lpd/ssl.cert/server.cert # - server cert file # SSL_SERVER_PASSWORD_FILE "/etc/lpd/ssl.server/server.pwd" # ${sysconfdir}/lpd/ssl.cert/server.pwd # - server private key password in this file # # # Use: # lprng_cert init - sets up directory structure # lprng_cert newca - creates CA certs # lprng_cert gen - generates certificates # lprng_cert verify path_to_cert - verifies certificates # lprng_cert defaults - sets/examines defaults # lprng_cert encrypt path_to_key - encrypts/decrypts key file # lprng_cert index - make certificate index files # # we force the location of the CERTS to be whereever we want # no redeeming social value to this stuff; # some optional terminal sequences case $TERM in xterm|xterm*|vt220|vt220*) T_MD=`echo dummy | awk '{ printf("%c%c%c%c", 27, 91, 49, 109); }'` T_ME=`echo dummy | awk '{ printf("%c%c%c", 27, 91, 109); }'` ;; vt100|vt100*) T_MD=`echo dummy | awk '{ printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }'` T_ME=`echo dummy | awk '{ printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }'` ;; default) T_MD='' T_ME='' ;; esac # announce what you are doing cat <&2 <>${CA_DEFAULTS} done finished=1; break; ;; [nN]* ) finished=1; break; ;; *) ;; esac done } # # encrypt the certificate key # encrypt() { cat <&2 echo "You may need to renter the password" 1>&2 else break; fi done (umask 077; cp ${1}.enc ${1}; rm -f ${1}.enc ) echo "Fine, you're using an encrypted private key to sign CERTS." ENCRYPTED=YES else echo "Warning, you're using an unencrypted private key for signing CERTS." echo "Make sure that the key is VERY well protected" fi } # help for signing shelp() { cat <${CFG} <&2 echo "Perhaps your ${TMPDIR:-/tmp} is not writable or you are missing mktemp." >&2 echo "try giving --TMPDIR=/place/only-you-can-read-or-write as first argument." >&2 exit 1; } ;; esac CFG=$TMPDIR/$$.sslcfg OPENSSL=@OPENSSL@ CA_KEY=@SSL_CA_KEY@ CA_CERT=@SSL_CA_FILE@ CA_USER_CERTS=@SSL_CERTS_DIR@ CA_CRL_FILE=@SSL_CRL_FILE@ SSL_SERVER_CERT=@SSL_SERVER_CERT@ C_val="XY" ST_val="Snake Desert" L_val="Snake Town" O_val="Snake Oil, Ltd" OU_ca_val="CA" OU_signer_val="Signer" OU_server_val="Server" OU_user_val="User" CN_ca_val="Snake Oil CA" CN_server_val="PrintServer Name" CN_signer_val="Signer Name" CN_user_val="John Q. User" Validity_ca_val=365 Validity_signer_val=365 Validity_user_val=365 Validity_server_val=365 Email_val="name@snakeoil.dom" case "$1" in --TEMP=* ) s=`expr "X$1" : "X--TEMP=\(.*\)"` CA_DIR="$s/ssl.ca" CA_CERT="$s/ssl.ca/ca.crt" CA_KEY="$s/ssl.ca/ca.key" CA_USER_CERTS="$s/ssl.certs" CA_CRL_FILE="$s/certs.crl" DIRS="" shift ;; esac if [ "$CA_DIR" = "" ] ; then CA_DIR=`dirname ${CA_CERT}` fi CA_DEFAULTS=${CA_DIR}/ca.defaults # if you have a defaults file, then read it if [ -f "${CA_DEFAULTS}" ] ; then . ${CA_DEFAULTS} fi set_values # find some random files # (do not use /dev/random here, because this device # doesn't work as expected on all platforms) randfiles='' for file in /var/log/messages /var/adm/messages \ /kernel /vmunix /vmlinuz \ /etc/hosts /etc/resolv.conf; do if [ -f $file ]; then if [ ".$randfiles" = . ]; then randfiles="$file" else randfiles="${randfiles}:$file" fi fi done case $1 in init ) # if directories do not exist then setup the directory init_ca_dirs ;; newca) # if directories do not exist then setup the directory init_ca_dirs if [ -f ${CA_CERT} ] ; then while [ 1 ] ; do echo -n "WARNING: ${CA_CERT} already exists! Do you want to overwrite it? [N/y]" read VAR case "$VAR" in [Yy]* ) break ;; * ) exit 1 esac done fi echo "${T_MD}INITIALIZATION - SET DEFAULTS in ${CA_DEFAULTS} ${T_ME}" echo "" if [ -f ${CA_DEFAULTS} ] ; then touch ${CA_DEFAULTS} ; fi defaults set_values echo "${T_MD}Generating custom Certificate Authority (CA)${T_ME}" echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 1: Generating RSA private key for CA (1024 bit)${T_ME}" cp /dev/null ${CA_RND} echo '02' >${CA_SER} if [ ".$randfiles" != . ]; then ${OPENSSL} genrsa -rand $randfiles -out ${CA_KEY} 1024 else ${OPENSSL} genrsa -out ${CA_KEY} 1024 fi if [ $? -ne 0 ]; then echo "$0: Error: Failed to generate RSA private key" 1>&2 rm -f ${CFG} exit 1 fi TYPE="ca" echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 2: Generating X.509 certificate signing request for CA${T_ME}" eval CN_val=\"\$CN_${TYPE}_val\" eval OU_val=\"\$OU_${TYPE}_val\" eval Validity_val=\"\$Validity_${TYPE}_val\" make_cfg #cat ${CFG} ${OPENSSL} req -config ${CFG} -new -key ${CA_KEY} -out ${CA_CSR} if [ $? -ne 0 ]; then echo "Error: Failed to generate certificate signing request" 1>&2 rm -f ${CFG} exit 1 fi echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 3: Generating X.509 certificate for CA signed by itself${T_ME}" cat >${CFG} <&2 rm -f ${CFG} exit 1 fi echo "______________________________________________________________________" echo "" echo "${T_MD}RESULT:${T_ME}" ${OPENSSL} verify ${CA_CERT} if [ $? -ne 0 ]; then echo "Error: Failed to verify resulting X.509 certificate" 1>&2 rm -f ${CFG} exit 1 fi STEP="STEP 4. " encrypt ${CA_KEY} echo "______________________________________________________________________" echo "" if [ "$ENCRYPTED" = YES ] ; then echo "${T_MD}STEP 5: Combine CERT and KEY file${T_ME}" echo "Generate single CERT and KEY file? [N/y] "; read VAR case "$VAR" in [yY]* ) (umask 077; cat ${CA_KEY} ${CA_CERT} \ > ${CA_CERT}.combined mv ${CA_CERT}.combined ${CA_CERT} rm ${CA_KEY} ) CA_KEY="${CA_CERT}" ;; esac fi index_certs ${CA_DIR} echo "" echo "Use the following commands to examine the CERT and KEY files:" echo " openssl x509 -text -in ${CA_CERT}" echo " openssl rsa -text -in ${CA_KEY}" ;; defaults ) echo "______________________________________________________________________" echo "" echo "${T_MD}${STEP}Setting Default Values${T_ME}" defaults; ;; encrypt ) shift if [ "$1" = "" ] ; then usage; fi; if [ ! -f "$1" ] ; then useage; fi; sed -n -e '/BEGIN.*PRIVATE KEY/,/END.*PRIVATE KEY/p' $1 >"$TMPDIR"/$$.key sed -e '/BEGIN.*PRIVATE KEY/,/END.*PRIVATE KEY/d' $1 >"$TMPDIR"/$$.crt STEP="" encrypt "$TMPDIR"/$$.key status=$? echo STATUS $status if [ $status = 0 ] ; then mv $1 $1.orig cat "$TMPDIR"/$$.crt "$TMPDIR"/$$.key >$1 fi ;; gen ) echo "${T_MD}CERTIFICATE GENERATION${T_ME}" COMBINE="Y/n" while [ 1 ] ; do echo -n "What type of certificate? User/Server/Signing Authority/Help? [u/s/a/H] " read VAR case "$VAR" in [uU] ) TYPE=user; nsCertType="client,email"; if [ "$Signer_cert_path" != "" ] ; then CA_CERT=$Signer_cert_path; CA_KEY=$Signer_key_path; fi break;; [sS] ) TYPE=server; nsCertType="client,server,email"; if [ "$Signer_cert_path" != "" ] ; then CA_CERT=$Signer_cert_path; CA_KEY=$Signer_key_path; fi break;; [Aa] ) TYPE=signer; nsCertType="objsign"; CA_USER_CERTS=$CA_DIR; CA_SER=$CA_DIR/ca.ser COMBINE="N/y" break;; *) shelp; ;; esac done while [ 1 ] ; do echo -n "Create in '$CA_USER_CERTS' [return for yes, or specify directory] " read VAR case "$VAR" in "" ) break ;; *) CA_USER_CERTS=$VAR; CA_SER=$VAR/ca.ser ;; esac done if [ ! -d ${CA_USER_CERTS} ] ; then mkdir -p ${CA_USER_CERTS} fi if [ ! -f $CA_SER ] ; then echo 1 > $CA_SER; fi user="$TYPE-`cat ${CA_SER}`" while [ 1 ] ; do echo -n "CERT name '$user'? [return for yes, or specify name] " read VAR case "$VAR" in "" ) break ;; *) user="$VAR" ;; esac done echo "Creating $user in $CA_USER_CERTS" CERT=$CA_CERT; KEY=$CA_KEY; while [ 1 ] ; do if [ ! -f "$CERT" ] ; then d=`dirname $CERT`; if [ "$d" = "." -o "$d" = "" ] ; then d="${CA_DIR}/"; fi if [ -f $d$CERT ] ; then CERT=$d$CERT; fi if [ -f $d${CERT}.crt ] ; then CERT=$d${CERT}.crt; fi fi echo -n "Sign with Certificate '$CERT' [return for yes, ? for list, or specify cert file] " read VAR case "$VAR" in "" ) if [ ! -f "$CERT" ] ; then echo "cert file '$CERT' does not exist" continue fi break; ;; "?" ) d=`dirname $CERT`; echo "Possible CERTS in directory '$d' are:" ls $d/*.crt 2>/dev/null ;; *) if [ ! -f "$VAR" ] ; then if [ -f "$VAR.crt" ] ; then VAR="$VAR.crt" fi d=`dirname $CERT`; v= for i in `ls $d/*.crt 2>/dev/null | grep $VAR` ; do echo "Match Found $i" if [ "$v" = "" ] ; then v="$i" ; else v="$v $i"; fi done if [ "$v" = "" ] ; then echo "Possible CERTS in directory '$d' are:" ls $d/*.crt 2>/dev/null elif [ -f "$v" ] ; then VAR=$v else continue fi fi CERT="$VAR"; KEY="$VAR" ;; esac done if [ "`grep 'PRIVATE KEY' $CERT`" != "" ] ; then echo Private key in $CERT KEY=$CERT else while [ 1 ] ; do echo -n "Private key file '$KEY' [return for yes, or specify path to key file] " read VAR case "$VAR" in "" ) if [ ! -f "$KEY" ] ; then echo "file '$KEY' does not exist" continue fi break; ;; *) if [ ! -f "$VAR" ] ; then echo "file '$VAR' does not exist" d=`dirname $CERT`; if [ -f $d/$VAR ] ; then VAR=$d/$VAR; echo "Trying $VAR" else continue fi fi KEY="$VAR" ;; esac done fi echo "" echo "${T_MD}Generating ${TYPE} Certificate [$user] ${T_ME}" echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 1: Generating RSA private key for ${TYPE} (1024 bit)${T_ME}" if [ ".$randfiles" != . ]; then ${OPENSSL} genrsa -rand $randfiles -out ${CA_USER_CERTS}/$user.key 1024 else ${OPENSSL} genrsa -out ${CA_USER_CERTS}/$user.key 1024 fi if [ $? -ne 0 ]; then echo "Error: Failed to generate RSA private key" 1>&2 rm -f ${CFG} exit 1 fi echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 2: Generating X.509 certificate signing request for ${TYPE}${T_ME}" eval CN_val=\"\$CN_${TYPE}_val\" eval OU_val=\"\$OU_${TYPE}_val\" eval Validity_val=\"\$Validity_${TYPE}_val\" make_cfg ${OPENSSL} req -config ${CFG} -new -key ${CA_USER_CERTS}/$user.key -out ${CA_USER_CERTS}/$user.csr if [ $? -ne 0 ]; then echo "Error: Failed to generate certificate signing request" 1>&2 rm -f ${CFG} exit 1 fi while [ 1 ] ; do echo -n "User Certificate Validity in days [default $Validity_val] " read VAR case "$VAR" in "" ) VAR=$Validity_val;; esac v=`echo ${VAR} | sed -e 's/[0-9]//g'` if [ "$v" != "" -o "$VAR" = "" ] ; then echo "Must be integer value" else Validity_val=$VAR; break; fi done rm -f ${CFG} echo "______________________________________________________________________" echo "" echo "${T_MD}STEP 3: Generating X.509 certificate signed by ${CERT}${T_ME}" cat >${CFG} <&2 echo "try again? [Y/n] " read VAR case "$VAR" in [Yy]* | "" ) ;; * ) rm -f ${CFG} exit 1 ;; esac else break; fi done # caname="`${OPENSSL} x509 -noout -text -in ${CERT} |\ # grep Subject: | sed -e 's;.*CN=;;' -e 's;/Em.*;;'`" # username="`${OPENSSL} x509 -noout -text -in ${CA_USER_CERTS}/$user.crt |\ # grep Subject: | sed -e 's;.*CN=;;' -e 's;/Em.*;;'`" # echo "Assembling PKCS#12 package" # ${OPENSSL} pkcs12 -export -in ${CA_USER_CERTS}/$user.crt \ # -inkey ${CA_USER_CERTS}/$user.key -certfile ${CERT} \ # -name "$username" -caname "$caname" -out ${CA_USER_CERTS}/$user.p12 echo "______________________________________________________________________" echo "" echo "${T_MD}RESULT:${T_ME}" ${OPENSSL} verify -CApath ${CA_DIR} -CAfile ${CERT} ${CA_USER_CERTS}/$user.crt if [ $? -ne 0 ]; then echo ": Failed to verify resulting X.509 certificate" 1>&2 rm -f ${CFG} exit 1 fi STEP="STEP 4. " encrypt ${CA_USER_CERTS}/$user.key echo "______________________________________________________________________" echo "" ofile=key if [ "$ENCRYPTED" = YES ] ; then echo "${T_MD}STEP 5: Combine CERT and KEY file${T_ME}" echo "Generate single CERT and KEY file? [$COMBINE] "; read VAR case "$VAR" in [yY]* | "" ) if [ "$VAR" = "" -a "$COMBINE" = "N/y" ] ; then break; fi (umask 077; cat ${CA_USER_CERTS}/$user.key ${CA_USER_CERTS}/$user.crt \ > ${CA_USER_CERTS}/$user.crt.combined mv ${CA_USER_CERTS}/$user.crt.combined \ ${CA_USER_CERTS}/$user.crt rm ${CA_USER_CERTS}/$user.key ) ofile=crt ;; esac fi if [ "${TYPE}" = "signer" ] ; then index_certs ${CA_USER_CERTS} fi echo "" echo "Use the following commands to examine the CERT and KEY files:" echo " openssl x509 -text -in ${CA_USER_CERTS}/$user.crt" echo " openssl rsa -text -in ${CA_USER_CERTS}/$user.$ofile" ;; verify ) shift if [ $# = 0 ] ; then v=`ls ${CA_USER_CERTS}/*.crt 2>/dev/null` else for i in $* ; do if [ -f $i ] ; then v="$v $i" elif [ -d $i ] ; then for j in $i/*.crt ; do v="$v $j" done fi done fi for i in $v ; do if [ -f $i ] ; then v=$i; elif [ -f $CA_USER_CERTS/$i ] ; then v=$CA_USER_CERTS/$i; elif [ -f $CA_USER_CERTS/$i.crt ] ; then v=$CA_USER_CERTS/$i.crt; elif [ -f $CA_DIR/$i ] ; then v=$CA_DIR/$i; elif [ -f $CA_DIR/$i.crt ] ; then v=$CA_DIR/$i.crt; else echo "cannot find $i in $CA_USER_CERTS or $CA_DIR"; continue fi echo "cert: $v" ${OPENSSL} x509 -in $v -subject -issuer -noout ${OPENSSL} verify -CApath ${CA_DIR} $v done ;; index ) shift if [ "$1" != "" ] ; then CA_DIR="$1" ; fi index_certs ${CA_DIR} ;; *) echo "Unknown request '$*'"; usage; rm -f ${CFG} exit 1 ;; esac rm -f ${CFG} exit $RET lprng-3.8.B/src/pclbanner.in0000644000131400013140000000703511531672134012672 00000000000000#!@SHELL@ # shell for PCL banner printing # # # pr:bp=/usr/local/.../pclbanner # :of=/usr/local/.../offilter # # Uses: printf PATH=/bin:/usr/bin Arglist="" Args="" vAr="" vAlue="" iI="" Args="$@" while expr "$1" : '-.*' >/dev/null ; do vAr=`expr "$1" : '-\(.\).*'`; vAlue=`expr "$1" : '-.\(.*\)'`; case "$vAr" in - ) break;; c ) c=1;; [a-zA-Z] ) if test "X$vAlue" = "X" ; then shift; vAlue=$1; fi; eval $vAr='$vAlue'; #setvar $vAr "$vAlue" case "$vAr" in J ) Title=$vAlue ;; P ) Printer=$vAlue ;; H ) Host=$vAlue ;; n ) User=$vAlue ;; C ) Class=$vAlue ;; A ) Jobid=$vAlue ;; D ) Date=$vAlue ;; Q ) Queue=$vAlue ;; N ) Filename=$vAlue ;; f ) Format=$vAlue ;; esac ;; esac; shift; done # set shell variables to the printcap options # flag -> flag=1 # flag@ -> flag=0 # option=value -> option='value' # #for iI in `echo $PRINTCAP_ENTRY | sed -e "s/.*/\"&\"/"` ; do for iI in $PRINTCAP_ENTRY ; do # echo X $iI; if expr "$iI" : " *\:" >/dev/null ; then vAr=`expr "$iI" : " *\:\([^#=][^#=]*\)[#=].*"`; vAlue=`expr "$iI" : " *\:[^#=][^#=]*[#=]\(.*\)"`; if test "X$vAr" = "X" ; then vAr=`expr "$iI" : " *:\(.*\)@"`; vAlue=0; fi if test "X$vAr" = "X" ; then vAr=`expr "$iI" : " *:\(.*\)"`; vAlue=1; fi if test "X$vAr" != "X" ; then eval $vAr='$vAlue'; #setvar $vAr "$vAlue" fi else vAr=`expr "$iI" : " *\([^|][^|]*\).*"`; if test "X$vAr" != "X" ; then eval Printer="$vAr" fi fi; done # set shell variables to the printcap options # flag -> flag=1 # flag@ -> flag=0 # option=value -> option='value' # for iI in $CONTROL ; do # echo X $iI; vAr=`expr "$iI" : " *\([A-Z]\).*"`; vAlue=`expr "$iI" : " *[A-Z]\(.*\)"`; if test "X$vAr" != "X" ; then eval $vAr='$vAlue'; #setvar $vAr "$vAlue"; fi; done # # restore argument list set -- $Args Args="" vAr="" vAlue="" iI="" xpos=0; ypos=0; incr=0; margins="\033&l0u0Z"; lightbar="\033*c1800a100b45g2P"; darkbar="\033*c1800a100b25g2P"; fontchange="\033(8U\033(s1p%dv0s0b4148T"; position="\033*p%dx%dY"; UEL="\033%%-12345X"; UELPJL="\033%%-12345X@PJL \n"; PCLRESETSTR="\033E"; CRLFSTR="\033&k2G"; moveto () { printf $position $1 $2; } fontsize () { incr=`expr "(" $1 "*" 300 "*" 11 ")" / 720`; printf $fontchange $1; } argline () { key=$1 value=$2 if [ -n "$value" ] ; then textline "$key" 1 0 textline ": " 0 0 textline "$value" 0 1 fi } textline () { line=$1 start=$2 end=$3 if [ "$start" -gt 0 ] ; then moveto $xpos $ypos fi printf '%s' "$line"; if [ "$end" -gt 0 ] ; then ypos=`expr "$ypos" + "$incr"` fi } pcl_banner () { printf "$UEL" ; printf "$PCLRESETSTR" ; # printf "$UELPJL" ; printf "$CRLFSTR" ; printf "$margins" ; # do light bar xpos=0; ypos=0; moveto $xpos $ypos ; printf $lightbar ; ypos=`expr $ypos + 100`; # set font size fontsize 24; ypos=`expr $ypos + $incr`; moveto $xpos $ypos ; argline Title "$Title" fontsize 14 argline Printer "$Printer" argline Host "$Host" argline User "$User" argline Class "$Class" argline Jobid "$Jobid" argline Date "$Date" argline Queue "$Queue" argline Filename "$Filename" argline Format "$Format" # smaller font fontsize 12 ; moveto $xpos $ypos ; date=`date`; textline 'Printed at: ' 0 1 ; textline "$date" 0 1 ; moveto $xpos $ypos ; printf $darkbar ; printf "$UEL" ; printf "$PCLRESETSTR" ; } pcl_banner lprng-3.8.B/src/lprng_index_certs.sh0000644000131400013140000000173111531672134014440 00000000000000#!/bin/sh # make an index in the certificate directory # usage () { echo "usage: lprng_index_certs [certdir]" >&2 echo " default directory $CA_DIR" >&2 exit 1 } ssl_program=@OPENSSL@ CA_CERT=@SSL_CA_FILE@ case "$1" in --TEMP=* ) CA_DIR=`expr "$1" : "--TEMP=\(.*\)"` shift ;; esac if [ "$1" != "" ] ; then CA_DIR=$1 fi if [ "$CA_DIR" = "" ] ; then CA_DIR=${CA_CERT} fi if [ -f $CA_DIR ] ; then CA_DIR=`dirname ${CA_DIR}` fi if [ ! -d $CA_DIR ] ; then echo "directory $CA_DIR does not exist" >&2 usage fi set -e cd $CA_DIR for file in *.crt; do if [ ".`grep SKIPME $file`" != . ]; then echo dummy | awk '{ printf("%-15s ... Skipped\n", file); }' "file=$file"; else n=0; while [ 1 ]; do hash="`$ssl_program x509 -noout -hash <$file`"; if [ -r "$hash.$n" ]; then n=`expr $n + 1`; else echo dummy | awk '{ printf("%-15s ... %s\n", file, hash); }' "file=$file" "hash=$hash.$n"; ln -s $file $hash.$n; break; fi; done; fi; done lprng-3.8.B/src/include/0000777000131400013140000000000011531672401012075 500000000000000lprng-3.8.B/src/include/fileopen.h0000644000131400013140000000170111531672132013763 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: fileopen.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _FILEOPEN_H_ #define _FILEOPEN_H_ 1 /***************************************************************** * File open functions * These perform extensive checking for permissions and types * see fileopen.c for details *****************************************************************/ /* PROTOTYPES */ int Checkread( const char *file, struct stat *statb ); int Checkwrite( const char *file, struct stat *statb, int rw, int create, int nodelay ); int Checkwrite_timeout(int timeout, const char *file, struct stat *statb, int rw, int create, int nodelay ); #endif lprng-3.8.B/src/include/lpstat.h0000644000131400013140000000177211531672133013502 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPSTAT_H_ #define _LPSTAT_H_ 1 EXTERN int LP_mode; /* LP mode */ EXTERN int Longformat; /* Long format */ EXTERN int Displayformat; /* Display format */ EXTERN int All_printers; /* show all printers */ EXTERN int Status_line_count; /* number of status lines */ EXTERN int Clear_scr; /* clear screen */ EXTERN int Interval; /* display interval */ /* PROTOTYPES */ int main(int argc, char *argv[], char *envp[]); static void Show_status(int display_format); static int Read_status_info( char *host, int sock, int output, int timeout, int display_format, int status_line_count ); static void Get_parms(int argc, char *argv[] ); static void usage(void); #endif lprng-3.8.B/src/include/checkpc.h0000644000131400013140000000242111531672132013562 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: checkpc.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _CHECKPC_H_ #define _CHECKPC_H_ 1 /* PROTOTYPES */ int main( int argc, char *argv[], char *envp[] ); static void mkdir_path( char *path ); static void Scan_printer(struct line_list *spooldirs); static void Check_executable_filter( const char *id, char *filter_str ); static void Make_write_file( char *file, char *printer ); static void usage(void); static int getage( char *age ); static int getk( char *age ); static int Check_file( char *path, int fix, int age, int rmflag ); static int Check_read_file( char *path, int fix, int perms ); static int Fix_create_dir( char *path, struct stat *statb ); static int Fix_owner( char *path ); static int Fix_perms( char *path, int perms ); static int Check_spool_dir( char *path ); static void Test_port(int ruid, int euid, char *serial_line ); static void Fix_clean( char *s, int no ); static int Check_path_list( char *plist, int allow_missing ); #endif lprng-3.8.B/src/include/linksupport.h0000644000131400013140000000360511531672133014562 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LINKSUPPORT_H_ #define _LINKSUPPORT_H_ 1 #include "config.h" #if !defined(HAVE_INET_NTOP) const char *inet_ntop( int family, const void *addr, char *str, size_t len ); #endif #if !defined(HAVE_INET_PTON) int inet_pton( int family, const char *strptr, void *addr ); #endif /* PROTOTYPES */ int Link_setreuse( int sock ); void Set_linger( int sock, int n ); int Link_listen( char *port_name ); int Unix_link_listen( char *unix_socket_path ); int Link_open(char *host, int timeout, struct sockaddr *bindto, char *unix_socket_path, char *errmsg, int errlen ); int Link_open_type(char *host, int timeout, int connection_type, struct sockaddr *bindto, char * unix_socket_path, char *errmsg, int errlen ); int Link_open_list( char *hostlist, char **result, int timeout, struct sockaddr *bindto, char *unix_socket_path, char *errmsg, int errlen ); void Link_close( int timeout, int *sock ); int Link_send( char *host, int *sock, int timeout, const char *sendstr, int count, int *ack ); int Link_copy( char *host, int *sock, int readtimeout, int writetimeout, const char *src, int fd, double pcount); int Link_dest_port_num( char *port ); int Link_line_read(char *host, int *sock, int timeout, char *buf, int *count ); int Link_read(char *host, int *sock, int timeout, char *buf, int *count ); int Link_file_read(char *host, int *sock, int readtimeout, int writetimeout, int fd, double *count, int *ack ); const char *Link_err_str (int n); const char *Ack_err_str (int n); int AF_Protocol(void); const char *inet_ntop_sockaddr( struct sockaddr *addr, char *str, int len ); #endif lprng-3.8.B/src/include/merge.h0000644000131400013140000000107411531672133013265 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: merge.h,v 1.74 2004/09/24 20:20:00 papowell Exp $ ***************************************************************************/ #ifndef _MERGE_H_ #define _MERGE_H_ 1 /* PROTOTYPES */ int Mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg); #endif lprng-3.8.B/src/include/lpq.h0000644000131400013140000000222211531672133012756 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPQ_H_ #define _LPQ_H_ 1 EXTERN int Auth; /* Authentication */ EXTERN int LP_mode; /* LP mode */ EXTERN int Longformat; /* Long format */ EXTERN int Rawformat; /* Long format */ EXTERN int Displayformat; /* Display format */ EXTERN int All_printers; /* show all printers */ EXTERN int Status_line_count; /* number of status lines */ EXTERN int Clear_scr; /* clear screen */ EXTERN int Interval; /* display interval */ EXTERN int Show_all; /* show all status */ /* PROTOTYPES */ int main(int argc, char *argv[], char *envp[]); static void Show_status(char **argv); static int Read_status_info( char *host, int sock, int output, int timeout, int displayformat, int status_line_count ); static void Term_clear(void); static void Get_parms(int argc, char *argv[] ); static void usage(void); #endif lprng-3.8.B/src/include/lpd_worker.h0000644000131400013140000000072511531672133014340 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_WORKER_H_ #define _LPD_WORKER_H_ 1 pid_t Start_worker( const char *name, WorkerProc *proc, struct line_list *parms, int fd ); #endif lprng-3.8.B/src/include/globmatch.h0000644000131400013140000000070211531672133014123 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _GLOBMATCH_H_ #define _GLOBMATCH_H_ 1 /* PROTOTYPES */ int Globmatch( const char *pattern, const char *str ); #endif lprng-3.8.B/src/include/readstatus.h0000644000131400013140000000104611531672133014344 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _READSTATUS_H_ #define _READSTATUS_H_ 1 /* PROTOTYPES */ int Read_status_info( char *host, int sock, int output, int timeout, int displayformat, int longformat, int status_line_count, int lp_mode ); #endif lprng-3.8.B/src/include/getprinter.h0000644000131400013140000000122211531672133014344 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: getprinter.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _GETPRINTER_H_ #define _GETPRINTER_H_ 1 /* PROTOTYPES */ char *Get_printer(void); void Fix_Rm_Rp_info(char *report_conflict, int report_len ); void Get_all_printcap_entries(void); void Show_formatted_info( void ); void Show_all_printcap_entries( void ); #endif lprng-3.8.B/src/include/debug.h0000644000131400013140000000741011531672132013253 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: debug.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _DEBUG_H_ #define _DEBUG_H_ 1 /* to remove all debugging, redefine this as follows * note that a good optimizing compiler should not produce code * for the logDebug call. It may produce lots of warnings, but no code... */ #if !defined(EXTERN) # define EXTERN extern #endif EXTERN int Debug; /* debug flags */ EXTERN int DbgFlag; /* debug flags */ EXTERN int DbgTest; /* debug flags */ #ifdef NODEBUG #define DEBUGFSET(FLAG) ( 0 ) #define DEBUGF(FLAG) if( 0 ) logDebug #define DEBUGFC(FLAG) if( 0 ) #define DEBUG1 if(0) logDebug #define DEBUGL1 (0) #define DEBUG2 if(0) logDebug #define DEBUGL2 (0) #define DEBUG3 if(0) logDebug #define DEBUGL3 (0) #define DEBUG4 if(0) logDebug #define DEBUGL4 (0) #define DEBUG5 if(0) logDebug #define DEBUGL5 (0) #define DEBUG6 if(0) logDebug #define DEBUGL6 (0) #else /* general purpose debug test */ #define DEBUGC(VAL,FLAG) if( (Debug >= (VAL) ) || ((FLAG) & DbgFlag) ) logDebug #define DEBUGL(VAL,FLAG) ( (Debug >= (VAL) ) || ((FLAG) & DbgFlag) ) #define DEBUGF(FLAG) if( (FLAG & DbgFlag) ) logDebug #define DEBUGFC(FLAG) if( (FLAG & DbgFlag) ) #define DEBUGFSET(FLAG) ( (FLAG & DbgFlag) ) /* Debug variable level */ #define DEBUG1 DEBUGC(1,DRECV1|DCTRL1|DLPQ1|DLPRM1) #define DEBUGL1 DEBUGL(1,DRECV1|DCTRL1|DLPQ1|DLPRM1) #define DEBUG2 DEBUGC(2,DRECV2|DCTRL2|DLPQ2|DLPRM2) #define DEBUGL2 DEBUGL(2,DRECV2|DCTRL2|DLPQ2|DLPRM2) #define DEBUG3 DEBUGC(3,DRECV3|DCTRL3|DLPQ3|DLPRM3) #define DEBUGL3 DEBUGL(3,DRECV3|DCTRL3|DLPQ3|DLPRM3) #define DEBUG4 DEBUGC(4,DRECV4|DCTRL4|DLPQ4|DLPRM4) #define DEBUGL4 DEBUGL(4,DRECV4|DCTRL4|DLPQ4|DLPRM4) #define DEBUG5 DEBUGC(5,0) #define DEBUGL5 DEBUGL(5,0) #define DEBUG6 DEBUGC(6,0) #define DEBUGL6 DEBUGL(6,0) #endif /* Flags for debugging */ #define DPRSHIFT 0 #define DLOGMASK ((0xF<", "", " All rights reserved.", "", "You may use \"LPRng\" or \"IFHP\" under either the terms of the GNU", "GPL License or the Artistc License. These licenses are included", "below. The licenses were obtained from the http://www.opensource.org", "web site on 28 Aug 2003.", "", " These Licenses apply to the computer software packages known as", "\"LPRng\", \"IFHP\", and associated files. The \"Package\" or \"Program\"", "below refers to the programs, files, and associated software which", "are distributed as the package.", "", " The \"LPRng\" Software Package is a copyrighted work whose copyright", "is held by Patrick Powell.", "", " The \"IFHP\" Software Package is a copyrighted work whose copyright", "is held by Patrick Powell.", "", " The \"LPRngTool\" Software Package is a copyrighted work whose copyright", "is held by Patrick Powell.", "", " BY MODIFYING OR DISTRIBUTING THE PROGRAM (OR ANY WORK BASED ON THE", "PROGRAM), YOU INDICATE YOUR ACCEPTANCE OF THIS LICENSE TO DO SO, AND ALL", "ITS TERMS AND CONDITIONS FOR COPYING, DISTRIBUTING OR MODIFYING THE", "PROGRAM OR WORKS BASED ON IT. NOTHING OTHER THAN THIS LICENSE GRANTS", "YOU PERMISSION TO MODIFY OR DISTRIBUTE THE PROGRAM OR ITS DERIVATIVE", "WORKS. THESE ACTIONS ARE PROHIBITED BY LAW. IF YOU DO NOT ACCEPT THESE", "TERMS AND CONDITIONS, DO NOT MODIFY OR DISTRIBUTE THE PROGRAM.", "", "-----------------------------------------------------------------------", " Addendum Fri Jun 21 17:06:33 PDT 2002", "", "If you wish to distribute the LPRng source code or binaries of any", "of the programs in the LPRng packages under terms of the GNU license,", "then when any package or portion of the LPRng is configured to use", "any facility or utility of the OpenSSL distribution, the additional", "following clause will be applied, as recommended in the OpenSSL", "0.9.6c release FAQ:", "", "\"This program is released under the GPL with the additional exemption that", "compiling, linking, and/or using OpenSSL is allowed.\"", "", "-----------------------------------------------------------------------", "", " GNU GENERAL PUBLIC LICENSE", " Version 2, June 1991", "", " Copyright (C) 1989, 1991 Free Software Foundation, Inc.", " 675 Mass Ave, Cambridge, MA 02139, USA", " Everyone is permitted to copy and distribute verbatim copies", " of this license document, but changing it is not allowed.", "", " Preamble", "", " The licenses for most software are designed to take away your", "freedom to share and change it. By contrast, the GNU General Public", "License is intended to guarantee your freedom to share and change free", "software--to make sure the software is free for all its users. This", "General Public License applies to most of the Free Software", "Foundation's software and to any other program whose authors commit to", "using it. (Some other Free Software Foundation software is covered by", "the GNU Library General Public License instead.) You can apply it to", "your programs, too.", "", " When we speak of free software, we are referring to freedom, not", "price. Our General Public Licenses are designed to make sure that you", "have the freedom to distribute copies of free software (and charge for", "this service if you wish), that you receive source code or can get it", "if you want it, that you can change the software or use pieces of it", "in new free programs; and that you know you can do these things.", "", " To protect your rights, we need to make restrictions that forbid", "anyone to deny you these rights or to ask you to surrender the rights.", "These restrictions translate to certain responsibilities for you if you", "distribute copies of the software, or if you modify it.", "", " For example, if you distribute copies of such a program, whether", "gratis or for a fee, you must give the recipients all the rights that", "you have. You must make sure that they, too, receive or can get the", "source code. And you must show them these terms so they know their", "rights.", "", " We protect your rights with two steps: (1) copyright the software, and", "(2) offer you this license which gives you legal permission to copy,", "distribute and/or modify the software.", "", " Also, for each author's protection and ours, we want to make certain", "that everyone understands that there is no warranty for this free", "software. If the software is modified by someone else and passed on, we", "want its recipients to know that what they have is not the original, so", "that any problems introduced by others will not reflect on the original", "authors' reputations.", "", " Finally, any free program is threatened constantly by software", "patents. We wish to avoid the danger that redistributors of a free", "program will individually obtain patent licenses, in effect making the", "program proprietary. To prevent this, we have made it clear that any", "patent must be licensed for everyone's free use or not licensed at all.", "", " The precise terms and conditions for copying, distribution and", "modification follow.", "", " GNU GENERAL PUBLIC LICENSE", " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION", "", " 0. This License applies to any program or other work which contains", "a notice placed by the copyright holder saying it may be distributed", "under the terms of this General Public License. The \"Program\", below,", "refers to any such program or work, and a \"work based on the Program\"", "means either the Program or any derivative work under copyright law:", "that is to say, a work containing the Program or a portion of it,", "either verbatim or with modifications and/or translated into another", "language. (Hereinafter, translation is included without limitation in", "the term \"modification\".) Each licensee is addressed as \"you\".", "", "Activities other than copying, distribution and modification are not", "covered by this License; they are outside its scope. The act of", "running the Program is not restricted, and the output from the Program", "is covered only if its contents constitute a work based on the", "Program (independent of having been made by running the Program).", "Whether that is true depends on what the Program does.", "", " 1. You may copy and distribute verbatim copies of the Program's", "source code as you receive it, in any medium, provided that you", "conspicuously and appropriately publish on each copy an appropriate", "copyright notice and disclaimer of warranty; keep intact all the", "notices that refer to this License and to the absence of any warranty;", "and give any other recipients of the Program a copy of this License", "along with the Program.", "", "You may charge a fee for the physical act of transferring a copy, and", "you may at your option offer warranty protection in exchange for a fee.", "", " 2. You may modify your copy or copies of the Program or any portion", "of it, thus forming a work based on the Program, and copy and", "distribute such modifications or work under the terms of Section 1", "above, provided that you also meet all of these conditions:", "", " a) You must cause the modified files to carry prominent notices", " stating that you changed the files and the date of any change.", "", " b) You must cause any work that you distribute or publish, that in", " whole or in part contains or is derived from the Program or any", " part thereof, to be licensed as a whole at no charge to all third", " parties under the terms of this License.", "", " c) If the modified program normally reads commands interactively", " when run, you must cause it, when started running for such", " interactive use in the most ordinary way, to print or display an", " announcement including an appropriate copyright notice and a", " notice that there is no warranty (or else, saying that you provide", " a warranty) and that users may redistribute the program under", " these conditions, and telling the user how to view a copy of this", " License. (Exception: if the Program itself is interactive but", " does not normally print such an announcement, your work based on", " the Program is not required to print an announcement.)", "", "These requirements apply to the modified work as a whole. If", "identifiable sections of that work are not derived from the Program,", "and can be reasonably considered independent and separate works in", "themselves, then this License, and its terms, do not apply to those", "sections when you distribute them as separate works. But when you", "distribute the same sections as part of a whole which is a work based", "on the Program, the distribution of the whole must be on the terms of", "this License, whose permissions for other licensees extend to the", "entire whole, and thus to each and every part regardless of who wrote it.", "", "Thus, it is not the intent of this section to claim rights or contest", "your rights to work written entirely by you; rather, the intent is to", "exercise the right to control the distribution of derivative or", "collective works based on the Program.", "", "In addition, mere aggregation of another work not based on the Program", "with the Program (or with a work based on the Program) on a volume of", "a storage or distribution medium does not bring the other work under", "the scope of this License.", "", " 3. You may copy and distribute the Program (or a work based on it,", "under Section 2) in object code or executable form under the terms of", "Sections 1 and 2 above provided that you also do one of the following:", "", " a) Accompany it with the complete corresponding machine-readable", " source code, which must be distributed under the terms of Sections", " 1 and 2 above on a medium customarily used for software interchange; or,", "", " b) Accompany it with a written offer, valid for at least three", " years, to give any third party, for a charge no more than your", " cost of physically performing source distribution, a complete", " machine-readable copy of the corresponding source code, to be", " distributed under the terms of Sections 1 and 2 above on a medium", " customarily used for software interchange; or,", "", " c) Accompany it with the information you received as to the offer", " to distribute corresponding source code. (This alternative is", " allowed only for noncommercial distribution and only if you", " received the program in object code or executable form with such", " an offer, in accord with Subsection b above.)", "", "The source code for a work means the preferred form of the work for", "making modifications to it. For an executable work, complete source", "code means all the source code for all modules it contains, plus any", "associated interface definition files, plus the scripts used to", "control compilation and installation of the executable. However, as a", "special exception, the source code distributed need not include", "anything that is normally distributed (in either source or binary", "form) with the major components (compiler, kernel, and so on) of the", "operating system on which the executable runs, unless that component", "itself accompanies the executable.", "", "If distribution of executable or object code is made by offering", "access to copy from a designated place, then offering equivalent", "access to copy the source code from the same place counts as", "distribution of the source code, even though third parties are not", "compelled to copy the source along with the object code.", "", " 4. You may not copy, modify, sublicense, or distribute the Program", "except as expressly provided under this License. Any attempt", "otherwise to copy, modify, sublicense or distribute the Program is", "void, and will automatically terminate your rights under this License.", "However, parties who have received copies, or rights, from you under", "this License will not have their licenses terminated so long as such", "parties remain in full compliance.", "", " 5. You are not required to accept this License, since you have not", "signed it. However, nothing else grants you permission to modify or", "distribute the Program or its derivative works. These actions are", "prohibited by law if you do not accept this License. Therefore, by", "modifying or distributing the Program (or any work based on the", "Program), you indicate your acceptance of this License to do so, and", "all its terms and conditions for copying, distributing or modifying", "the Program or works based on it.", "", " 6. Each time you redistribute the Program (or any work based on the", "Program), the recipient automatically receives a license from the", "original licensor to copy, distribute or modify the Program subject to", "these terms and conditions. You may not impose any further", "restrictions on the recipients' exercise of the rights granted herein.", "You are not responsible for enforcing compliance by third parties to", "this License.", "", " 7. If, as a consequence of a court judgment or allegation of patent", "infringement or for any other reason (not limited to patent issues),", "conditions are imposed on you (whether by court order, agreement or", "otherwise) that contradict the conditions of this License, they do not", "excuse you from the conditions of this License. If you cannot", "distribute so as to satisfy simultaneously your obligations under this", "License and any other pertinent obligations, then as a consequence you", "may not distribute the Program at all. For example, if a patent", "license would not permit royalty-free redistribution of the Program by", "all those who receive copies directly or indirectly through you, then", "the only way you could satisfy both it and this License would be to", "refrain entirely from distribution of the Program.", "", "If any portion of this section is held invalid or unenforceable under", "any particular circumstance, the balance of the section is intended to", "apply and the section as a whole is intended to apply in other", "circumstances.", "", "It is not the purpose of this section to induce you to infringe any", "patents or other property right claims or to contest validity of any", "such claims; this section has the sole purpose of protecting the", "integrity of the free software distribution system, which is", "implemented by public license practices. Many people have made", "generous contributions to the wide range of software distributed", "through that system in reliance on consistent application of that", "system; it is up to the author/donor to decide if he or she is willing", "to distribute software through any other system and a licensee cannot", "impose that choice.", "", "This section is intended to make thoroughly clear what is believed to", "be a consequence of the rest of this License.", "", " 8. If the distribution and/or use of the Program is restricted in", "certain countries either by patents or by copyrighted interfaces, the", "original copyright holder who places the Program under this License", "may add an explicit geographical distribution limitation excluding", "those countries, so that distribution is permitted only in or among", "countries not thus excluded. In such case, this License incorporates", "the limitation as if written in the body of this License.", "", " 9. The Free Software Foundation may publish revised and/or new versions", "of the General Public License from time to time. Such new versions will", "be similar in spirit to the present version, but may differ in detail to", "address new problems or concerns.", "", "Each version is given a distinguishing version number. If the Program", "specifies a version number of this License which applies to it and \"any", "later version\", you have the option of following the terms and conditions", "either of that version or of any later version published by the Free", "Software Foundation. If the Program does not specify a version number of", "this License, you may choose any version ever published by the Free Software", "Foundation.", "", " 10. If you wish to incorporate parts of the Program into other free", "programs whose distribution conditions are different, write to the author", "to ask for permission. For software which is copyrighted by the Free", "Software Foundation, write to the Free Software Foundation; we sometimes", "make exceptions for this. Our decision will be guided by the two goals", "of preserving the free status of all derivatives of our free software and", "of promoting the sharing and reuse of software generally.", "", " NO WARRANTY", "", " 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY", "FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN", "OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES", "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED", "OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF", "MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS", "TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE", "PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,", "REPAIR OR CORRECTION.", "", " 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING", "WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR", "REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,", "INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING", "OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED", "TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY", "YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER", "PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE", "POSSIBILITY OF SUCH DAMAGES.", "", " END OF TERMS AND CONDITIONS", "", " Appendix: How to Apply These Terms to Your New Programs", "", " If you develop a new program, and you want it to be of the greatest", "possible use to the public, the best way to achieve this is to make it", "free software which everyone can redistribute and change under these terms.", "", " To do so, attach the following notices to the program. It is safest", "to attach them to the start of each source file to most effectively", "convey the exclusion of warranty; and each file should have at least", "the \"copyright\" line and a pointer to where the full notice is found.", "", " ", " Copyright (C) 19yy ", "", " This program 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.", "", " This program 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 this program; if not, write to the Free Software", " Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.", "", "Also add information on how to contact you by electronic and paper mail.", "", "If the program is interactive, make it output a short notice like this", "when it starts in an interactive mode:", "", " Gnomovision version 69, Copyright (C) 19yy name of author", " Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.", " This is free software, and you are welcome to redistribute it", " under certain conditions; type `show c' for details.", "", "The hypothetical commands `show w' and `show c' should show the appropriate", "parts of the General Public License. Of course, the commands you use may", "be called something other than `show w' and `show c'; they could even be", "mouse-clicks or menu items--whatever suits your program.", "", "You should also get your employer (if you work as a programmer) or your", "school, if any, to sign a \"copyright disclaimer\" for the program, if", "necessary. Here is a sample; alter the names:", "", " Yoyodyne, Inc., hereby disclaims all copyright interest in the program", " `Gnomovision' (which makes passes at compilers) written by James Hacker.", "", " , 1 April 1989", " Ty Coon, President of Vice", "", "This General Public License does not permit incorporating your program into", "proprietary programs. If your program is a subroutine library, you may", "consider it more useful to permit linking proprietary applications with the", "library. If this is what you want to do, use the GNU Library General", "Public License instead of this License.", "", "--------------------------------------------------------------------------------------------", "", "From http://www.opensource.org - The Artistic License", "Version as of 28 Aug, 2003", "", " The Artistic License", "", "Preamble", "", "The intent of this document is to state the conditions under which", "a Package may be copied, such that the Copyright Holder maintains", "some semblance of artistic control over the development of the", "package, while giving the users of the package the right to use and", "distribute the Package in a more-or-less customary fashion, plus", "the right to make reasonable modifications.", "", "Definitions:", "", "\"Package\" refers to the collection of files distributed by the", "Copyright Holder, and derivatives of that collection of files created", "through textual modification.", "", "\"Standard Version\" refers to such a Package if it has not been", "modified, or has been modified in accordance with the wishes of the", "Copyright Holder.", "", "\"Copyright Holder\" is whoever is named in the copyright or copyrights", "for the package.", "", "\"You\" is you, if you're thinking about copying or distributing this", "Package.", "", "\"Reasonable copying fee\" is whatever you can justify on the basis", "of media cost, duplication charges, time of people involved, and", "so on. (You will not be required to justify it to the Copyright", "Holder, but only to the computing community at large as a market", "that must bear the fee.)", "", "\"Freely Available\" means that no fee is charged for the item itself,", "though there may be fees involved in handling the item. It also", "means that recipients of the item may redistribute it under the", "same conditions they received it.", "", "1. You may make and give away verbatim copies of the source form", "of the Standard Version of this Package without restriction, provided", "that you duplicate all of the original copyright notices and", "associated disclaimers.", "", "2. You may apply bug fixes, portability fixes and other modifications", "derived from the Public Domain or from the Copyright Holder. A", "Package modified in such a way shall still be considered the Standard", "Version.", "", "3. You may otherwise modify your copy of this Package in any way,", "provided that you insert a prominent notice in each changed file", "stating how and when you changed that file, and provided that you", "do at least ONE of the following:", "", "a) place your modifications in the Public Domain or otherwise make", "them Freely Available, such as by posting said modifications to", "Usenet or an equivalent medium, or placing the modifications on a", "major archive site such as ftp.uu.net, or by allowing the Copyright", "Holder to include your modifications in the Standard Version of the", "Package.", "", "b) use the modified Package only within your corporation or", "organization.", "", "c) rename any non-standard executables so the names do not conflict", "with standard executables, which must also be provided, and provide", "a separate manual page for each non-standard executable that clearly", "documents how it differs from the Standard Version.", "", "d) make other distribution arrangements with the Copyright Holder.", "", "4. You may distribute the programs of this Package in object code", "or executable form, provided that you do at least ONE of the", "following:", "", "a) distribute a Standard Version of the executables and library", "files, together with instructions (in the manual page or equivalent)", "on where to get the Standard Version.", "", "b) accompany the distribution with the machine-readable source of", "the Package with your modifications.", "", "c) accompany any non-standard executables with their corresponding", "Standard Version executables, giving the non-standard executables", "non-standard names, and clearly documenting the differences in", "manual pages (or equivalent), together with instructions on where", "to get the Standard Version.", "", "d) make other distribution arrangements with the Copyright Holder.", "", "5. You may charge a reasonable copying fee for any distribution of", "this Package. You may charge any fee you choose for support of this", "Package. You may not charge a fee for this Package itself. However,", "you may distribute this Package in aggregate with other (possibly", "commercial) programs as part of a larger (possibly commercial)", "software distribution provided that you do not advertise this Package", "as a product of your own.", "", "6. The scripts and library files supplied as input to or produced", "as output from the programs of this Package do not automatically", "fall under the copyright of this Package, but belong to whomever", "generated them, and may be sold commercially, and may be aggregated", "with this Package.", "", "7. C or perl subroutines supplied by you and linked into this Package", "shall not be considered part of this Package.", "", "8. The name of the Copyright Holder may not be used to endorse or", "promote products derived from this software without specific prior", "written permission.", "", "9. THIS PACKAGE IS PROVIDED \"AS IS\" AND WITHOUT ANY EXPRESS OR", "IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED", "WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.", lprng-3.8.B/src/include/portable.h0000644000131400013140000005247311531672133014007 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _PLP_PORTABLE_H #define _PLP_PORTABLE_H 1 /*************************************************************************** * MODULE: portable.h * PURPOSE: * The configure program generates config.h, which defines various * macros indicating the presence or abscence of include files, etc. * However, there are some systems which pass the tests, but things * do not work correctly on them. This file will try and fix * these things up for the user. * * NOTE: if there were no problems, this file would be: * #include "config.h" * * Sigh. Patrick Powell Thu Apr 6 07:00:48 PDT 1995 * NOTE: thanks to all the folks who worked on the PLP software, * Justin Mason especially. Some of the things * that you have to do to get portability are truely bizzare. * * portable.h,v 3.14 1998/03/24 02:43:22 papowell Exp **************************************************************************/ #if !defined(EXTERN) #define EXTERN extern #define DEFINE(X) #undef DEFS #endif #ifndef __STDC__ LPRng requires ANSI Standard C compiler #endif #include #ifdef HAVE_CTYPE_H #include #endif /************************************************************************* * ARGH: some things that "configure" can't get right. *************************************************************************/ /*************************************************************************** * porting note: if you port PLP and you get some errors * caused by autoconf guessing the wrong set of functions/headers/structs, * add or change the entry for your system in the ARGH section below. * You might want to try and determine how your system is identified * by the C preprocessor and use this informaton rather than trying * to look for information in various f1les. * Patrick Powell and Justin Mason ***************************************************************************/ /************************************************************************* * APOLLO Ports * Thu Apr 6 07:01:51 PDT 1995 Patrick Powell * This appears to be historical. *************************************************************************/ #ifdef apollo # define IS_APOLLO OSVERSION /* #undef __STDC__ */ /* # define CONFLICTING_PROTOS */ #endif /************************************************************************* * ULTRIX. * Patrick Powell Thu Apr 6 07:17:34 PDT 1995 * * Take a chance on using the standard calls *************************************************************************/ #ifdef ultrix # define IS_ULTRIX OSVERSION #endif /************************************************************************* * AIX. *************************************************************************/ #ifdef _AIX32 # define IS_AIX32 OSVERSION #endif /************************************************************************* * Sun *************************************************************************/ #if defined(sun) #endif /************************************************************************* * SCO OpenServer 5.0.5 *************************************************************************/ /* normal include files do not define MAXPATHLEN - rather PATHSIZE in sys/param.h */ #ifdef sco #ifndef MAXPATHLEN #define MAXPATHLEN PATHSIZE #endif /* SCO doesn't define the S_ISSOCK POSIX macro to use in testing the stat.st_mode structure member - it appears as though a socket has st_mode = 0020000 (same as character special) */ #ifndef S_ISSOCK #define S_IFSOCK 0020000 #define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) #endif #endif /************************************************************************* * Cray *************************************************************************/ #if defined(cray) #define MAXPATHLEN 1023 #define HAVE_SIGLONGJMP 1 /* configure incorrectly chooses STATVFS */ #if defined(USE_STATFS_TYPE) #undef USE_STATFS_TYPE #endif #define USE_STATFS_TYPE SRV3_STATFS #endif /*************************************************************************/ #if defined(NeXT) # define IS_NEXT OSVERSION # define __STRICT_BSD__ #endif /*************************************************************************/ #if defined(__sgi) && defined(_SYSTYPE_SVR4) # define IS_IRIX5 OSVERSION #endif /*************************************************************************/ #if defined(__sgi) && defined(_SYSTYPE_SYSV) #define IS_IRIX4 OSVERSION #endif /*************************************************************************/ #if defined(__linux__) || defined (__linux) || defined (LINUX) # define IS_LINUX OSVERSION #endif /*************************************************************************/ #if defined(__convex__) /* Convex OS 11.0 - from w_stef */ # define IS_CONVEX OSVERSION # define LPASS8 (L004000>>16) #endif /*************************************************************************/ #ifdef _AUX_SOURCE # define IS_AUX OSVERSION # define _POSIX_SOURCE # undef SETPROCTITLE #endif /*************************************************************************/ #if defined(SNI) && defined(sinix) # define IS_SINIX OSVERSION #endif /*************************************************************************/ #if defined(__svr4__) && !defined(SVR4) # define SVR4 __svr4__ #endif /*************************************************************************** * Solaris SUNWorks CC compiler * man page indicates __SVR4 is defined, as is __unix, __sun ***************************************************************************/ #if (defined(__SVR4) || defined(_SVR4_)) && !defined(SVR4) # define SVR4 1 #endif /*************************************************************************/ #if defined(__bsdi__) # define IS_BSDI OSVERSION #endif /*************************************************************************/ /************************************************************************* * we also need some way of spotting IS_DATAGEN (Data Generals), * and IS_SEQUENT (Sequent machines). Any suggestions? * these ports probably don't work anymore... *************************************************************************/ /************************************************************************* * END OF ARGH SECTION; next: overrides from the Makefile. *************************************************************************/ /************************* * STTY functions to use * *************************/ #define SGTTYB 0 #define TERMIO 1 #define TERMIOS 2 /************************* * FSTYPE functions to use * *************************/ #define SVR3_STATFS 0 #define ULTRIX_STATFS 1 #define STATFS 2 #define STATVFS 3 #if defined(MAKE_USE_STATFS) # undef USE_STATFS # define USE_STATFS MAKE_USE_STATFS #endif #if defined(MAKE_USE_STTY) # undef USE_STTY # define USE_STTY MAKE_USE_STTY #endif /********************************************************************* * GET STANDARD INCLUDE FILES * This is the one-size-fits-all include that should grab everthing. * This has a horrible impact on compilation speed, but then, do you * want compilation speed or portability? * * Patrick Powell Thu Apr 6 07:21:10 PDT 1995 ********************************************************************* * If you do not have the following, you are doomed. Or at least * going to have an uphill hard time. * NOTE: string.h might also be strings.h on some very very odd systems * * Patrick Powell Thu Apr 6 07:21:10 PDT 1995 *********************************************************************/ /********************************************************************* * yuck -- this is a nightmare! half-baked-ANSI systems are poxy (jm) * * Note that configure checks for absolute compliance, i.e.- * older versions of SUNOS, HP-UX, do not meet this. * * Patrick Powell Thu Apr 6 07:21:10 PDT 1995 *********************************************************************/ #ifdef HAVE_UNISTD_H # include #else extern int dup2 (); extern int execve (); extern uid_t geteuid (), getegid (); #if !defined(_AIX51) extern int setgid (), getgid (); #endif #endif #ifdef HAVE_STDLIB_H # include #else char *getenv( char * ); void abort(void); #endif #include #include #include #if defined(HAVE_STRINGS_H) # include #endif #include #include #include #include #include #include #include #include #if defined(HAVE_SYS_SIGNAL_H) # include #endif #include #include #include #include #include #ifdef HAVE_MEMORY_H #include #endif #ifndef HAVE_STRCHR # define strchr index # define strrchr rindex #endif #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif /* case insensitive compare for OS without it */ #if !defined(HAVE_STRCASECMP) int strcasecmp (const char *s1, const char *s2); #endif #if !defined(HAVE_STRNCASECMP) int strncasecmp (const char *s1, const char *s2, int len ); #endif #if !defined(HAVE_STRCASECMP_DEF) int strcasecmp (const char *s1, const char *s2 ); #endif /********************************************************************* * directory management is nasty. There are two standards: * struct directory and struct dirent. * Solution: macros + a typedef. * Patrick Powell Thu Apr 6 07:44:50 PDT 1995 * *See GNU autoconf documentation for this little AHEM gem... and others * too obnoxious to believe *********************************************************************/ #if HAVE_DIRENT_H # include # define NLENGTH(dirent) strlen((dirent)->d_name) #else # define dirent direct # define NLENGTH(dirent) (dirent)->d_namlen # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif typedef struct dirent plp_dir_t; /********************************************************************* * malloc strikes again. Definition is a la ANSI C. However, * You may need to edit this on historical systems. * Patrick Powell Thu Apr 6 07:47:54 PDT 1995 *********************************************************************/ #if !defined(HAVE_STDLIB_H) # ifdef HAVE_MALLOC_H # include # else void *malloc(size_t); void free(void *); # endif #endif /********************************************************************* * Note the may already be included by some previous * lines. You may need to edit this by hand. * Better solution is to put include guards in all of the include files. * Patrick Powell Thu Apr 6 07:55:58 PDT 1995 *********************************************************************/ #ifdef TIME_WITH_SYS_TIME # include # include #else # ifdef HAVE_SYS_TIME_H # include # else # include # endif #endif #ifdef HAVE_SYS_FILE_H # include #endif #ifdef HAVE_SYS_RESOURCE_H # include #endif #ifdef HAVE_SYS_FCNTL_H # include #endif #ifdef HAVE_FCNTL_H # include #endif /* * we use the FCNTL code if we have it * We want you to define F_SETLK, etc. If they are not defined, * Then you better put a system dependent configuration * in and define them. */ #if defined(HAVE_FCNTL) && ! defined(F_SETLK) /*ABORT: "defined(HAVE_FCNTL) && ! defined(F_SETLK)"*/ #undef HAVE_FCNTL #endif #if defined(HAVE_LOCKF) && ! defined(F_LOCK) /*ABORT: "defined(HAVE_LOCKF) && ! defined(F_LOCK)"*/ /* You must fix this up */ #undef HAVE_LOCKF #endif #if defined(HAVE_FLOCK) && ! defined(LOCK_EX) /*AB0RT: "defined(HAVE_FLOCK) && ! defined(LOCK_EX)"*/ /* You must fix this up */ #undef HAVE_FLOCK #endif #ifdef HAVE_LIMITS_H #include #endif /* 4.2 BSD systems */ #ifndef S_IRUSR # define S_IRUSR S_IREAD # define S_IWUSR S_IWRITE # define S_IXUSR S_IEXEC # define S_IXGRP (S_IEXEC >> 3) # define S_IXOTH (S_IEXEC >> 6) #endif #ifndef S_ISLNK # define S_ISLNK(mode) (((mode) & S_IFLNK) == S_IFLNK) #endif #ifndef S_ISREG # define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) #endif #ifndef S_ISDIR # define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) #endif /* 4.2 BSD systems */ #ifndef SEEK_SET # define SEEK_SET 0 # define SEEK_CUR 1 # define SEEK_END 2 #endif #ifndef HAVE_KILLPG # define killpg(pg,sig) ((int) kill ((pid_t)(-(pg)), (sig))) #else extern int killpg(pid_t pgrp, int sig); #endif /*********************************************************************** * wait() stuff: most recent systems support a compatability version * of "union wait", but it's not as fully-featured as the recent stuff * that uses an "int *". However, we want to keep support for the * older BSD systems as much as possible, so it's still supported; * however, if waitpid() exists, we're POSIX.1 compliant, and we should * not use "union wait". (hack hack hack) (jm) * * I agree. See the waitchild.c code for a tour through the depths of * portability hell. * * Patrick Powell Thu Apr 6 08:03:58 PDT 1995 * ***********************************************************************/ #ifdef HAVE_WAITPID # undef HAVE_UNION_WAIT /* and good riddance */ #endif /*************************************************************************** * HAVE_UNION_WAIT will be def'd by configure if it's in , * and isn't just there for compatibility (like it is on HP/UX). ***************************************************************************/ #ifdef HAVE_UNION_WAIT typedef union wait plp_status_t; /* * with some BSDish systems, there are already #defines for this, * so we should use them if they're there. */ # ifndef WCOREDUMP # define WCOREDUMP(x) ((x).w_coredump) # endif # ifndef WEXITSTATUS # define WEXITSTATUS(x) ((x).w_retcode) # endif # ifndef WTERMSIG # define WTERMSIG(x) ((x).w_termsig) # endif # ifndef WIFSTOPPED # define WIFSTOPPED(x) ((x).w_stopval == WSTOPPED) # endif # ifndef WIFEXITED # define WIFEXITED(x) ((x).w_stopval == WEXITED) # endif #else typedef int plp_status_t; /* The POSIX defaults for these macros. (this is cheating!) */ # ifndef WTERMSIG # define WTERMSIG(x) ((x) & 0x7f) # endif # if defined(_AIX52) # undef WTERMSIG # define WTERMSIG(__x) (WIFSIGNALED(__x) ? (int)((((unsigned int)__x) >> 16) & 0xff) : -1) # endif # ifndef WCOREDUMP # define WCOREDUMP(x) ((x) & 0x80) # endif # if !defined(WEXITSTATUS) # define WEXITSTATUS(x) (((x) >> 8) & 0xff) # endif # if defined(_AIX52) # undef WEXITSTATUS # define WEXITSTATUS(__x) (WIFEXITED(__x) ? (int)((((unsigned int)__x) >> 8) & 0xff) : -1) # endif # ifndef WIFSIGNALED # define WIFSIGNALED(x) (WTERMSIG (x) != 0) # endif # ifndef WIFEXITED # define WIFEXITED(x) (WTERMSIG (x) == 0) # endif #endif /* HAVE_UNION_WAIT */ /*********************************************************************** * SVR4: SIGCHLD is really SIGCLD; #define it here. * PLP lpd _does_ handle the compatibility semantics properly * (Advanced UNIX Programming p. 281). ***********************************************************************/ #if !defined(SIGCHLD) && defined(SIGCLD) # define SIGCHLD SIGCLD #endif /*********************************************************************** * configure will set RETSIGTYPE to the type returned by signal() ***********************************************************************/ typedef RETSIGTYPE plp_signal_t; typedef plp_signal_t (*plp_sigfunc_t)(int) ; #ifndef HAVE_GETDTABLESIZE # ifdef NOFILE # define getdtablesize() NOFILE # else # ifdef NOFILES_MAX # define getdtablesize() NOFILES_MAX # endif # endif #endif #ifndef HAVE_STRDUP # ifdef __STDC__ char *strdup(const char*); # else char *strdup(); # endif #endif #ifndef IPPORT_RESERVED #define IPPORT_RESERVED 1024 #endif /* varargs declarations: */ #if defined(HAVE_STDARG_H) # include # define HAVE_STDARGS /* let's hope that works everywhere (mj) */ # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap, f) # define VA_SHIFT(v,t) ; /* no-op for ANSI */ # define VA_END va_end(ap) #else # if defined(HAVE_VARARGS_H) # include # undef HAVE_STDARGS # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap) /* f is ignored! */ # define VA_SHIFT(v,t) v = va_arg(ap,t) # define VA_END va_end(ap) # else XX ** NO VARARGS ** XX # endif #endif #if !defined(IS_ULTRIX) && defined(HAVE_SYSLOG_H) # include #endif #if defined(HAVE_SYS_SYSLOG_H) # include #endif # if !(defined(LOG_PID) && defined(LOG_NOWAIT) && defined(HAVE_OPENLOG)) # undef HAVE_OPENLOG # endif /* LOG_PID && LOG_NOWAIT */ /* * Priorities (these are ordered) */ #ifndef LOG_ERR # define LOG_EMERG 0 /* system is unusable */ # define LOG_ALERT 1 /* action must be taken immediately */ # define LOG_CRIT 2 /* critical conditions */ # define LOG_ERR 3 /* error conditions */ # define LOG_WARNING 4 /* warning conditions */ # define LOG_NOTICE 5 /* normal but signification condition */ # define LOG_INFO 6 /* informational */ # define LOG_DEBUG 7 /* debug-level messages */ #endif #ifdef LOG_LPR # define SYSLOG_FACILITY LOG_LPR #else # ifdef LOG_LOCAL0 # define SYSLOG_FACILITY LOCAL0 # else # define SYSLOG_FACILITY (0) /* for Ultrix -- facilities aren't supported */ # endif #endif /************************************************************************* * If we have SVR4 and no setpgid() then we need getpgrp() *************************************************************************/ #if defined(SVR4) || defined(__alpha__) # undef HAVE_SETPGRP_0 #endif /* * NONBLOCKING Open and IO - different flags for * different systems */ #define NONBLOCK (O_NDELAY|O_NONBLOCK) /* we no longer set HPUX, so this cannot be done automatically, * unless knowing why it was here. is O_NDELAY not defined there? * something else? Hif defined(HPUX) && HPUX<110 H undef NONBLOCK H define NONBLOCK (O_NONBLOCK) Hendif */ /********************************************************************* * AIX systems need this *********************************************************************/ #if defined(HAVE_SYS_SELECT_H) # include #endif /********************************************************************** * Signal blocking **********************************************************************/ #ifdef HAVE_SIGPROCMASK /* a signal set */ #define plp_block_mask sigset_t #else /* an integer */ #define plp_block_mask int #endif /********************************************************************** * Select() problems **********************************************************************/ #ifdef HAVE_SELECT_H #include #endif /********************************************************************** * IPV6 and newer versions **********************************************************************/ #if !defined(HAVE_INET_PTON) int inet_pton( int family, const char *strptr, void *addr ); #endif #if !defined(HAVE_INET_NTOP) const char *inet_ntop( int family, const void *addr, char *strptr, size_t len ); #endif /***************************************************** * Internationalisation of messages, using GNU gettext *****************************************************/ #if HAVE_LOCALE_H # include #else # define setlocale(category, locale) #endif #if ENABLE_NLS # include # define _(Text) gettext(Text) # ifdef gettext_noop # define N_(Text) gettext_noop(Text) # else # define N_(Text) Text # endif #else # define _(Text) Text # define N_(Text) Text # define ngettext(Singular, Plural, n) ((n==1)?(Singular):(Plural)) # define textdomain(Domain) # define bindtextdomain(Package, Directory) #endif /********************************************************************** * Cygwin Definitions **********************************************************************/ #ifdef __CYGWIN__ #define ROOTUID 18 #else #define ROOTUID 0 #endif #ifndef HAVE_FLOCK_DEF extern int flock( int fd, int operation ); #endif #if !defined(HAVE_SYSLOG_DEF) extern void syslog(int, const char *, ...); #endif #if !defined(HAVE_OPENLOG_DEF) extern int openlog( const char *ident, int logopt, int facility ); #endif #ifdef IS_AIX32 extern int seteuid(uid_t); extern int setruid(uid_t); #if !defined(_AIX51) && !defined(_AIX52) extern int setenv(char *, char *, int); #endif #endif /* IPV6 structures define */ #if defined(AF_INET6) # if defined(IN_ADDR6) # define in6_addr in_addr6 # endif #endif #if defined(HAVE_ARPA_NAMESER_H) # include #endif #if defined(HAVE_RESOLV_H) # include #endif #ifdef HAVE_INNETGR #if !defined(HAVE_INNETGR_DEF) extern int innetgr(const char *netgroup, const char *machine, const char *user, const char *domain); #endif #endif #define Cast_int_to_voidstar(v) ((void *)(long)(v)) #define Cast_ptr_to_int(v) ((int)(long)(v)) #define Cast_ptr_to_long(v) ((long)(v)) # define FPRINTF safefprintf # define STDOUT 1 # define STDERR 2 #ifdef __GNUC__ # define PRINTFATTR(fmtofs,dotsofs) __attribute__ ((format (printf, fmtofs, dotsofs))) # define NORETURN __attribute__ ((noreturn)) # define UNUSED __attribute__ ((unused)) #else # define PRINTFATTR(fmtofs,dotsofs) # define NORETURN # define UNUSED #endif #endif lprng-3.8.B/src/include/krb5_auth.h0000644000131400013140000000103711531672133014051 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _KRB5_AUTH_H #define _KRB5_AUTH_H 1 #ifndef WITHPLUGINS #include "user_auth.h" #if defined(KERBEROS) extern const struct security kerberos5_auth; extern const struct security k5conn_auth; #endif #endif #endif lprng-3.8.B/src/include/lpd.h0000644000131400013140000000272611531672133012752 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_H_ #define _LPD_H_ 1 /* * file_info - information in log file */ struct file_info { int fd; int max_size; /* maximum file size */ char *outbuffer; /* for writing */ int outmax; /* max buffer size */ char *inbuffer; /* buffer for IO */ int inmax; /* buffer size */ int start; /* starting offset */ int count; /* total size of info */ }; union val{ int v; char s[sizeof(int)]; }; EXTERN int Foreground_LPD; EXTERN char *Worker_LPD; EXTERN char *Logfile_LPD; EXTERN volatile int Reread_config; EXTERN int Started_server; /* PROTOTYPES */ int main(int argc, char *argv[], char *envp[]); static void Setup_log(char *logfile ); static void Reinit(void); static int Get_lpd_pid(void); static void Set_lpd_pid(int lockfd); static int Lock_lpd_pid(void); static int Read_server_status( int fd ); static void usage(void); static void Get_parms(int argc, char *argv[] ); static void Accept_connection( int sock ); static int Start_all( int first_scan, int *start_fd ); plp_signal_t sigchld_handler (int signo); static void Setup_waitpid (void); static void Setup_waitpid_break (void); static void Fork_error( int last_fork_pid_value ); #endif lprng-3.8.B/src/include/getqueue.h0000644000131400013140000002562011531672133014015 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: getqueue.h,v 1.4 2005/04/14 20:05:20 papowell Exp $ ***************************************************************************/ #ifndef _GETQUEUE_H #define _GETQUEUE_H EXTERN const char *CTRL_A_str DEFINE( = "\001" ); /* SSL */ EXTERN const char * ACTION DEFINE( = "action" ); EXTERN const char * ACCNTNAME DEFINE( = "R" ); EXTERN const char * ACTIVE_TIME DEFINE( = "active_time" ); EXTERN const char * ADDR DEFINE( = "addr" ); EXTERN const char * ALL DEFINE( = "all" ); EXTERN const char * ATTEMPT DEFINE( = "attempt" ); EXTERN const char * AUTH DEFINE( = "auth" ); EXTERN const char * AUTHCA DEFINE( = "authca" ); EXTERN const char * AUTHFROM DEFINE( = "authfrom" ); EXTERN const char * AUTHTYPE DEFINE( = "authtype" ); EXTERN const char * AUTHUSER DEFINE( = "authuser" ); EXTERN const char * AUTOHOLD DEFINE( = "autohold" ); EXTERN const char * BNRNAME DEFINE( = "L" ); EXTERN const char * CALL DEFINE( = "call" ); EXTERN const char * CF_OUT_IMAGE DEFINE( = "cf_out_image" ); EXTERN const char * CHANGE DEFINE( = "change" ); EXTERN const char * CLASS DEFINE( = "C" ); EXTERN const char * CLIENT DEFINE( = "client" ); EXTERN const char * CMD DEFINE( = "cmd" ); EXTERN const char * COPIES DEFINE( = "copies" ); EXTERN const char * COPY_DONE DEFINE( = "copy_done" ); EXTERN const char * HFDATAFILES DEFINE( = "hfdatafiles" ); EXTERN const char * DATAFILES DEFINE( = "datafiles" ); EXTERN const char * DATAFILE_COUNT DEFINE( = "datafile_count" ); EXTERN const char * DATE DEFINE( = "D" ); EXTERN const char * DEBUG DEFINE( = "debug" ); EXTERN const char * DEBUGFV DEFINE( = "debugfv" ); EXTERN const char * DEST DEFINE( = "dest" ); EXTERN const char * DESTINATION DEFINE( = "destination" ); EXTERN const char * DESTINATIONS DEFINE( = "destinations" ); EXTERN const char * DF_NAME DEFINE( = "df_name" ); EXTERN const char * DMALLOC_OPTIONS DEFINE( = "DMALLOC_OPTIONS" ); EXTERN const char * DMALLOC_OUTFILE DEFINE( = "dmalloc_outfile" ); EXTERN const char * DONE_TIME DEFINE( = "done_time" ); EXTERN const char * DONE_REMOVE DEFINE( = "done_remove" ); EXTERN const char * DUMP DEFINE( = "dump" ); EXTERN const char * END DEFINE( = "end" ); EXTERN const char * ERROR DEFINE( = "error" ); EXTERN const char * ERROR_TIME DEFINE( = "error_time" ); EXTERN const char * ESC_ID DEFINE( = "esc_id" ); EXTERN const char * FILENAMES DEFINE( = "filenames" ); EXTERN const char * FILE_HOSTNAME DEFINE( = "file_hostname" ); EXTERN const char * FILTER DEFINE( = "filter" ); EXTERN const char * FIRST_SCAN DEFINE( = "first_scan" ); EXTERN const char * FORMAT DEFINE( = "format" ); EXTERN const char * FORMAT_ERROR DEFINE( = "format_error" ); EXTERN const char * FORWARDING DEFINE( = "forwarding" ); EXTERN const char * FORWARD_ID DEFINE( = "forward_id" ); EXTERN const char * FROM DEFINE( = "from" ); EXTERN const char * FROMHOST DEFINE( = "H" ); EXTERN const char * HELD DEFINE( = "held" ); EXTERN const char * HF_IMAGE DEFINE( = "hf_image" ); EXTERN const char * HF_NAME DEFINE( = "hf_name" ); EXTERN const char * HOLD_ALL DEFINE( = "hold_all" ); EXTERN const char * HOLD_CLASS DEFINE( = "hold_class" ); EXTERN const char * HOLD_TIME DEFINE( = "hold_time" ); EXTERN const char * HOST DEFINE( = "host" ); EXTERN const char * HPFORMAT DEFINE( = "hpformat" ); EXTERN const char * ID DEFINE( = "id" ); EXTERN const char * IDENTIFIER DEFINE( = "A" ); EXTERN const char * INCOMING_PID DEFINE( = "incoming_pid" ); EXTERN const char * INCOMING_TIME DEFINE( = "incoming_time" ); EXTERN const char * INPUT DEFINE( = "input" ); EXTERN const char * JOBNAME DEFINE( = "J" ); EXTERN const char * JOBSEQ DEFINE( = "jobseq" ); EXTERN const char * JOBSIZE DEFINE( = "jobsize" ); EXTERN const char * JOB_TIME DEFINE( = "job_time" ); EXTERN const char * JOB_TIME_USEC DEFINE( = "job_time_usec" ); EXTERN const char * KEYID DEFINE( = "keyid" ); EXTERN const char * LOCALHOST DEFINE( = "localhost" ); EXTERN const char * LOG DEFINE( = "log" ); EXTERN const char * LOGNAME DEFINE( = "P" ); EXTERN const char * LP DEFINE( = "lp" ); EXTERN const char * LPC DEFINE( = "lpc" ); EXTERN const char * LPD DEFINE( = "lpd" ); EXTERN const char * LPD_CONF DEFINE( = "LPD_CONF" ); EXTERN const char * LPD_PORT DEFINE( = "lpd_port" ); EXTERN const char * MAILNAME DEFINE( = "M" ); EXTERN const char * MOVE DEFINE( = "move" ); EXTERN const char * MOVE_DEST DEFINE( = "move_dest" ); EXTERN const char * MOVE_COUNT DEFINE( = "move_count" ); EXTERN const char * MSG DEFINE( = "msg" ); EXTERN const char * NAME DEFINE( = "name" ); EXTERN const char * NEW_DEST DEFINE( = "new_dest" ); EXTERN const char * NONEP DEFINE( = "none" ); EXTERN const char * NUMBER DEFINE( = "number" ); EXTERN const char * OPENNAME DEFINE( = "openname" ); EXTERN const char * ORIG_IDENTIFIER DEFINE( = "orig_identifier" ); EXTERN const char * PORT DEFINE( = "port" ); EXTERN const char * PRINTABLE DEFINE( = "printable" ); EXTERN const char * PRINTER DEFINE( = "printer" ); EXTERN const char * PRINTING_ABORTED DEFINE( = "printing_aborted" ); EXTERN const char * PRINTING_DISABLED DEFINE( = "printing_disabled" ); EXTERN const char * PRIORITY DEFINE( = "priority" ); EXTERN const char * PRIORITY_TIME DEFINE( = "priority_time" ); EXTERN const char * PROCESS DEFINE( = "process" ); EXTERN const char * PRSTATUS DEFINE( = "prstatus" ); EXTERN const char * QUEUE DEFINE( = "queue" ); EXTERN const char * QUEUENAME DEFINE( = "Q" ); EXTERN const char * QUEUE_CONTROL_FILE DEFINE( = "queue_control_file" ); EXTERN const char * QUEUE_STATUS_FILE DEFINE( = "queue_status_file" ); EXTERN const char * REDIRECT DEFINE( = "redirect" ); EXTERN const char * REMOTEHOST DEFINE( = "remotehost" ); EXTERN const char * REMOTEPORT DEFINE( = "remoteport" ); EXTERN const char * REMOTEUSER DEFINE( = "remoteuser" ); EXTERN const char * REMOVE_TIME DEFINE( = "remove_time" ); EXTERN const char * SD DEFINE( = "sd" ); EXTERN const char * SEQUENCE DEFINE( = "sequence" ); EXTERN const char * SERVER DEFINE( = "server" ); EXTERN const char * SERVER_ORDER DEFINE( = "server_order" ); EXTERN const char * SERVICE DEFINE( = "service" ); EXTERN const char * SIZE DEFINE( = "size" ); EXTERN const char * SORT_KEY DEFINE( = "sort_key" ); EXTERN const char * SPOOLDIR DEFINE( = "spooldir" ); EXTERN const char * SPOOLING_DISABLED DEFINE( = "spooling_disabled" ); EXTERN const char * START_TIME DEFINE( = "start_time" ); EXTERN const char * STATE DEFINE( = "state" ); EXTERN const char * STATUS_CHANGE DEFINE( = "status_change" ); EXTERN const char * SUBSERVER DEFINE( = "subserver" ); EXTERN const char * TRACE DEFINE( = "trace" ); /* EXTERN const char * TRANSFERNAME DEFINE( = "transfername" ); */ EXTERN const char * DFTRANSFERNAME DEFINE( = "dftransfername" ); EXTERN const char * XXCFTRANSFERNAME DEFINE( = "cftransfername" ); EXTERN const char * NTRANSFERNAME DEFINE( = "ntransfername" ); EXTERN const char * OTRANSFERNAME DEFINE( = "otransfername" ); EXTERN const char * UNIXSOCKET DEFINE( = "unixsocket" ); EXTERN const char * UPDATE DEFINE( = "update" ); EXTERN const char * UPDATE_TIME DEFINE( = "update_time" ); EXTERN const char * USER DEFINE( = "user" ); EXTERN const char * VALUE DEFINE( = "value" ); /* PROTOTYPES */ int Scan_queue( struct line_list *spool_control, struct line_list *sort_order, int *pprintable, int *pheld, int *pmove, int only_queue_process, int *perr, int *pdone, const char *remove_prefix, const char *remove_suffix ); char *Get_fd_image( int fd, off_t maxsize ); char *Get_file_image( const char *file, off_t maxsize ); int Get_fd_image_and_split( int fd, int maxsize, int clean, struct line_list *l, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, char **return_image ); int Get_file_image_and_split( const char *file, int maxsize, int clean, struct line_list *l, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, char **return_image ); void Check_for_hold( struct job *job, struct line_list *spool_control ); int Get_hold_class( struct line_list *info, struct line_list *sq ); int Set_job_ticket_from_cf_info( struct job *job, char *cf_file_image, int read_cf_file ); char *Make_job_ticket_image( struct job *job ); int Set_job_ticket_file( struct job *job, struct line_list *perm_check, int fd ); void Get_job_ticket_file( int *lock_fd, struct job *job, char *job_ticket_name ); void Get_spool_control( const char *file, struct line_list *info ); void Set_spool_control( struct line_list *perm_check, const char *file, struct line_list *info ); void intval( const char *key, struct line_list *list, struct job *job ); void revintval( const char *key, struct line_list *list, struct job *job ); void strzval( const char *key, struct line_list *list, struct job *job ); void strnzval( const char *key, struct line_list *list, struct job *job ); void strval( const char *key, struct line_list *list, struct job *job, int reverse ); void Make_sort_key( struct job *job ); int Setup_printer( char *prname, char *error, int errlen, int subserver ); pid_t Read_pid( int fd); pid_t Read_pid_from_file( const char *filename); int Write_pid( int fd, int pid, char *str ); int Patselect( struct line_list *token, struct line_list *cf, int starting ); int Check_format( int type, const char *name, struct job *job ); char *Frwarding(struct line_list *l); int Pr_disabled(struct line_list *l); int Sp_disabled(struct line_list *l); int Pr_aborted(struct line_list *l); int Hld_all(struct line_list *l); char *Clsses(struct line_list *l); char *Cntrol_debug(struct line_list *l); char *Srver_order(struct line_list *l); void Init_job( struct job *job ); void Free_job( struct job *job ); void Copy_job( struct job *dest, struct job *src ); char *Fix_job_number( struct job *job, int n ); char *Make_identifier( struct job *job ); void Dump_job( const char *title, struct job *job ); void Job_printable( struct job *job, struct line_list *spool_control, int *pprintable, int *pheld, int *pmove, int *perr, int *pdone ); int Server_active( char *file ); void Update_destination( struct job *job ); int Get_destination( struct job *job, int n ); int Get_destination_by_name( struct job *job, char *name ); int Trim_status_file( int status_fd, char *file, int max, int min ); char *Fix_datafile_infox( struct job *job, const char *number, const char *suffix, const char *xlate_format, int update_df_names ); void Fix_control( struct job *job, char *filter, char *xlate_format, int update_df_names ); void Init_buf(char **buf, int *max, int *len); void Put_buf_len( const char *s, int cnt, char **buf, int *max, int *len ); void Put_buf_str( const char *s, char **buf, int *max, int *len ); #endif lprng-3.8.B/src/include/lpc.h0000644000131400013140000000134411531672133012744 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPC_H_ #define _LPC_H_ 1 EXTERN int Auth; extern char LPC_optstr[]; /* number of status lines */ EXTERN char *Server; EXTERN int All_pc_printers; /* use the printers in the printcap */ /* PROTOTYPES */ int main(int argc, char *argv[], char *envp[]); static void doaction( struct line_list *args ); static void Get_parms(int argc, char *argv[] ); static void use_msg(void); static void usage(void); #endif lprng-3.8.B/src/include/child.h0000644000131400013140000000160311531672132013246 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _CHILD_H_ #define _CHILD_H_ 1 /* PROTOTYPES */ pid_t plp_waitpid (pid_t pid, plp_status_t *statusPtr, int options); int Countpid(void); void Killchildren( int sig ); pid_t dofork( int new_process_group ); plp_signal_t cleanup_USR1 (int passed_signal) NORETURN; plp_signal_t cleanup_HUP (int passed_signal) NORETURN; plp_signal_t cleanup_INT (int passed_signal) NORETURN; plp_signal_t cleanup_QUIT (int passed_signal) NORETURN; plp_signal_t cleanup_TERM (int passed_signal) NORETURN; void Max_open( int fd ); plp_signal_t cleanup (int passed_signal) NORETURN; #endif lprng-3.8.B/src/include/lpd_rcvjob.h0000644000131400013140000000164611531672133014317 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_RCVJOB_H_ #define _LPD_RCVJOB_H_ 1 /* PROTOTYPES */ int Receive_job( int *sock, char *input ); int Receive_block_job( int *sock, char *input ); int Scan_block_file( int fd, char *error, int errlen, struct line_list *header_info ); int Check_space( double jobsize, int min_space, char *pathname ); int Check_for_missing_files( struct job *job, struct line_list *files, char *error, int errlen, struct line_list *header_info, int holdfile_fd ); int Setup_temporary_job_ticket_file( struct job *job, char *filename, int read_control_file, char *cf_file_image, char *error, int errlen ); #endif lprng-3.8.B/src/include/permission.h0000644000131400013140000001023111531672133014351 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _PERMISSION_H_ #define _PERMISSION_H_ 1 /*************************************************************************** * Permissions keywords ***************************************************************************/ #define P_REJECT -1 #define P_ACCEPT 1 #define P_NOT 2 /* invert test condition */ #define P_SERVICE 3 /* Service listed below */ #define P_USER 4 /* USER field from control file (LPR) or command */ /* if a command, the user name is sent with command */ #define P_HOST 5 /* HOST field from control file */ /* if not a printing operation, then host name sent with command */ #define P_IP 6 /* IP address of HOST */ #define P_PORT 7 /* remote connect */ #define P_REMOTEHOST 8 /* remote end of connnection host name */ /* if printing, has the same value as HOST */ #define P_REMOTEIP 9 /* remote end of connnection IP address */ /* if printing, has the same value as IP */ #define P_PRINTER 10 /* printer */ #define P_DEFAULT 11 #define P_FORWARD 12 /* forward - REMOTE IP != IP */ #define P_SAMEHOST 13 /* same host - REMOTE IP == IP */ #define P_SAMEUSER 14 /* remote user name on command line == user in file */ #define P_CONTROLLINE 15 /* line from control file */ #define P_GROUP 16 /* user is in named group - uses getpwname() */ #define P_SERVER 17 /* request is from the server */ #define P_REMOTEUSER 18 /* USER from control information */ #define P_REMOTEGROUP 19 /* remote user is in named group - uses getpwname() */ #define P_IFIP 20 /* interface IP address */ #define P_LPC 21 /* LPC operations */ #define P_AUTH 22 /* authentication type - USER, SERVER, NONE */ #define P_AUTHTYPE 23 /* authentication type */ #define P_AUTHUSER 24 /* authentication user name */ #define P_AUTHFROM 25 /* from client or name */ #define P_AUTHSAMEUSER 26 /* from same authenticated user name */ #define P_AUTHJOB 27 /* job has authentication */ #define P_REMOTEPORT 28 /* alias for PORT */ #define P_UNIXSOCKET 29 /* connection via unixsocket - localhost + port 0 */ #define P_AUTHCA 30 /* Certifying authority */ /* * First character of protocol to letter mappings */ #define STARTPR 'P' /* 1 - from lPc */ #define RECVJOB 'R' /* 2 - from lpR, connection for printer */ #define TRANSFERJOB 'T' /* 2 - from lpR, user information in job */ #define SHORTSTAT 'Q' /* 3 - from lpQ */ #define LONGSTAT 'Q' /* 4 - from lpQ */ #define REMOVEJOB 'M' /* 5 - from lprM */ #define CONNECTION 'X' /* connection from remote host */ struct perm_check { const char *user; /* USER field from control file */ /* or REMOTEUSER from command line */ const char *remoteuser; /* remote user name sent on command line */ /* or USER field if no command line */ struct host_information *host; /* HOST field from control file */ /* or REMOTEHOST if no control file */ struct host_information *remotehost;/* remote HOST name making connection */ /* or HOST if no control file */ int port; /* port for remote connection */ const char *printer; /* printer name */ /* struct sockaddr addr; / * IF address information */ int unix_socket; /* connection via unix socket */ int service; /* first character service */ const char *lpc; /* lpc operation */ const char *authtype; /* authentication type */ const char *authfrom; /* authentication from */ const char *authuser; /* user from */ const char *authca; /* authentication certifying authority */ }; EXTERN struct perm_check Perm_check; /* PROTOTYPES */ const char *perm_str( int n ); int Perms_check( struct line_list *perms, struct perm_check *check, struct job *job, int job_check ); int match( struct line_list *list, const char *str, int invert ); void Dump_perm_check( const char *title, struct perm_check *check ); void Perm_check_to_list( struct line_list *list, struct perm_check *check ); #endif lprng-3.8.B/src/include/utilities.h0000644000131400013140000000630111531672133014177 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _UTILITIES_H_ #define _UTILITIES_H_ 1 #include EXTERN volatile int Alarm_timed_out; /* flag */ EXTERN volatile int Timeout_pending; #if defined(HAVE_SIGLONGJMP) EXTERN sigjmp_buf Timeout_env; # define Set_timeout() (sigsetjmp(Timeout_env,1)==0) #else EXTERN jmp_buf Timeout_env; # define Set_timeout() (setjmp(Timeout_env)==0) #endif /* PROTOTYPES */ char *Time_str(int shortform, time_t t); char *Pretty_time( time_t t ); time_t Convert_to_time_t( char *str ); void Printlist( const char **m, int fd ); int Write_fd_len( int fd, const char *msg, int len ); int Write_fd_len_timeout( int timeout, int fd, const char *msg, int len ); int Write_fd_str( int fd, const char *msg ); int Write_fd_str_timeout( int timeout, int fd, const char *msg ); int Read_fd_len_timeout( int timeout, int fd, char *msg, int len ); plp_sigfunc_t plp_signal (int signo, plp_sigfunc_t func); plp_sigfunc_t plp_signal_break (int signo, plp_sigfunc_t func); void plp_block_all_signals ( plp_block_mask *oblock ); void plp_unblock_all_signals ( plp_block_mask *oblock ); void plp_set_signal_mask ( plp_block_mask *in, plp_block_mask *out ); void plp_unblock_one_signal ( int sig, plp_block_mask *oblock ); void plp_block_one_signal( int sig, plp_block_mask *oblock ); void plp_sigpause( void ); int safestrcasecmp (const char *s1, const char *s2); int safestrncasecmp (const char *s1, const char *s2, int len ); int safestrcmp( const char *s1, const char *s2 ); int safestrlen( const char *s1 ); int safestrncmp( const char *s1, const char *s2, int len ); char *safestrchr( const char *s1, int c ); char *safestrrchr( const char *s1, int c ); char *safestrpbrk( const char *s1, const char *s2 ); int plp_usleep( int i ); int plp_sleep( int i ); int Get_max_servers( void ); int Get_max_fd( void ); char *Brk_check_size( void ); char *mystrncat( char *s1, const char *s2, int len ); char *mystrncpy( char *s1, const char *s2, int len ); int Get_nonblock_io( int fd ); int Set_nonblock_io( int fd ); int Set_block_io( int fd ); int Read_write_timeout( int readfd, char *inbuffer, int maxinlen, int *readlen, int writefd, char **outbuffer, int *outlen, int timeout ); void Set_timeout_signal_handler( int timeout, plp_sigfunc_t handler ); void Set_timeout_alarm( int timeout ); void Set_timeout_break( int timeout ); void Clear_timeout( void ); void Setup_uid(void); int To_euid_root(void); int To_daemon(void); int To_user(void); int To_ruid(int ruid); int To_euid( int euid ); int setuid_wrapper(uid_t to); int Full_daemon_perms(void); int Full_root_perms(void); int Full_user_perms(void); int Getdaemon(void); int Getdaemon_group(void); int Set_full_group( int euid, int gid ); int Setdaemon_group(void); void Reset_daemonuid(void); double Space_avail( const char *pathname ); /* VARARGS2 */ #ifdef HAVE_STDARGS int safefprintf (int fd, const char *format,...) PRINTFATTR(2,3) #else int safefprintf (va_alist) va_dcl #endif ; #endif lprng-3.8.B/src/include/stty.h0000644000131400013140000000100211531672133013160 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: stty.h,v 1.74 2004/09/24 20:20:01 papowell Exp $ ***************************************************************************/ #ifndef _STTY_H_ #define _STTY_H_ 1 /* PROTOTYPES */ void Do_stty( int fd ); void Do_stty( int fd ); void Do_stty( int fd ); #endif lprng-3.8.B/src/include/lockfile.h0000644000131400013140000000101411531672133013750 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: lockfile.h,v 1.74 2004/09/24 20:20:00 papowell Exp $ ***************************************************************************/ #ifndef _LOCKFILE_H_ #define _LOCKFILE_H_ 1 /* PROTOTYPES */ int Do_lock( int fd, int block ); int LockDevice(int fd, int block ); #endif lprng-3.8.B/src/include/errormsg.h0000644000131400013140000000414311531672132014025 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _ERRORMSG_H_ #define _ERRORMSG_H_ 1 #define LOGDEBUG logDebug #define DIEMSG Diemsg #define WARNMSG Warnmsg #define MESSAGE Message /* PROTOTYPES */ #ifdef HAVE_STRERROR #define Errormsg strerror #else const char * Errormsg ( int err ); #endif /* VARARGS2 */ #ifdef HAVE_STDARGS void logmsg(int kind, const char *msg,...) PRINTFATTR(2,3) #else void logmsg(va_alist) va_dcl #endif ; /* VARARGS2 */ #ifdef HAVE_STDARGS void fatal (int kind, const char *msg,...) PRINTFATTR(2,3) #else void fatal (va_alist) va_dcl #endif ; /* VARARGS2 */ #ifdef HAVE_STDARGS void logerr (int kind, const char *msg,...) PRINTFATTR(2,3) #else void logerr (va_alist) va_dcl #endif ; /* VARARGS2 */ #ifdef HAVE_STDARGS void logerr_die (int kind, const char *msg,...) PRINTFATTR(2,3) #else void logerr_die (va_alist) va_dcl #endif ; /* VARARGS1 */ #ifdef HAVE_STDARGS void Diemsg (const char *msg,...) PRINTFATTR(1,2) #else void Diemsg (va_alist) va_dcl #endif ; /* VARARGS1 */ #ifdef HAVE_STDARGS void Warnmsg (const char *msg,...) PRINTFATTR(1,2) #else void Warnmsg (va_alist) va_dcl #endif ; /* VARARGS1 */ #ifdef HAVE_STDARGS void Message (const char *msg,...) PRINTFATTR(1,2) #else void Message (va_alist) va_dcl #endif ; /* VARARGS1 */ #ifdef HAVE_STDARGS void logDebug (const char *msg,...) PRINTFATTR(1,2) #else void logDebug (va_alist) va_dcl #endif ; const char *Sigstr (int n); const char *Decode_status (plp_status_t *status); const char *Server_status( int d ); struct job; /* VARARGS2 */ #ifdef HAVE_STDARGS void setstatus (struct job *job,const char *fmt,...) PRINTFATTR(2,3) #else void setstatus (va_alist) va_dcl #endif ; /* VARARGS2 */ #ifdef HAVE_STDARGS void setmessage (struct job *job,const char *header, const char *fmt,...) PRINTFATTR(3,4) #else void setmessage (va_alist) va_dcl #endif ; #endif lprng-3.8.B/src/include/getopt.h0000644000131400013140000000104011531672132013460 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _GETOPT_H_ #define _GETOPT_H_ 1 extern int Optind, Opterr; extern char *Optarg; extern const char *Name; /* program name */ /* PROTOTYPES */ int Getopt (int argc, char *argv[], const char *optstring); #endif lprng-3.8.B/src/include/lpr.h0000644000131400013140000000506511531672133012767 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: lpr.h,v 1.74 2004/09/24 20:20:00 papowell Exp $ ***************************************************************************/ #ifndef _LPR_1_ #define _LPR_1_ EXTERN char *Accntname_JOB; /* Accounting name: PLP 'R' control file option */ EXTERN int Auth_JOB; /* Use authentication */ EXTERN int Binary_JOB; /* Binary format: 'l' Format */ EXTERN char *Bnrname_JOB; /* Banner name: RFC 'L' option */ EXTERN char *Classname_JOB; /* Class name: RFC 'C' option */ EXTERN int Copies_JOB; /* Copies */ EXTERN int Direct_JOB; /* Connect and send to TCP/IP port */ EXTERN int Format_JOB; /* format for printing: lower case letter */ EXTERN char *Font1_JOB; /* Font information 1 */ EXTERN char *Font2_JOB; /* Font information 2 */ EXTERN char *Font3_JOB; /* Font information 3 */ EXTERN char *Font4_JOB; /* Font information 4 */ EXTERN int Indent_JOB; /* indent: RFC 'I' option */ EXTERN char *Jobname_JOB; /* Job name: RFC 'J' option */ EXTERN int Lpr_zero_file_JOB; /* LPR does file filtering and job flattening */ EXTERN int Lpr_bounce_JOB; /* LPR does file filtering and job flattening */ EXTERN char *Mailname_JOB; /* Mail name: RFC 'M' option */ EXTERN int No_header_JOB; /* No header flag: no L option in control file */ EXTERN int Priority_JOB; /* Priority */ EXTERN char *Printer_JOB; /* Printer passed as option */ EXTERN char *Prtitle_JOB; /* Pr title: RFC 'T' option */ EXTERN int Pwidth_JOB; /* Width paper: RFC 'W' option */ EXTERN int Removefiles_JOB; /* Remove files */ EXTERN char *Username_JOB; /* Specified with the -U option */ EXTERN char *Zopts_JOB; /* Z options */ EXTERN char * User_filter_JOB; /* User specified filter for job files */ extern struct jobwords Lpr_parms[]; /* parameters for LPR */ EXTERN int LP_mode_JOB; /* look like LP */ EXTERN int Silent_JOB; /* lp -s option */ EXTERN int Job_number; /* PROTOTYPES */ int main(int argc, char *argv[], char *envp[]); static void Get_parms(int argc, char *argv[] ); static void usage(void); static int Make_job( struct job *job ); static int Check_lpr_printable(char *file, int fd, struct stat *statb, int format ); static void Dienoarg(int option); static void Check_int_dup (int option, int *value, char *arg, int maxvalue); static void Check_str_dup(int option, char **value, char *arg ); #endif lprng-3.8.B/src/include/md5.h0000644000131400013140000000107611531672133012655 00000000000000#ifndef MD5_H #define MD5_H #ifdef HAVE_STDINT_H #include #else #ifdef HAVE_SYS_TYPES_H #include #else #define uint32_t unsigned int #warning make sure to find a uint32_t that is 32 bit and unsigned #endif #endif typedef struct MD5Context { uint32_t buf[4]; uint32_t bits[2]; unsigned char in[64]; } MD5_CONTEXT; #define MD5_KEY_LENGTH 16 void MD5Init(struct MD5Context *context); void MD5Update(struct MD5Context *context, const unsigned char *buf, unsigned int len); void MD5Final(struct MD5Context *context, unsigned char* digest); #endif lprng-3.8.B/src/include/copyright.h0000644000131400013140000001152211531672132014174 00000000000000"", " COPYRIGHT NOTICES", "", "Copyright (c) 1986-2001 Patrick Powell", "", "THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND", "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE", "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE", "ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE", "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL", "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS", "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)", "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT", "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF", "SUCH DAMAGE.", "", "Copyright 1986-2000, Patrick Powell, San Diego, CA.", " All rights reserved.", "The following notice is included to satisfy the requirements of the", " BSD 4.4 Software Distribution.", "", "Copyright (c) 1988 The Regents of the University of California.", " All rights reserved.", "", "Redistribution and use in source and binary forms, with or without", "modification, are permitted provided that the following conditions", "are met:", "1. Redistributions of source code must retain the above copyright", " notice, this list of conditions and the following disclaimer.", "2. Redistributions in binary form must reproduce the above copyright", " notice, this list of conditions and the following disclaimer in the", " documentation and/or other materials provided with the distribution.", "", "3. All advertising materials mentioning features or use of this software", " must display the following acknowledgement:", " This product includes software developed by the University of", " California, Berkeley and its contributors.", "4. Neither the name of the University nor the names of its contributors", " may be used to endorse or promote products derived from this software", " without specific prior written permission.", "", "July 22, 1999", "", "To All Licensees, Distributors of Any Version of BSD:", "", "As you know, certain of the Berkeley Software Distribution (\"BSD\") source", "code files require that further distributions of products containing all or", "portions of the software, acknowledge within their advertising materials", "that such products contain software developed by UC Berkeley and its", "contributors.", "", "Specifically, the provision reads:", "", "\" * 3. All advertising materials mentioning features or use of this software", " * must display the following acknowledgement:", " * This product includes software developed by the University of", " * California, Berkeley and its contributors.\"", "", "Effective immediately, licensees and distributors are no longer required to", "include the acknowledgement within advertising materials. Accordingly, the", "foregoing paragraph of those BSD Unix files containing it is hereby deleted", "in its entirety.", "", "William Hoskins", "Director, Office of Technology Licensing", "University of California, Berkeley", "", "THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND", "ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE", "IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE", "ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE", "FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL", "DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS", "OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)", "HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT", "LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY", "OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF", "SUCH DAMAGE.", "", "", "-----------------------------------------------------------------------", "", " Addendum Fri Jun 21 17:06:33 PDT 2002", "", "Under the terms of the OpenSSL license, the following statement is included:", "", "This product includes software developed by the OpenSSL Project", "for use in the OpenSSL Toolkit (http://www.openssl.org/)", "", "If you wish to distribute the LPRng source code or binaries of any", "of the programs in the LPRng packages under terms of the GNU license,", "then when any package or portion of the LPRng is configured to use", "any facility or utility of the OpenSSL distribution, the additional", "following clause will be applied, as recommended in the OpenSSL", "0.9.6c release FAQ:", "", "\"This program is released under the GPL with the additional exemption that", "compiling, linking, and/or using OpenSSL is allowed.\"", "", "-----------------------------------------------------------------------", lprng-3.8.B/src/include/linelist.h0000644000131400013140000002334611531672133014017 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LINELIST_H_ #define _LINELIST_H_ 1 /* * arrays of pointers to lines */ #define cval(x) (int)(*(unsigned const char *)(x)) struct line_list { char **list; /* array of pointers to lines */ int count; /* number of entries */ int max; /* maximum number of entries */ }; typedef void (WorkerProc)( struct line_list *args, int input ); /* * data structure for job */ struct job{ char sort_key[512]; /* sort key for job */ /* information about job in key=value format */ struct line_list info; /* data file information This actually an array of line_list structures that has the data file information indexed by keyword. There is one of each of these entries for each 'block' of datafiles in the original control file. */ struct line_list datafiles; /* routing information for a job This is really a list of lists for each destination The information per destination is accessed by keyword */ struct line_list destination; }; /* * Types of options that we can initialize or set values of */ #define FLAG_K 0 #define INTEGER_K 1 #define STRING_K 2 /* * datastructure for initialization */ struct keywords{ const char *keyword; /* name of keyword */ const char *translation;/* translation for display */ int type; /* type of entry */ void *variable; /* address of variable */ int maxval; /* value of token */ int flag; /* flag for variable */ const char *default_value; /* default value */ }; struct jobwords{ const char **keyword; /* name of value in job->info */ int type; /* type of entry */ void *variable; /* address of variable */ int maxlen; /* length of value */ const char *key; /* key we use for value */ }; /* * Variables */ extern struct keywords Pc_var_list[], DYN_var_list[]; /* we need to free these when we initialize */ EXTERN struct line_list Config_line_list, PC_filters_line_list, PC_names_line_list, PC_order_line_list, PC_info_line_list, PC_entry_line_list, PC_alias_line_list, /* User_PC_names_line_list, User_PC_order_line_list, User_PC_info_line_list, User_PC_alias_line_list, */ All_line_list, Spool_control, Sort_order, RawPerm_line_list, Perm_line_list, Perm_filters_line_list, Process_list, Tempfiles, Servers_line_list, Printer_list, Files, Status_lines, Logger_line_list, RemoteHost_line_list; EXTERN struct line_list *Allocs[] #ifdef DEFS ={ &Config_line_list, &PC_filters_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, &PC_entry_line_list, &PC_alias_line_list, /* &User_PC_names_line_list, &User_PC_order_line_list, &User_PC_info_line_list, &User_PC_alias_line_list, */ &All_line_list, &Spool_control, &Sort_order, &RawPerm_line_list, &Perm_line_list, &Perm_filters_line_list, &Tempfiles, &Servers_line_list, &Printer_list, &Files, &Status_lines, &Logger_line_list, &RemoteHost_line_list, 0 } #endif ; /* * Constants */ EXTERN const char *Option_value_sep DEFINE( = " \t=#@" ); EXTERN const char *Hash_value_sep DEFINE( = "=#" ); EXTERN const char *Whitespace DEFINE( = " \t\n\f" ); EXTERN const char *List_sep DEFINE( = "[] \t\n\f," ); EXTERN const char *Linespace DEFINE( = " \t" ); EXTERN const char *File_sep DEFINE( = " \t,;:" ); EXTERN const char *Strict_file_sep DEFINE( = ";:" ); EXTERN const char *Perm_sep DEFINE( = "=,;" ); EXTERN const char *Arg_sep DEFINE( = ",;" ); EXTERN const char *Name_sep DEFINE( = "|:" ); EXTERN const char *Line_ends DEFINE( = "\n\014\004\024" ); EXTERN const char *Line_ends_and_colon DEFINE( = "\n\014\004\024:" ); EXTERN const char *Printcap_sep DEFINE( = "|:" ); EXTERN const char *Host_sep DEFINE( = "{} \t," ); /* PROTOTYPES */ void lowercase( char *s ); void uppercase( char *s ); char *trunc_str( char *s); void *malloc_or_die( size_t size, const char *file, int line ); void *realloc_or_die( void *p, size_t size, const char *file, int line ); char *safestrdup (const char *p, const char *file, int line); char *safestrdup2( const char *s1, const char *s2, const char *file, int line ); char *safeextend2( char *s1, const char *s2, const char *file, int line ); char *safestrdup3( const char *s1, const char *s2, const char *s3, const char *file, int line ); char *safeextend3( char *s1, const char *s2, const char *s3, const char *file, int line ); char *safeextend4( char *s1, const char *s2, const char *s3, const char *s4, const char *file, int line ); char *safestrdup4( const char *s1, const char *s2, const char *s3, const char *s4, const char *file, int line ); char *safeextend5( char *s1, const char *s2, const char *s3, const char *s4, const char *s5, const char *file, int line ); char *safestrdup5( const char *s1, const char *s2, const char *s3, const char *s4, const char *s5, const char *file, int line ); void Init_line_list( struct line_list *l ); void Free_line_list( struct line_list *l ); void Free_listof_line_list( struct line_list *l ); void Check_max( struct line_list *l, int incr ); char *Add_line_list( struct line_list *l, const char *str, const char *sep, int sort, int uniq ); void Merge_line_list( struct line_list *dest, struct line_list *src, const char *sep, int sort, int uniq ); void Merge_listof_line_list( struct line_list *dest, struct line_list *src); void Split( struct line_list *l, const char *str, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, const char *escape ); char *Join_line_list( struct line_list *l, const char *sep ); char *Join_line_list_with_sep( struct line_list *l, const char *sep ); void Dump_line_list( const char *title, struct line_list *l ); void Dump_line_list_sub( const char *title, struct line_list *l ); char *Find_str_in_flat( char *str, const char *key, const char *sep ); int Find_first_key( struct line_list *l, const char *key, const char *sep, int *m ); const char *Find_exists_value( struct line_list *l, const char *key, const char *sep ); char *Find_str_value( struct line_list *l, const char *key ); char *Find_casekey_str_value( struct line_list *l, const char *key, const char *sep ); void Set_str_value( struct line_list *l, const char *key, const char *value ); void Set_casekey_str_value( struct line_list *l, const char *key, const char *value ); void Set_flag_value( struct line_list *l, const char *key, long value ); void Set_nz_flag_value( struct line_list *l, const char *key, long value ); void Set_double_value( struct line_list *l, const char *key, double value ); void Set_decimal_value( struct line_list *l, const char *key, long value ); void Remove_line_list( struct line_list *l, int mid ); int Find_flag_value( struct line_list *l, const char *key ); int Find_decimal_value( struct line_list *l, const char *key ); double Find_double_value( struct line_list *l, const char *key ); void Find_tags( struct line_list *dest, struct line_list *l, const char *key ); void Find_default_tags( struct line_list *dest, struct keywords *var_list, const char *tag ); void Read_file_list( int required, struct line_list *model, char *str, const char *linesep, int sort, const char *keysep, int uniq, int trim, int marker, int doinclude, int nocomment, int depth, int maxdepth ); void Read_fd_and_split( struct line_list *list, int fd, const char *linesep, int sort, const char *keysep, int uniq, int trim, int nocomment ); void Build_printcap_info( struct line_list *names, struct line_list *order, struct line_list *list, struct line_list *raw, struct host_information *hostname ); char *Select_pc_info( const char *id, struct line_list *info, struct line_list *aliases, struct line_list *names, struct line_list *order, struct line_list *input, int depth, int wildcard ); void Clear_var_list( struct keywords *v, int setv ); void Set_var_list( struct keywords *keys, struct line_list *values ); void Expand_percent( char **var ); void Expand_vars( void ); void Expand_hash_values( struct line_list *hash ); char *Set_DYN( char **v, const char *s ); void Clear_config( void ); void Get_config( int required, char *path ); void Reset_config( void ); void close_on_exec( int fd ); void Getprintcap_pathlist( int required, struct line_list *raw, struct line_list *filters, char *path ); void Filterprintcap( struct line_list *raw, struct line_list *filters, const char *str ); int Check_for_rg_group( char *user ); int Make_temp_fd_in_dir( char **temppath, char *dir ); int Make_temp_fd( char **temppath ); void Clear_tempfile_list(void); void Unlink_tempfiles(void); void Remove_tempfiles(void); void Split_cmd_line( struct line_list *l, char *line ); int Make_passthrough( char *line, const char *flags, struct line_list *passfd, struct job *job, struct line_list *env_init ); int Filter_file( int timeout, int input_fd, int output_fd, const char *error_header, char *pgm, const char * filter_options, struct job *job, struct line_list *env, int verbose ); char *Is_clean_name( char *s ); void Clean_name( char *s ); void Clean_meta( char *t ); void Dump_parms( const char *title, struct keywords *k ); void Dump_default_parms( int fd, const char *title, struct keywords *k ); void Fix_Z_opts( struct job *job ); void Fix_dollars( struct line_list *l, struct job *job, int nosplit, const char *flags ); char *Make_pathname( const char *dir, const char *file ); int Get_keyval( char *s, struct keywords *controlwords ); const char *Get_keystr( int c, struct keywords *controlwords ); char *Escape( const char *str, int level ); void Escape_colons( struct line_list *list ); void Unescape( char *str ); char *Fix_str( char *str ); int Shutdown_or_close( int fd ); void Fix_bq_format( int format, struct line_list *datafile ); #endif lprng-3.8.B/src/include/lpd_dispatch.h0000644000131400013140000000112111531672133014615 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_DISPATCH_H_ #define _LPD_DISPATCH_H_ 1 /* PROTOTYPES */ void Dispatch_input(int *talk, char *input, const char *from_addr ); void Service_all( struct line_list *args, int ) NORETURN; void Service_connection( struct line_list *args, int ) NORETURN; #endif lprng-3.8.B/src/include/control.h0000644000131400013140000000234011531672132013642 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: control.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _CONTROL_H_ #define _CONTROL_H_ 1 #define OP_START 1 #define OP_STOP 2 #define OP_ENABLE 3 #define OP_DISABLE 4 #define OP_ABORT 6 #define OP_KILL 7 #define OP_HOLD 8 #define OP_RELEASE 9 #define OP_TOPQ 10 #define OP_LPQ 11 #define OP_LPRM 12 #define OP_STATUS 13 #define OP_REDIRECT 14 #define OP_LPD 15 #define OP_PRINTCAP 16 #define OP_UP 17 #define OP_DOWN 18 #define OP_REREAD 19 #define OP_MOVE 20 #define OP_DEBUG 21 #define OP_HOLDALL 22 #define OP_NOHOLDALL 23 #define OP_CLASS 24 #define OP_DEFAULTQ 25 #define OP_ACTIVE 26 #define OP_REDO 27 #define OP_CLIENT 28 #define OP_SERVER 29 #define OP_MSG 30 #define OP_DEFAULTS 31 #define OP_FLUSH 32 #define OP_LANG 33 #define OP_PPD 34 /* PROTOTYPES */ int Get_controlword( char *s ); const char *Get_controlstr( int c ); #endif lprng-3.8.B/src/include/lp.h0000644000131400013140000005622411531672133012610 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LP_H_ #define _LP_H_ 1 #ifndef EXTERN #define EXTERN extern #define DEFINE(X) #endif /***************************************************************** * get the portability information and configuration *****************************************************************/ #include "portable.h" /***************************************************************** * Global variables and routines that will be common to all programs *****************************************************************/ /***************************************************************** * BUFFER SIZES * * A common size is 1024 bytes; * However, it appears that this is overkill for most purposes. * 180 bytes appears to be satisfactory for a line, * 512 for a small buffer, 1024 for a large buffer * *****************************************************************/ #define LINEBUFFER 180 #define SMALLBUFFER 512 #define LARGEBUFFER 10240 /***************************************************************** * Include files that are so common they should be included anyways *****************************************************************/ /* declare structures for forward references */ struct host_information; struct line_list; #include "linelist.h" #include "utilities.h" #include "debug.h" #include "errormsg.h" #include "plp_snprintf.h" /***************************************************************** * General variables use in the common routines; * while in principle we could segragate these, it is not worth it * as the number is relatively small *****************************************************************/ EXTERN int Optind; /* next argv to process */ EXTERN int Opterr DEFINE(=1); /* Zero disables errors msgs */ EXTERN char *Optarg; /* Pointer to option argument */ EXTERN const char *Name; /* Name of program */ extern const char *Copyright[]; /* Copyright info */ #define Version Copyright[0] EXTERN int Is_server; /* LPD sets to non-zero */ EXTERN pid_t Server_pid; /* PID of server */ EXTERN int Is_lpr; /* LPR sets to non-zero */ EXTERN int Logger_fd; /* for logger */ EXTERN int Mail_fd; /* for mail */ EXTERN int Lpd_request; /* pipe to server */ EXTERN int Doing_cleanup; /* process exiting */ EXTERN int Verbose; /* LPD sets to non-zero */ EXTERN int Warnings; /* set for warnings and not fatal - used with checkcp */ EXTERN int Errorcode; /* Exit code for an error */ EXTERN int Status_fd; /* Status file descriptor for spool queue */ EXTERN char *Outbuf, *Inbuf; /* buffer */ EXTERN int Outlen, Outmax, Inlen, Inmax; /* max and current len of buffer */ EXTERN uid_t OriginalEUID, OriginalRUID; /* original EUID, RUID values */ EXTERN uid_t OriginalEGID, OriginalRGID; /* original EGID, RGID values */ EXTERN uid_t DaemonUID; /* Daemon UID */ EXTERN uid_t UID_root; /* UID is root */ EXTERN gid_t DaemonGID; /* Daemon GID */ EXTERN int Max_fd DEFINE(=4); /* Maximum FD opened */ extern void Max_open(int fd); #if 0 typepdef void (*WorkerProc)( struct line_list *args ); struct call_list{ const char *id; void (*p)( struct line_list *args ); }; extern struct call_list Calls[]; #endif void send_to_logger( int sfd, int mfd, struct job *job, const char *header, char *msg ); /*************************************************************************** * ACKs from the remote host on job transfers ***************************************************************************/ #define ACK_SUCCESS 0 /* succeeded; delete remote copy */ #define ACK_STOP_Q 1 /* failed; no spooling to the remote queue */ #define ACK_RETRY 2 /* failed; retry later */ #define ACK_FAIL 3 /* failed; bad job */ /* * macros for the names and maximum lengths for the various fields */ #define M_DEFAULT 131 /* default limit on line length */ /* IDENTIFIER 'A' LPRng - unique job ID */ #define M_IDENTIFIER 131 /* default limit on line length */ /* CLASSNAME 'C' RFC: 31 char limit */ #define M_DATE 31 /* DATE 'D' LPRng - date job started */ #define M_CLASSNAME 1024 /* FROMHOST 'H' RFC: 31 char limit */ #define M_FROMHOST 31 /* INDENT 'I' RFC: number */ #define M_INDENT 31 /* JOBNAME 'J' RFC: 99 char limit */ #define M_JOBNAME 99 /* BNRNAME 'L' RFC: ?? char limit */ #define M_BNRNAME 31 /* FILENAME 'N' RFC: 131 char limit */ #define M_FILENAME 131 /* MAILNAME 'M' RFC: ?? char limit */ #define M_MAILNAME 131 /* FILENAME 'N' RFC: 131 char limit on 'N' entries */ #define M_NAME 131 /* LOGNAME 'P' RFC: 31 char limit */ #define M_LOGNAME 31 /* QUEUENAME 'Q' PLP: 131 char limit */ #define M_QUEUENAME 131 /* ACCNTNAME 'R' PLP: info for accounting: 131 */ #define M_ACCNTNAME 131 /* SLINKDATA 'S' RFC: number " " number */ #define M_SLINKDATA 131 /* PRTITLE 'T' RFC: 79 char limit */ #define M_PRTITLE 79 /* UNLNKFILE 'U' RFC: flag */ #define M_UNLNKFILE 131 /* PWIDTH 'W' RFC: number */ #define M_PWIDTH 31 /* ZOPTS 'Z' PLP */ #define M_ZOPTS 1024 /* FONT1 '1' RFC: ?? char limit */ /* FONT2 '2' RFC: ?? char limit */ /* FONT3 '3' RFC: ?? char limit */ /* FONT4 '4' RFC: ?? char limit */ #define M_FONT 131 /***************************************************************** * Command file option checking: * We specify the allowed order of options in the control file. * Note that '*' is a wild card * Berkeley- HPJCLIMWT1234 * PLP- HPJCLIMWT1234* *****************************************************************/ /* error codes for return values */ #define LINK_OPEN_FAIL -1 /* open or connect */ #define LINK_TRANSFER_FAIL -2 /* transfer failed */ #define LINK_ACK_FAIL -3 /* non-zero ACK on operation */ #define LINK_FILE_READ_FAIL -4 /* read from a file failed */ #define LINK_LONG_LINE_FAIL -5 /* a line was too long to read */ #define LINK_BIND_FAIL -6 /* cannot bind to port */ #define LINK_PERM_FAIL -7 /* permission failure, remove job */ #define LINK_ECONNREFUSED -8 /* connection refused */ #define LINK_ETIMEDOUT -9 /* connection timedout */ /***************************************************************** * LPD Protocol Information *****************************************************************/ /***************************************************************** * Request types * A request sent to the LPD daemon has the format: * \Xprinter [options], where \X is a single character or byte value. * The following are the values and commands *****************************************************************/ #define REQ_START 1 /* start printer */ #define REQ_RECV 2 /* transfer a printer job */ #define REQ_DSHORT 3 /* print short form of queue status */ #define REQ_DLONG 4 /* print long form of queue status */ #define REQ_REMOVE 5 /* remove jobs */ #define REQ_CONTROL 6 /* do control operation */ #define REQ_BLOCK 7 /* transfer a block format print job */ #define REQ_SECURE 8 /* secure command transfer */ #define REQ_VERBOSE 9 /* verbose status information */ #define REQ_LPSTAT 10 /* LPSTAT format */ #define REQ_K4AUTH 'k' /* krb4 authentication */ #define KLPR_SERVICE "rcmd" #define ABORT_XFER 1 /* \1\n - abort transfer */ #define CONTROL_FILE 2 /* \2 \n */ #define DATA_FILE 3 /* \3 \n */ #define safestrncat( s1, s2 ) mystrncat(s1,s2,sizeof(s1)) #define safestrncpy( s1, s2 ) mystrncpy(s1,s2,sizeof(s1)); #define STR(X) #X #ifdef ISNULL # error - you have already defined ISNULL xxx error - you have already defined ISNULL #endif #define ISNULL(X) ((X)==0||(*X)==0) /* some handy definitions */ #define CTRL_A '\001' /* * global variables with definitions done at run time */ EXTERN char *ShortHost_FQDN; /* Short hostname for logging */ EXTERN char *FQDNHost_FQDN; /* FQDN hostname */ EXTERN char* FQDNRemote_FQDN; /* FQDN of Remote host */ EXTERN char* ShortRemote_FQDN; /* Short form of Remote host */ /* EXTERN char* Auth_client_id_DYN; / * client sent/received authentication info */ EXTERN int Drop_root_DYN; /* drop root permissions */ EXTERN int Accounting_check_DYN; /* check accounting at start */ EXTERN char* Accounting_end_DYN;/* accounting at start (see also af, la, ar) */ EXTERN char* Accounting_file_DYN; /* name of accounting file (see also la, ar) */ EXTERN char* Accounting_namefixup_DYN; /* fix up accounting name */ EXTERN int Accounting_remote_DYN; /* write remote transfer accounting (if af is set) */ EXTERN char* Accounting_start_DYN;/* accounting at start (see also af, la, ar) */ EXTERN char* Allow_user_setting_DYN; /* allow users to set job submitter */ EXTERN int Allow_getenv_DYN; EXTERN int Allow_user_logging_DYN; /* allow users to get log info */ EXTERN int Always_banner_DYN; /* always print banner, ignore lpr -h option */ EXTERN char* Append_Z_DYN; /* append -Z options on outgoing or filter*/ EXTERN char* Architecture_DYN; EXTERN char* Auth_DYN; /* authentication to use to send to server */ EXTERN char* Auth_forward_DYN; /* server use authentication when forwarding */ EXTERN int Auto_hold_DYN; /* automatically hold all jobs */ EXTERN char* BK_filter_options_DYN; /* backwards compatible filter options */ EXTERN char* BK_of_filter_options_DYN; /* backwards compatible OF filter options */ EXTERN int Backwards_compatible_DYN; /* backwards-compatible: job file format */ EXTERN int Backwards_compatible_filter_DYN; /* backwards-compatible: filter parameters */ EXTERN char* Banner_end_DYN; /* end banner printing program overrides bp */ EXTERN int Banner_last_DYN; /* print banner after job instead of before */ EXTERN char* Banner_line_DYN; /* short banner line sent to banner printer */ EXTERN char* Banner_printer_DYN; /* banner printing program (see ep) */ EXTERN char* Banner_start_DYN; /* start banner printing program overrides bp */ EXTERN int Baud_rate_DYN; /* if lp is a tty, set the baud rate (see ty) */ EXTERN char* Bounce_queue_format_DYN; /* destination for bounce queue files */ EXTERN int Break_classname_priority_link_DYN; /* do not set priority from class name */ EXTERN int Check_for_nonprintable_DYN; /* lpr check for nonprintable file */ EXTERN int Check_for_protocol_violations_DYN; /* check for RFC1179 protocol violations */ EXTERN char* Chooser_DYN; /* choose the destination for a load balance queue */ EXTERN int Chooser_interval_DYN; /* interval between tests for load balance destination */ EXTERN int Chooser_scan_queue_DYN; /* scan the queue */ EXTERN char* Chooser_routine_DYN; /* choose the destination for a load balance queue */ EXTERN int Class_in_status_DYN; /* Show class in status information */ EXTERN char* Comment_tag_DYN; /* comment identifying printer (LPQ) */ EXTERN char* Config_file_DYN; EXTERN int Connect_grace_DYN; /* grace period for reconnections */ EXTERN int Connect_interval_DYN; EXTERN int Connect_timeout_DYN; EXTERN char* Control_filter_DYN; /* Control filter */ EXTERN char* Control_file_line_order_DYN; /* Control file line order */ EXTERN int Create_files_DYN; /* allow spool dir files to be created */ EXTERN char* Current_date_DYN; /* Current Date */ EXTERN char* Daemon_group_DYN; EXTERN char* Daemon_user_DYN; EXTERN char* Default_format_DYN; /* default format */ EXTERN char* Default_permission_DYN; /* default permission */ EXTERN char* Default_printer_DYN; /* default printer */ EXTERN char* Default_priority_DYN; /* default priority */ EXTERN char* Default_remote_host_DYN; EXTERN char* Default_tmp_dir_DYN; /* default temporary file directory */ EXTERN char* Destinations_DYN; /* printers that a route filter may return and we should query */ EXTERN int Discard_large_jobs_DYN; /* discard jobs that exceed max job size */ EXTERN int Done_jobs_DYN; /* keep the last NN done jobs */ EXTERN int Done_jobs_max_age_DYN; /* keep the done jobs for at least max age seconds */ EXTERN int Direct_DYN; /* allow LPR to send jobs to a socket */ EXTERN int Discard_zero_length_jobs_DYN; /* discard zero length jobs */ EXTERN int Exit_linger_timeout_DYN; /* we set this timeout on all of the sockets */ EXTERN int FF_on_close_DYN; /* print a form feed when device is closed */ EXTERN int FF_on_open_DYN; /* print a form feed when device is opened */ EXTERN int Fifo_DYN; /* FIFO (first in first out) order enforced */ EXTERN char* Fifo_lock_file_DYN; /* lock file for FIFO */ EXTERN char* Filter_DYN; /* default filter */ EXTERN int Filter_stderr_to_status_file_DYN; /* filter errors sent to :ps file */ EXTERN char* Filter_ld_path_DYN; EXTERN char* Filter_options_DYN; EXTERN char* Filter_path_DYN; EXTERN int Fake_large_file_DYN; /* fake large file size if you cannot use 0 */ EXTERN int Filter_poll_interval_DYN; /* intervals at which to check filter */ EXTERN int Force_FQDN_hostname_DYN; /* force FQDN Host name in control file */ EXTERN int Force_IPADDR_hostname_DYN; /* force IPADDR for Host name in control file */ EXTERN int Force_localhost_DYN; /* force localhost for client job transfer */ EXTERN char* Force_lpq_status_DYN; /* force lpq status format */ EXTERN int Force_poll_DYN; /* force polling job queues */ EXTERN char* Force_queuename_DYN; /* force the use of this queue name */ EXTERN char* Form_feed_DYN; /* string to send for a form feed */ EXTERN char* Formats_allowed_DYN; /* valid output filter formats */ EXTERN int Full_time_DYN; /* full or complete time format in messages */ EXTERN int Half_close_DYN; /* do shutdown on socket when sending job */ EXTERN int Generate_banner_DYN; /* generate a banner when not a bounce queue */ EXTERN char* IF_Filter_DYN; /* filter command, run on a per-file basis */ EXTERN int IPV6Protocol_DYN; /* IPV4 or IPV6 protocol */ EXTERN int Ignore_requested_user_priority_DYN; /* ignore requested user priority */ EXTERN char* Incoming_control_filter_DYN; /* incoming control file filter */ EXTERN int Keepalive_DYN; /* TCP keepalive enabled */ EXTERN char* Kerberos_keytab_DYN; /* kerberos keytab file */ EXTERN char* Kerberos_dest_id_DYN; /* kerberos destination principle */ EXTERN char* Kerberos_life_DYN; /* kerberos lifetime */ EXTERN char* Kerberos_renew_DYN; /* kerberos newal time */ EXTERN char* Kerberos_forward_principal_DYN; /* kerberos server principle */ EXTERN char* Kerberos_server_principal_DYN; /* kerberos server principle */ EXTERN char* Kerberos_service_DYN; /* kerberos service */ EXTERN int LPR_bsd_DYN; /* use BSD -m mail option */ EXTERN char* Leader_on_open_DYN; /* leader string printed on printer open */ EXTERN int Local_accounting_DYN; /* write local printer accounting (if af is set) */ EXTERN int Lock_it_DYN; /* lock the IO device */ EXTERN char* Lockfile_DYN; EXTERN char* Log_file_DYN; /* status log file */ EXTERN char* Logger_destination_DYN; /* logger host and port */ EXTERN int Logger_max_size_DYN; /* log record size */ EXTERN char* Logger_path_DYN; /* path to status log file */ EXTERN int Logger_timeout_DYN; /* logger timeout size */ EXTERN char* Logname_DYN; /* Username for logging */ EXTERN int Long_number_DYN; /* long job number (6 digits) */ EXTERN char* Lp_device_DYN; /* device name or lp-pipe command to send output to */ EXTERN int Lpd_bounce_DYN; /* force LPD to do bounce queue filtering */ EXTERN char* Lpd_listen_port_DYN; /* lpd listens on this port, "off" does not open port */ #ifdef IPP_STUBS EXTERN char* Ipp_listen_port_DYN; /* lpd listens on this port, "off" does not open port */ EXTERN char* Ipp_port_DYN; /* ipp protocol port */ #endif /* not IPP_STUBS */ EXTERN char* Lpd_path_DYN; /* LPD path for server use */ EXTERN char* Lpd_port_DYN; /* client/lpd connect to remote (non-local) lpd servers on this port */ EXTERN char* Lpd_printcap_path_DYN; EXTERN int Lpr_bounce_DYN; /* allow LPR to do bounce queue filtering */ EXTERN char* Lpq_status_file_DYN; /* cached lpq status */ EXTERN int Lpq_status_cached_DYN; /* how many to cache */ EXTERN int Lpq_status_interval_DYN; /* interval between updates */ EXTERN int Lpq_status_stale_DYN; /* cached lpq status is stale after this */ EXTERN char* Lpr_opts_DYN; /* addional options for LPR */ EXTERN int Lpr_send_try_DYN; /* number of times for lpr to try sending job */ EXTERN char* Mail_from_DYN; EXTERN char* Mail_operator_on_error_DYN; EXTERN int Max_accounting_file_size_DYN; /* maximum accounting file size */ EXTERN int Max_connect_interval_DYN; /* maximum connect interval */ EXTERN int Max_copies_DYN; /* maximum copies allowed */ EXTERN int Max_datafiles_DYN; /* maximum datafiles */ EXTERN int Max_job_size_DYN; /* maximum job size (1Kb blocks, 0 = unlimited) */ EXTERN int Max_log_file_size_DYN; /* maximum log file size */ EXTERN int Max_move_count_DYN; /* maximum number of moves or forwards */ EXTERN int Max_servers_active_DYN; /* maximum number of servers active */ EXTERN int Max_status_line_DYN; /* maximum status line size */ EXTERN int Max_status_size_DYN; EXTERN int Min_accounting_file_size_DYN; /* minimum accounting file size */ EXTERN int Min_log_file_size_DYN; /* minimum log file size */ EXTERN int Min_printable_count_DYN; /* minimum printable characters for printable check */ EXTERN int Min_status_size_DYN; EXTERN int Minfree_DYN; /* minimum space (Kb) to be left in spool filesystem */ EXTERN int Minfree_DYN; /**/ EXTERN int Ms_time_resolution_DYN; EXTERN int Network_connect_grace_DYN; /* grace period for reconnections */ EXTERN char* New_debug_DYN; /* debug level set for queue handler */ EXTERN int Nline_after_file_DYN; /* Put Nxxx after fcfA... line in control file */ EXTERN int No_FF_separator_DYN; /* no interfile FF separator */ EXTERN int FF_separator_DYN; /* no interfile FF separator */ EXTERN int Nonblocking_open_DYN; /* nonblocking open on io device */ EXTERN char* OF_Filter_DYN; /* output filter, run once for all output */ EXTERN char* OF_filter_options_DYN; EXTERN char* Originate_port_DYN; EXTERN int Order_routine_DYN; /* use user specified order routine */ EXTERN int Page_length_DYN; /* page length (in lines) */ EXTERN int Page_width_DYN; /* page width (in characters) */ EXTERN int Page_x_DYN; /* page width in pixels (horizontal) */ EXTERN int Page_y_DYN; /* page length in pixels (vertical) */ EXTERN char* Pc_entries_required_DYN; /* make sure these entries are in PRINTCAP_ENTRY */ EXTERN char* Pass_env_DYN; /* pass these environment variables */ EXTERN char *Plugin_path_DYN; /* plugin path */ EXTERN int Poll_time_DYN; /* force polling job queues */ EXTERN int Poll_start_interval_DYN; /* interval between trying to start servers */ EXTERN int Poll_servers_started_DYN; /* maximum servers to start at one time */ EXTERN char* Ppd_file_DYN; /* ppd file */ EXTERN char* Pr_program_DYN; /* pr program for p format */ EXTERN char* Prefix_Z_DYN; /* prefix -Z options on outgoing or filter*/ EXTERN char* Prefix_option_to_option_DYN; /* prefix option to option, ie, "z,o" */ EXTERN char* Printcap_path_DYN; EXTERN char* Printer_DYN; /* Printe r name for logging */ EXTERN char* Printer_DYN; /* printer name */ EXTERN char* Printer_perms_path_DYN; EXTERN char* Queue_name_DYN; /* Queue name used for spooling */ EXTERN char* Queue_control_file_DYN; /* Queue control file name */ EXTERN char* Queue_lock_file_DYN; /* Queue lock file name */ EXTERN char* Queue_status_file_DYN; /* Queue status file name */ EXTERN char* Queue_unspooler_file_DYN; /* Unspooler PID status file name */ EXTERN int Read_write_DYN; /* open the printer for reading and writing */ EXTERN char* RemoteHost_DYN; /* remote-queue machine (hostname) (with rm) */ EXTERN char* RemotePrinter_DYN; /* remote-queue printer name (with rp) */ EXTERN char* Remote_support_DYN; /* Operations allowed to remote system */ EXTERN char* Remove_Z_DYN; /* remove -Z options on outgoing or filter*/ EXTERN char* Report_server_as_DYN; /* report server name as this value */ EXTERN int Require_configfiles_DYN; /* require lpd.conf, printcap, lpd.perms files */ EXTERN int Require_explicit_Q_DYN; /* require default queue to be explicitly defined */ EXTERN char* RestrictToGroupMembers_DYN; /* restrict to group members */ EXTERN int Retry_ECONNREFUSED_DYN; /* retry on ECONNREFUSED */ EXTERN int Retry_NOLINK_DYN; /* retry on link connection failure */ EXTERN char* Return_short_status_DYN; /* return short status */ EXTERN int Reuse_addr_DYN; /* set SO_REUSEADDR on outgoing ports */ EXTERN int Reverse_priority_order_DYN; /* priority z-aZ-A order */ EXTERN char* Reverse_lpq_status_DYN; /* change lpq format when from host */ EXTERN char* Routing_filter_DYN; /* filter to determine routing of jobs */ EXTERN char* Safe_chars_DYN; /* safe characters in control file */ EXTERN int Save_on_error_DYN; /* save this job when an error */ EXTERN int Save_when_done_DYN; /* save this job when done */ EXTERN int Send_block_format_DYN; /* send block of data */ EXTERN int Send_data_first_DYN; /* send data files first */ EXTERN char* Send_failure_action_DYN; EXTERN int Send_job_rw_timeout_DYN; EXTERN int Send_query_rw_timeout_DYN; EXTERN int Send_try_DYN; EXTERN int Sendmail_to_user_DYN; EXTERN char* Sendmail_DYN; EXTERN char* Server_names_DYN; /* names of servers for queue (with ss) */ EXTERN char* Server_queue_name_DYN; /* name of queue that server serves (with sv) */ EXTERN char* Server_tmp_dir_DYN; /* default temporary file directory */ EXTERN char* Shell_DYN; EXTERN int Short_banner_DYN; /* short banner (one line only) */ EXTERN int Short_status_length_DYN; /* short status length */ EXTERN int Socket_linger_DYN; /* set SO_linger for connections to remote hosts */ EXTERN char* Spool_dir_DYN; /* spool directory (only ONE printer per directory!) */ EXTERN int Spool_dir_perms_DYN; EXTERN int Spool_file_perms_DYN; EXTERN char *Ssl_ca_file_DYN; /* ssl cert file */ EXTERN char *Ssl_ca_path_DYN; /* ssl cert directory (path) */ EXTERN char *Ssl_crl_file_DYN; /* ssl crl cert directory (path) */ EXTERN char *Ssl_crl_path_DYN; /* ssl crl cert directory (path) */ EXTERN char *Ssl_server_cert_DYN; /* ssl server cert file */ EXTERN char *Ssl_server_password_file_DYN; /* ssl server password file */ EXTERN int Stalled_time_DYN; /* amount of time before reporing stalled job */ EXTERN char* Status_file_DYN; /* printer status file name */ EXTERN int Stop_on_abort_DYN; /* stop when job aborts */ EXTERN char* Stty_command_DYN; /* stty commands to set output line characteristics */ EXTERN int Suppress_header_DYN; /* suppress headers and/or banner page */ EXTERN int Suspend_OF_filter_DYN; /* suspend OF filter */ EXTERN char* Syslog_device_DYN; /* default syslog() facility */ EXTERN char* Trailer_on_close_DYN; /* trailer string to print when queue empties */ EXTERN char* Unix_socket_path_DYN; /* UNIX socket pathname */ EXTERN int Use_info_cache_DYN; EXTERN int Use_queuename_DYN; /* put queuename in control file */ EXTERN int Use_queuename_flag_DYN; /* Specified with the -Q option */ EXTERN int Use_shorthost_DYN; /* Use short hostname in control file information */ EXTERN char* User_printcap_DYN; /* Allow a ${HOME}/.printcap file - name of file*/ EXTERN int User_is_authuser_DYN; /* set user to be authentication user value */ EXTERN char* Xlate_incoming_format_DYN; /* translate format ids on incoming jobs */ EXTERN char* Xlate_format_DYN; /* translate format ids on outgoing jobs */ #if defined(DMALLOC) # include extern int dmalloc_outfile; #endif #define ok_read read #endif lprng-3.8.B/src/include/lpd_logger.h0000644000131400013140000000065711531672133014312 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_LOGGER_H_ #define _LPD_LOGGER_H_ 1 /* PROTOTYPES */ pid_t Start_logger( int log_fd ); #endif lprng-3.8.B/src/include/errorcodes.h0000644000131400013140000000273711531672132014343 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: errorcodes.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _ERRORCODES_H_ #define _ERRORCODES_H_ 1 /* * filter return codes and job status codes * - exit status of the filter process * If a printer filter fails, then we assume JABORT status and * will record information about failure */ /* process exit codes */ #define JSUCC 0 /* 0 done */ /* from 1 - 31 are signal terminations */ #define JFAIL 32 /* 1 failed - retry later */ #define JABORT 33 /* 2 aborted - do not try again, but keep job */ #define JREMOVE 34 /* 3 failed - remove job */ #define JHOLD 37 /* 6 hold this job */ #define JNOSPOOL 38 /* 7 no spooling to this queue */ #define JNOPRINT 39 /* 8 no printing from this queue */ #define JSIGNAL 40 /* 9 killed by unrecognized signal */ #define JFAILNORETRY 41 /* 10 no retry on failure */ #define JSUSP 42 /* 11 process suspended successfully */ #define JTIMEOUT 43 /* 12 timeout */ #define JWRERR 44 /* 13 write error */ #define JRDERR 45 /* 14 read error */ #define JCHILD 46 /* 15 no children */ #define JNOWAIT 47 /* 16 no wait status */ /* PROTOTYPES */ #endif lprng-3.8.B/src/include/lpd_secure.h0000644000131400013140000000103311531672133014306 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_SECURE_H_ #define _LPD_SECURE_H_ 1 /* PROTOTYPES */ int Receive_secure( int *sock, char *input ); int Check_secure_perms( struct line_list *options, int from_server, char *error, int errlen ); #endif lprng-3.8.B/src/include/accounting.h0000644000131400013140000000102711531672132014315 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: accounting.h,v 1.74 2004/09/24 20:19:59 papowell Exp $ ***************************************************************************/ #ifndef _ACCOUNTING_H_ #define _ACCOUNTING_H_ 1 /* PROTOTYPES */ int Do_accounting( int end, char *command, struct job *job, int timeout ); #endif lprng-3.8.B/src/include/printjob.h0000644000131400013140000000145711531672133014022 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _PRINTJOB_H_ #define _PRINTJOB_H_ 1 /* PROTOTYPES */ int Print_job( int output, int status_device, struct job *job, int send_job_rw_timeout, int poll_for_status, char *user_filter ); int Get_status_from_OF( struct job *job, const char *title, int of_pid, int of_error, char *msg, int msgmax, int timeout, int suspend, int max_wait, char *status_file ); int Wait_for_pid( int of_pid, const char *name, int suspend, int timeout ); void Add_banner_to_job( struct job *job ); #endif lprng-3.8.B/src/include/sendreq.h0000644000131400013140000000135011531672133013624 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: sendreq.h,v 1.74 2004/09/24 20:20:01 papowell Exp $ ***************************************************************************/ #ifndef _SENDREQ_H_ #define _SENDREQ_H_ 1 /* PROTOTYPES */ int Send_request( int class, /* 'Q'= LPQ, 'C'= LPC, M = lprm */ int format, /* X for option */ char **options, /* options to send */ int connnect_timeout, /* timeout on connection */ int transfer_timeout, /* timeout on transfer */ int output /* output on this FD */ ); #endif lprng-3.8.B/src/include/sendjob.h0000644000131400013140000000140511531672133013610 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _SENDJOB_1_ #define _SENDJOB_1_ 1 /* PROTOTYPES */ int Send_job( struct job *job, struct job *logjob, int connect_timeout_len, int connect_interval, int max_connect_interval, int transfer_timeout, char *final_filter ); int Send_normal( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd, char *final_filter ); int Send_block( int *sock, struct job *job, struct job *logjob, int transfer_timeout ); #endif lprng-3.8.B/src/include/user_objs.h0000644000131400013140000000112211531672133014153 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * $Id: user_objs.h,v 1.74 2004/09/24 20:20:01 papowell Exp $ ***************************************************************************/ #ifndef _USER_OBJS_H_ #define _USER_OBJS_H_ 1 /* PROTOTYPES */ int test_chooser( struct line_list *servers, struct line_list *available, int *use_subserver ); char *test_sort_key( struct job *job ); #endif lprng-3.8.B/src/include/lpd_jobs.h0000644000131400013140000000112011531672133013752 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_JOBS_H_ #define _LPD_JOBS_H_ 1 /* PROTOTYPES */ int Do_queue_jobs( char *name, int subserver ); void Service_worker( struct line_list *args, int ) NORETURN; void Service_queue( struct line_list *args, int ) NORETURN; int Remove_done_jobs( void ); #endif lprng-3.8.B/src/include/initialize.h0000644000131400013140000000076311531672133014333 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _INITIALIZE_H #define _INITIALIZE_H /* PROTOTYPES */ void Initialize(int argc, char *argv[], char *envp[], int debugchar ); void Setup_configuration( void ); #endif lprng-3.8.B/src/include/lpd_status.h0000644000131400013140000000153711531672133014354 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _LPD_STATUS_H_ #define _LPD_STATUS_H_ 1 /* PROTOTYPES */ int Job_status( int *sock, char *input ); void Get_queue_status( struct line_list *tokens, int *sock, int displayformat, int status_lines, struct line_list *done_list, int max_size, char *hash_key ); void Print_different_last_status_lines( int *sock, int fd, int status_lines, int max_size ); void Get_local_or_remote_status( struct line_list *tokens, int *sock, int displayformat, int status_lines, struct line_list *done_list, int max_size, char *hash_key ); #endif lprng-3.8.B/src/include/sendauth.h0000644000131400013140000000127711531672133014006 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #ifndef _SENDAUTH_H_ #define _SENDAUTH_H_ 1 /* PROTOTYPES */ int Send_auth_transfer( int *sock, int transfer_timeout, struct job *job, struct job *logjob, char *error, int errlen, char *cmd, const struct security *security, struct line_list *info ); const struct security *Fix_send_auth( char *name, struct line_list *info, struct job *job, char *error, int errlen ); #endif lprng-3.8.B/src/Makefile.am0000644000131400013140000001630011531672131012422 00000000000000MAINTAINERCLEANFILES = Makefile.in CLEANFILES = *.tmp *core ? ?.bak ?.orig lpd.conf log lprng_certs lprng_index_certs DISTCLEANFILES = pclbanner psbanner EXTRA_DIST = pclbanner.in psbanner.in lprng_certs.sh lprng_index_certs.sh common/user_objs.c include/user_objs.h AUTHENTICATE/sserver.c AUTHENTICATE/sclient.c PATHDEFINES = "-DLOCKFILE=\"$(LOCKFILE)\"" \ "-DPRINTCAP_PATH=\"$(PRINTCAP_PATH)\"" \ "-DLPD_PRINTCAP_PATH=\"$(LPD_PRINTCAP_PATH)\"" \ "-DLPD_PERMS_PATH=\"$(LPD_PERMS_PATH)\"" \ "-DLPD_CONF_PATH=\"$(LPD_CONF_PATH)\"" \ "-DUNIXSOCKETPATH=\"$(UNIXSOCKETPATH)\"" \ "-DSSL_CA_FILE=\"$(SSL_CA_FILE)\"" \ "-DSSL_CA_KEY=\"$(SSL_CA_KEY)\"" \ "-DSSL_CRL_FILE=\"$(SSL_CRL_FILE)\"" \ "-DSSL_CERTS_DIR=\"$(SSL_CERTS_DIR)\"" \ "-DSSL_SERVER_CERT=\"$(SSL_SERVER_CERT)\"" \ "-DSSL_SERVER_PASSWORD_FILE=\"$(SSL_SERVER_PASSWORD_FILE)\"" \ "-DSD_DEFAULT=\"$(SD_DEFAULT)\"" \ "-DPLUGINDIR=\"$(plugindir)\"" AM_CPPFLAGS = -I$(srcdir)/include "-DLOCALEDIR=\"$(localedir)\"" lpdbin_PROGRAMS = lpd bin_PROGRAMS = lpr lpq lprm lpstat sbin_PROGRAMS = lpc checkpc sbin_SCRIPTS = lprng_certs lprng_index_certs filter_PROGRAMS = lpf lpbanner filter_SCRIPTS = psbanner pclbanner noinst_DATA = lpd.conf noinst_PROGRAMS = monitor # were not even compiled in the old build system # and may have issues hidden before because of static linking: # noinst_PROGRAMS = sserver sclient uninstall-hook: rm -f $(DESTDIR)$(bindir)/lp $(DESTDIR)$(bindir)/cancel if WITHPLUGINS if WITHKERBEROS rm -f $(DESTDIR)$(plugindir)/kerberos.so $(DESTDIR)$(plugindir)/k5conn.so endif endif install-exec-hook: rm -f $(DESTDIR)$(bindir)/lp $(DESTDIR)$(bindir)/cancel ln $(DESTDIR)$(bindir)/lpr $(DESTDIR)$(bindir)/lp ln $(DESTDIR)$(bindir)/lprm $(DESTDIR)$(bindir)/cancel if WITHPLUGINS if WITHKERBEROS $(mkdir_p) $(DESTDIR)$(plugindir) ln -sf kerberos5.so $(DESTDIR)$(plugindir)/kerberos.so ln -sf kerberos5.so $(DESTDIR)$(plugindir)/k5conn.so endif endif # - think about making things suid at install time COMMON_SOURCES = common/child.c common/copyright.c common/debug.c \ common/errormsg.c common/fileopen.c common/gethostinfo.c \ common/getopt.c common/getprinter.c common/getqueue.c \ common/globmatch.c common/initialize.c common/linelist.c \ common/linksupport.c common/lockfile.c common/merge.c \ common/plp_snprintf.c common/proctitle.c common/utilities.c \ vars.c MORE_SOURCES = $(COMMON_SOURCES) \ common/sendauth.c common/sendjob.c common/sendreq.c \ common/user_auth.c common/printjob.c SEND_SOURCES = $(MORE_SOURCES) \ common/openprinter.c common/stty.c # This is a crude hack, but better than needing libtool... if WITHPLUGINS MORE_LDADD = $(DL_LIBS) MORELDFLAGS = $(PLUGINUSER_LDFLAGS) plugin_PROGRAMS = if WITHKERBEROS plugin_PROGRAMS += kerberos5.so kerberos5_so_SOURCES = auth/krb5_auth.c kerberos5_so_LDFLAGS = $(PLUGIN_LDFLAGS) kerberos5_so_LDADD = $(KRB_LIBS) kerberor5_so_CFLAGS = $(PLUGIN_CFLAGS) uninstall-local: if test -l $(DESTDIR)$(plugindir)/k5conn.so ; then \ rm $(DESTDIR)$(plugindir)/k5conn.so ; fi if test -l $(DESTDIR)$(plugindir)/kerberos.so ; then \ rm $(DESTDIR)$(plugindir)/kerberos.so ; fi endif if WITHSSL plugin_PROGRAMS += ssl.so ssl_so_SOURCES = auth/ssl_auth.c ssl_so_LDFLAGS = $(PLUGIN_LDFLAGS) ssl_so_CFLAGS = $(PLUGIN_CFLAGS) ssl_so_LDADD = $(SSL_LDADD) endif plugin_PROGRAMS += md5.so md5_so_SOURCES = auth/md5_auth.c common/md5.c md5_so_LDFLAGS = $(PLUGIN_LDFLAGS) md5_so_CFLAGS = $(PLUGIN_CFLAGS) plugin_PROGRAMS += test.so test_so_SOURCES = auth/test_auth.c test_so_LDFLAGS = $(PLUGIN_LDFLAGS) test_so_CFLAGS = $(PLUGIN_CFLAGS) else MORE_LDADD = $(SSL_LDADD) $(KRB_LIBS) MORE_SOURCES += common/md5.c auth/md5_auth.c auth/test_auth.c \ auth/ssl_auth.c auth/krb5_auth.c MORELDFLAGS = endif lpd_SOURCES = common/lpd.c common/lpd_worker.c common/lpd_jobs.c \ common/lpd_control.c common/sendmail.c common/lpd_dispatch.c \ common/lpd_logger.c common/lpd_rcvjob.c common/lpd_remove.c \ common/lpd_secure.c common/lpd_status.c \ common/permission.c common/accounting.c common/controlword.c \ $(SEND_SOURCES) lpd_LDADD = $(MORE_LDADD) lpd_LDFLAGS = $(MORELDFLAGS) lpr_SOURCES = common/lpr.c $(SEND_SOURCES) lpr_LDADD = $(MORE_LDADD) lpr_LDFLAGS = $(MORELDFLAGS) lpq_SOURCES = common/lpq.c $(MORE_SOURCES) lpq_LDADD = $(MORE_LDADD) lpq_LDFLAGS = $(MORELDFLAGS) lpstat_SOURCES = common/lpstat.c $(MORE_SOURCES) lpstat_LDADD = $(MORE_LDADD) lpstat_LDFLAGS = $(MORELDFLAGS) lprm_SOURCES = common/lprm.c $(MORE_SOURCES) lprm_LDADD = $(MORE_LDADD) lprm_LDFLAGS = $(MORELDFLAGS) lpc_SOURCES = common/lpc.c common/controlword.c $(MORE_SOURCES) lpc_LDADD = $(MORE_LDADD) lpc_LDFLAGS = $(MORELDFLAGS) checkpc_SOURCES = common/checkpc.c common/stty.c $(COMMON_SOURCES) lpf_SOURCES = common/lpf.c common/plp_snprintf.c lpbanner_SOURCES = common/lpbanner.c common/plp_snprintf.c monitor_SOURCES = common/monitor.c $(COMMON_SOURCES) # sserver_SOURCES = AUTHENTICATE/sserver.c # sclient_SOURCES = AUTHENTICATE/sclient.c noinst_HEADERS = include/accounting.h include/checkpc.h include/child.h include/control.h include/copyright.h include/debug.h include/errorcodes.h include/errormsg.h include/fileopen.h include/gethostinfo.h include/getopt.h include/getprinter.h include/getqueue.h include/globmatch.h include/initialize.h include/krb5_auth.h include/license.h include/linelist.h include/linksupport.h include/lockfile.h include/lpc.h include/lpd_control.h include/lpd_dispatch.h include/lpd.h include/lpd_jobs.h include/lpd_logger.h include/lpd_rcvjob.h include/lpd_remove.h include/lpd_secure.h include/lpd_status.h include/lp.h include/lpq.h include/lpr.h include/lprm.h include/lpstat.h include/md5.h include/merge.h include/permission.h include/plp_snprintf.h include/portable.h include/printjob.h include/proctitle.h include/readstatus.h include/sendauth.h include/sendjob.h include/sendmail.h include/sendreq.h include/ssl_auth.h include/stty.h include/user_auth.h include/utilities.h include/openprinter.h include/lpd_worker.h # vars.c needs all the defines for defaults. # This only adds them for vars.c, which might need GNU make # if your make does not support it, try to add them to the # global AM_CPPFLAGS vars.$(OBJEXT): AM_CPPFLAGS += $(PATHDEFINES) vars.$(OBJEXT): ../config.h ./lpd.conf: vars.c ../config.h set -e; \ rm -f $@ ; \ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(PATHDEFINES) -C $(srcdir)/vars.c \ | $(SHELL) ../UTILS/make_lpd_conf '$(VERSION)' '$(LPD_CONF_PATH).local' >> $@ \ || rm $@ %: %.sh Makefile set -e ; \ rm -f $@ ; \ sed \ -e "s,@OPENSSL.,@OPENSSL@," \ -e "s,@SSL_CA_FILE.,@SSL_CA_FILE@," \ -e "s,@SSL_CA_KEY.,@SSL_CA_KEY@," \ -e "s,@SSL_CRL_FILE.,@SSL_CRL_FILE@," \ -e "s,@SSL_SERVER_CERT.,@SSL_SERVER_CERT@," \ -e "s,@SSL_SERVER_PASSWORD_FILE.,@SSL_SERVER_PASSWORD_FILE@," \ -e "s,@SSL_CERTS_DIR.,@SSL_CERTS_DIR@," \ $< >$@ chmod 755 $@ # run make install with SAMPLESUFFIX="" to force files in their final position # (which will overwrite everything else you have there, you have been warned) SAMPLESUFFIX = .sample # run make install with INSTALLCONFIGEXAMPLES=No to not install them at all INSTALLCONFIGEXAMPLES = Yes install-data-hook: lpd.conf $(mkinstalldirs) $(DESTDIR)$(configdir) if [ "$(INSTALLCONFIGEXAMPLES)" = "Yes" ] ; then \ $(INSTALL_DATA) lpd.conf $(DESTDIR)$(LPD_CONF_PATH)$(SAMPLESUFFIX) ;\ fi lprng-3.8.B/src/vars.c0000644000131400013140000007115711531672134011523 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /* force local definitions */ #define EXTERN #define DEFINE(X) X #define DEFS #include "lp.h" #include "child.h" #include "gethostinfo.h" #include "getqueue.h" #include "accounting.h" #include "permission.h" #include "printjob.h" /**** ENDINCLUDE ****/ /*************************************************************************** Commentary: Patrick Powell Tue Nov 26 08:10:12 PST 1996 Put all of the variables in a separate file. ***************************************************************************/ /* * configuration values that are checked and expanded */ #if !defined(GETENV) #define GETENV "0" #endif #if !defined(TARGETARCHITECTURE) #define TARGETARCHITECTURE "unknown" #endif #if !defined(LPD_CONF_PATH) #error Missing LPD_CONF_PATH definition #endif #if !defined(LPD_PERMS_PATH) #error Missing LPD_PERMS_PATH definition #endif #if !defined(PRINTCAP_PATH) #error Missing PRINTCAP_PATH definition #endif #if !defined(LPD_PRINTCAP_PATH) #error Missing LPD_PRINTCAP_PATH definition #endif #if !defined(FORCE_LOCALHOST) #error Missing FORCE_LOCALHOST definition #endif #if !defined(REQUIRE_CONFIGFILES) #error Missing REQUIRE_CONFIGFILES definition #endif #if !defined(FILTER_PATH) #define FILTER_PATH "/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin:/usr/ucb:/usr/sbin:/usr/etc:/etc" #endif #if !defined(FILTER_LD_PATH) #define FILTER_LD_PATH "" #endif #if !defined(LOCKFILE) #error Missing LOCKFILE definition #endif #if !defined(USERID) #error Missing USERID definition #endif #if !defined(GROUPID) #error Missing GROUPID definition #endif #if !defined(DONE_JOBS) #error Missing DONE_JOBS definition #endif #if !defined(DONE_JOBS_MAX_AGE) #error Missing DONE_JOBS_MAX_AGE definition #endif #if !defined(UNIXSOCKETPATH) #error Missing UNIXSOCKETPATH definition #endif #if !defined(PRUTIL) #error Missing PRUTIL definition #endif #if !defined(SD_DEFAULT) #error Missing SD_DEFAULT definition #endif #if defined(WITHPLUGINS) && !defined(PLUGINDIR) #error Missing PLUGINDIR definition #endif /* * printcap variables used by LPD for printing * THESE MUST BE IN SORTED ORDER * NOTE: the maxval field is used to suppress clearing * these values when initializing the printcap variable * values. */ struct keywords Pc_var_list[] = { /* XXSTARTXX */ /* always print banner, ignore lpr -h option */ { "ab", 0, FLAG_K, &Always_banner_DYN,0,0,0}, /* set accounting name in control file based on host name */ { "accounting_namefixup", 0, STRING_K, &Accounting_namefixup_DYN,0,0,0}, /* query accounting server when connected */ { "achk", 0, FLAG_K, &Accounting_check_DYN,0,0,0}, /* accounting at end (see also af, la, ar, as) */ { "ae", 0, STRING_K, &Accounting_end_DYN,0,0,"=jobend $H $n $P $k $b $t $'C $'J $'M"}, /* name of accounting file (see also la, ar) */ { "af", 0, STRING_K, &Accounting_file_DYN,0,0,"=acct"}, /* automatically hold all jobs */ { "ah", 0, FLAG_K, &Auto_hold_DYN,0,0,0}, /* Allow use of LPD_CONF environment variable */ { "allow_getenv", 0, FLAG_K, &Allow_getenv_DYN,1,0,GETENV}, /* allow users to request logging info using lpr -mhost%port */ { "allow_user_logging", 0, FLAG_K, &Allow_user_logging_DYN,0,0,0}, /* allow these users or UIDs to set owner of job. For Samba front ending */ { "allow_user_setting", 0, STRING_K, &Allow_user_setting_DYN,0,0,0}, /* append these -Z options to end of options list on outgoing or filters */ { "append_z", 0, STRING_K, &Append_Z_DYN,0,0,0}, /* write remote transfer accounting (if af is set) */ { "ar", 0, FLAG_K, &Accounting_remote_DYN,0,0,"1"}, /* host architecture */ { "architecture", 0, STRING_K, &Architecture_DYN,1,0,TARGETARCHITECTURE}, /* accounting at start (see also af, la, ar) */ { "as", 0, STRING_K, &Accounting_start_DYN,0,0,"=jobstart $H $n $P $k $b $t $'C $'J $'M"}, /* authentication type for client to server */ { "auth", 0, STRING_K, &Auth_DYN,0,0,0}, /* client to server authentication filter */ { "auth_forward", 0, STRING_K, &Auth_forward_DYN,0,0,0}, /* end banner printing program overides bp */ { "be", 0, STRING_K, &Banner_end_DYN,0,0,0}, /* Berkeley LPD: job file strictly RFC-compliant */ { "bk", 0, FLAG_K, &Backwards_compatible_DYN,0,0,0}, /* Berkeley LPD filter options */ { "bk_filter_options", 0, STRING_K, &BK_filter_options_DYN,0,0,"=$P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a"}, /* Berkeley LPD OF filter options */ { "bk_of_filter_options", 0, STRING_K, &BK_of_filter_options_DYN,0,0,"=$w $l $x $y"}, /* backwards-compatible filters: use simple paramters */ { "bkf", 0, FLAG_K, &Backwards_compatible_filter_DYN,0,0,0}, /* short banner line sent to banner printer */ { "bl", 0, STRING_K, &Banner_line_DYN,0,0,"=$-C:$-n Job: $-J Date: $-t"}, /* banner printing program (see bs, be) */ { "bp", 0, STRING_K, &Banner_printer_DYN,0,0,0}, /* format for bounce queue output */ { "bq_format", 0, STRING_K, &Bounce_queue_format_DYN,0,0,"=f"}, /* if lp is a tty, set the baud rate (see ty) */ { "br", 0, INTEGER_K, &Baud_rate_DYN,0,0,0}, /* do not set priority from class name */ { "break_classname_priority_link", 0, FLAG_K, &Break_classname_priority_link_DYN,0,0,0}, /* banner printing program overrides bp */ { "bs", 0, STRING_K, &Banner_start_DYN,0,0,0}, /* check for nonprintable file */ { "check_for_nonprintable", 0, FLAG_K, &Check_for_nonprintable_DYN,0,0,0}, /* check for RFC1179 protocol violations */ { "check_for_protocol_violations", 0, FLAG_K, &Check_for_protocol_violations_DYN,0,0,0}, /* filter selects the destination for a load balance queue */ { "chooser", 0, STRING_K, &Chooser_DYN,0,0,0}, /* interval between checks for available destination for load balance queue */ { "chooser_interval", 0, INTEGER_K, &Chooser_interval_DYN,0,0,"=10"}, /* user provided routine selects the destination for a load balance queue */ { "chooser_routine", 0, FLAG_K, &Chooser_routine_DYN,0,0,0}, /* chooser filter scans entire queue */ { "chooser_scan_queue", 0, FLAG_K, &Chooser_scan_queue_DYN,0,0,0}, /* show classname in status display */ { "class_in_status", 0, FLAG_K, &Class_in_status_DYN,0,0,0}, /* comment identifying printer (LPQ) */ { "cm", 0, STRING_K, &Comment_tag_DYN,0,0,0}, /* configuration file */ { "config_file", 0, STRING_K, &Config_file_DYN,1,0,"=" LPD_CONF_PATH}, /* minimum interval between connections and jobs */ { "connect_grace", 0, INTEGER_K, &Connect_grace_DYN,0,0,"=0"}, /* interval between connection or open attempts */ { "connect_interval", 0, INTEGER_K, &Connect_interval_DYN,0,0,"=10"}, /* connection timeout for remote printers */ { "connect_timeout", 0, INTEGER_K, &Connect_timeout_DYN,0,0,"=10"}, /* control file line order */ { "control_file_line_order", 0, STRING_K, &Control_file_line_order_DYN,0,0,0}, /* control file filter */ { "control_filter", 0, STRING_K, &Control_filter_DYN,0,0,0}, /* create files in spool directory */ { "create_files", 0, FLAG_K, &Create_files_DYN,0,0,0}, /* debug level set for queue handler */ { "db", 0, STRING_K, &New_debug_DYN,0,0,0}, /* default job format */ { "default_format", 0, STRING_K, &Default_format_DYN,0,0,"=f"}, /* default permission for files */ { "default_permission", 0, STRING_K, &Default_permission_DYN,0,0,"=ACCEPT"}, /* default printer */ { "default_printer", 0, STRING_K, &Default_printer_DYN,0,0,"=missingprinter"}, /* default job priority */ { "default_priority", 0, STRING_K, &Default_priority_DYN,0,0,"=A"}, /* default remote host */ { "default_remote_host", 0, STRING_K, &Default_remote_host_DYN,0,0,"=localhost"}, /* default temp directory for temp files */ { "default_tmp_dir", 0, STRING_K, &Default_tmp_dir_DYN,0,0,"=/tmp"}, /* printers that we should query for status information */ { "destinations", 0, STRING_K, &Destinations_DYN,0,0,0}, /* allow LPR to make direct socket connection to printer */ { "direct", 0, FLAG_K, &Direct_DYN,0,0,0}, /* discard jobs that exceed max job size */ { "discard_large_jobs", 0, FLAG_K, &Discard_large_jobs_DYN,0,0,"=1"}, /* keep the last NN done jobs for status purposes */ { "discard_zero_length_jobs", 0, FLAG_K, &Discard_zero_length_jobs_DYN,0,0,"=0"}, /* do not print zero length jobs */ { "done_jobs", 0, INTEGER_K, &Done_jobs_DYN,0,0,"=" DONE_JOBS}, /* keep done jobs for at most max age seconds */ { "done_jobs_max_age", 0, INTEGER_K, &Done_jobs_max_age_DYN,0,0,"=" DONE_JOBS_MAX_AGE}, /* drop root permissions after binding to listening port */ { "drop_root", 0, FLAG_K, &Drop_root_DYN,0,0,0}, /* exit linger timeout to wait for socket to close */ { "exit_linger_timeout", 0, INTEGER_K, &Exit_linger_timeout_DYN,0,0,"=600"}, /* use this size (in Kbytes) when sending 'unknown' size files to a spooler */ { "fakelargefile", 0, INTEGER_K, &Fake_large_file_DYN,0,0,0}, /* string to send for a form feed */ { "ff", 0, STRING_K, &Form_feed_DYN,0,0,"=\\f"}, /* send a form feed (value set by ff) between files of a job */ { "ff_separator", 0, FLAG_K, &FF_separator_DYN,0,0,0}, /* enforce FIFO (first in, first out) sequential job printing order */ { "fifo", 0, FLAG_K, &Fifo_DYN,0,0,"=1"}, /* FIFO lock file */ { "fifo_lock_file", 0, STRING_K, &Fifo_lock_file_DYN,0,0,"=fifo.lock"}, /* default filter */ { "filter", 0, STRING_K, &Filter_DYN,0,0,0}, /* filter LD_LIBRARY_PATH value */ { "filter_ld_path", 0, STRING_K, &Filter_ld_path_DYN,0,0,"=" FILTER_LD_PATH }, /* filter options */ { "filter_options", 0, STRING_K, &Filter_options_DYN,0,0,"=$A $B $C $D $E $F $G $H $I $J $K $L $M $N $O $P $Q $R $S $T $U $V $W $X $Y $Z $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z $-a"}, /* filter PATH environment variable */ { "filter_path", 0, STRING_K, &Filter_path_DYN,0,0,"=" FILTER_PATH }, /* interval at which to check OF filter for error status */ { "filter_poll_interval", 0, INTEGER_K, &Filter_poll_interval_DYN,0,0,"=30"}, /* write filter errors to the :ps=status file if there is one */ { "filter_stderr_to_status_file", 0, FLAG_K, &Filter_stderr_to_status_file_DYN,0,0,0}, /* print a form feed when device is opened */ { "fo", 0, FLAG_K, &FF_on_open_DYN,0,0,0}, /* force FQDN HOST value in control file */ { "force_fqdn_hostname", 0, FLAG_K, &Force_FQDN_hostname_DYN,0,0,0}, /* force IPADDR of Originating host for host value in control file */ { "force_ipaddr_hostname", 0, FLAG_K, &Force_IPADDR_hostname_DYN,0,0,0}, /* force clients to send all requests to localhost */ { "force_localhost", 0, FLAG_K, &Force_localhost_DYN,0,0,FORCE_LOCALHOST}, /* force lpq status format for specified hostnames */ { "force_lpq_status", 0, STRING_K, &Force_lpq_status_DYN,0,0,0}, /* force use of this queuename if none provided */ { "force_queuename", 0, STRING_K, &Force_queuename_DYN,0,0,0}, /* print a form feed when device is closed */ { "fq", 0, FLAG_K, &FF_on_close_DYN,0,0,0}, /* full or complete time format */ { "full_time", 0, FLAG_K, &Full_time_DYN,0,0,0}, /* valid output filter formats */ { "fx", 0, STRING_K, &Formats_allowed_DYN,0,0,0}, /* generate a banner when forwarding job */ { "generate_banner", 0, FLAG_K, &Generate_banner_DYN,0,0,0}, /* group to run SUID ROOT programs */ { "group", 0, STRING_K, &Daemon_group_DYN,1,0,"=" GROUPID}, /* do a 'half close' on socket when sending job to remote printer */ { "half_close", 0, FLAG_K, &Half_close_DYN,0,0,"=1"}, /* print banner after job instead of before */ { "hl", 0, FLAG_K, &Banner_last_DYN,0,0,0}, /* filter command, run on a per-file basis */ { "if", 0, STRING_K, &IF_Filter_DYN,0,0,0}, /* ignore requested user priority */ { "ignore_requested_user_priority", 0, FLAG_K, &Ignore_requested_user_priority_DYN,0,0,0}, /* incoming job control file filter */ { "incoming_control_filter", 0, STRING_K, &Incoming_control_filter_DYN,0,0,0}, #ifdef IPP_STUBS /* ipp server listen port port, no value or "off" does not open port */ { "ipp_listen_port", 0, STRING_K, &Ipp_listen_port_DYN,0,0,"=off"}, /* ipp destination port */ { "ipp_port", 0, STRING_K, &Ipp_port_DYN,0,0,"=631"}, #endif /* not IPP_STUBS */ /* Running IPV6 */ { "ipv6", 0, FLAG_K, &IPV6Protocol_DYN,0,0,0}, /* TCP keepalive enabled */ { "keepalive", 0, FLAG_K, &Keepalive_DYN,0,0,"1"}, /* remote server principal for server to server forwarding */ { "kerberos_forward_principal", 0, STRING_K, &Kerberos_forward_principal_DYN,0,0,0}, /* keytab file location for kerberos, used by server */ { "kerberos_keytab", 0, STRING_K, &Kerberos_keytab_DYN,0,0,"=/etc/lpd/lpd.keytab"}, /* key lifetime for kerberos, used by server */ { "kerberos_life", 0, STRING_K, &Kerberos_life_DYN,0,0,0}, /* key renewal time for kerberos, used by server */ { "kerberos_renew", 0, STRING_K, &Kerberos_renew_DYN,0,0,0}, /* remote server principle, overides default */ { "kerberos_server_principal", 0, STRING_K, &Kerberos_server_principal_DYN,0,0,0}, /* default service */ { "kerberos_service", 0, STRING_K, &Kerberos_service_DYN,0,0,"=lpr"}, /* write local printer accounting (if af is set) */ { "la", 0, FLAG_K, &Local_accounting_DYN,0,0,"1"}, /* leader string printed on printer open */ { "ld", 0, STRING_K, &Leader_on_open_DYN,0,0,0}, /* error log file (servers, filters and prefilters) */ { "lf", 0, STRING_K, &Log_file_DYN,0,0,"=log"}, /* lock the IO device */ { "lk", 0, FLAG_K, &Lock_it_DYN,0,0,0}, /* lpd lock file */ { "lockfile", 0, STRING_K, &Lockfile_DYN,1,0,"=" LOCKFILE}, /* where to send status information for logging */ { "logger_destination", 0, STRING_K, &Logger_destination_DYN,0,0,0}, /* maximum size in K of logger file */ { "logger_max_size", 0, INTEGER_K, &Logger_max_size_DYN,0,0,0}, /* path of file to hold logger information */ { "logger_path", 0, STRING_K, &Logger_path_DYN,0,0,0}, /* timeout between connection attempts to remote logger */ { "logger_timeout", 0, INTEGER_K, &Logger_timeout_DYN,0,0,0}, /* use long job number (0 - 999999) when a job is submitted */ { "longnumber", 0, FLAG_K, &Long_number_DYN,0,0,0}, /* device name or lp-pipe command to send output to */ { "lp", 0, STRING_K, &Lp_device_DYN,0,0,0}, /* force lpd to filter jobs (bounce) before sending to remote queue */ { "lpd_bounce", 0, FLAG_K, &Lpd_bounce_DYN,0,0,0}, /* force a poll operation */ { "lpd_force_poll", 0, FLAG_K, &Force_poll_DYN,0,0,0}, /* lpd server listen port, "off" does not open remote port, usual port is 515. */ { "lpd_listen_port", 0, STRING_K, &Lpd_listen_port_DYN,0,0,LPD_LISTEN_PORT}, /* lpd pathname for server use */ { "lpd_path", 0, STRING_K, &Lpd_path_DYN,0,0,0}, /* max number of queues to start at a time */ { "lpd_poll_servers_started", 0, INTEGER_K, &Poll_servers_started_DYN,1,0,"=3"}, /* interval in secs between starting small numbers of queue servers */ { "lpd_poll_start_interval", 0, INTEGER_K, &Poll_start_interval_DYN,0,0,"=1"}, /* interval in secs between servicing all queues */ { "lpd_poll_time", 0, INTEGER_K, &Poll_time_DYN,0,0,"=600"}, /* lpd port */ { "lpd_port", 0, STRING_K, &Lpd_port_DYN,0,0,"=515"}, /* lpd printcap path */ { "lpd_printcap_path", 0, STRING_K, &Lpd_printcap_path_DYN,1,0,"=" LPD_PRINTCAP_PATH}, /* maximum number of lpq status queries kept in cache */ { "lpq_status_cached", 0, INTEGER_K, &Lpq_status_cached_DYN,0,0,"=10"}, /* cached lpq status file */ { "lpq_status_file", 0, STRING_K, &Lpq_status_file_DYN,0,0,"=lpq"}, /* minimum interval between updates */ { "lpq_status_interval", 0, INTEGER_K, &Lpq_status_interval_DYN,0,0,"=2"}, /* cached lpq status timeout - refresh after this time */ { "lpq_status_stale", 0, INTEGER_K, &Lpq_status_stale_DYN,0,0,"=3600"}, /* Additional options for LPR */ { "lpr", 0, STRING_K, &Lpr_opts_DYN,0,0,0}, /* lpr will run job through filters and send single file */ { "lpr_bounce", 0, FLAG_K, &Lpr_bounce_DYN,0,0,0}, /* BSD LPR -m flag, does not require mail address */ { "lpr_bsd", 0, FLAG_K, &LPR_bsd_DYN,0,0,0}, /* numbers of times for lpr to try sending job - 0 is infinite */ { "lpr_send_try", 0, INTEGER_K, &Lpr_send_try_DYN,0,0,"=3"}, /* from address to use in mail messages */ { "mail_from", 0, STRING_K, &Mail_from_DYN,0,0,0}, /* mail to this operator on error */ { "mail_operator_on_error", 0, STRING_K, &Mail_operator_on_error_DYN,0,0,0}, /* maximum accounting file size in Kbytes; 0 means no limit on size */ { "max_accounting_file_size", 0, INTEGER_K, &Max_accounting_file_size_DYN,0,0,"=0"}, /* maximum interval between connection attempts */ { "max_connect_interval", 0, INTEGER_K, &Max_connect_interval_DYN,0,0,"=60"}, /* maximum number of datafiles */ { "max_datafiles", 0, INTEGER_K, &Max_datafiles_DYN,0,0,"=52"}, /* maximum log file size in Kbytes; 0 means no limit on size */ { "max_log_file_size", 0, INTEGER_K, &Max_log_file_size_DYN,0,0,"=1000"}, /* maximum number of moves or forwards for a job; 0 means no limit */ { "max_move_count", 0, INTEGER_K, &Max_move_count_DYN,0,0,"=10"}, /* maximum number of servers that can be active */ { "max_servers_active", 0, INTEGER_K, &Max_servers_active_DYN,1,0,"=1024"}, /* maximum length of status line */ { "max_status_line", 0, INTEGER_K, &Max_status_line_DYN,0,0,"=79"}, /* maximum size (in K) of status file; 0 means no limit on size */ { "max_status_size", 0, INTEGER_K, &Max_status_size_DYN,0,0,"=10"}, /* maximum copies allowed */ { "mc", 0, INTEGER_K, &Max_copies_DYN,0,0,"=1"}, /* minimum accounting file size in Kbytes */ { "min_accounting_file_size", 0, INTEGER_K, &Min_accounting_file_size_DYN,0,0,0}, /* minimum log file size in Kbytes */ { "min_log_file_size", 0, INTEGER_K, &Min_log_file_size_DYN,0,0,0}, /* minimum status file size in Kbytes */ { "min_status_size", 0, INTEGER_K, &Min_status_size_DYN,0,0,0}, /* minimum amount of free space needed in K bytes */ { "minfree", 0, INTEGER_K, &Minfree_DYN,0,0,0}, /* minimum number of printable characters for printable check */ { "ml", 0, INTEGER_K, &Min_printable_count_DYN,0,0,0}, /* millisecond time resolution */ { "ms_time_resolution", 0, FLAG_K, &Ms_time_resolution_DYN,0,0,"=1"}, /* maximum job size (1Kb blocks, 0 = unlimited) */ { "mx", 0, INTEGER_K, &Max_job_size_DYN,0,0,0}, /* use nonblocking open */ { "nb", 0, FLAG_K, &Nonblocking_open_DYN,0,0,0}, /* connection control for remote network printers */ { "network_connect_grace", 0, INTEGER_K, &Network_connect_grace_DYN,0,0,0}, /* N line after cfA000... line in control file */ { "nline_after_file", 0, FLAG_K, &Nline_after_file_DYN,0,0,0}, /* output filter, run once for all output */ { "of", 0, STRING_K, &OF_Filter_DYN,0,0,0}, /* OF filter options */ { "of_filter_options", 0, STRING_K, &OF_filter_options_DYN,0,0,0}, /* use user supplied queue order routine */ { "order_routine", 0, FLAG_K, &Order_routine_DYN,0,0,0}, /* orginate connections from these ports */ { "originate_port", 0, STRING_K, &Originate_port_DYN,0,0,"=512 1023"}, /* pass these environment variables to filters (clients and lpd)*/ { "pass_env", 0, STRING_K, &Pass_env_DYN,0,0,"=LANG,LC_CTYPE,LC_NUMERIC,LC_TIME,LC_COLLATE,LC_MONETARY,LC_MESSAGES,LC_PAPER,LC_NAME,LC_ADDRESS,LC_TELEPHONE,LC_MEASUREMENT,LC_IDENTIFICATION,LC_ALL" }, /* make sure these printcap entries are in PRINTCAP_ENTRY filter environment variable */ { "pc_entries_required", 0, STRING_K, &Pc_entries_required_DYN,0,0,"=ppd" }, /* lpd.perms file */ { "perms_path", 0, STRING_K, &Printer_perms_path_DYN,1,0,"=" LPD_PERMS_PATH }, /* page length (in lines) */ { "pl", 0, INTEGER_K, &Page_length_DYN,0,0,"=66"}, #ifdef WITHPLUGINS /* directory where authentication plugins reside */ { "pluginpath", 0, STRING_K, &Plugin_path_DYN,0,0,"=" PLUGINDIR}, #endif /* ppd files */ { "ppd", 0, STRING_K, &Ppd_file_DYN,0,0,0 }, /* pr program for p format */ { "pr", 0, STRING_K, &Pr_program_DYN,0,0,PRUTIL}, /* prefix control file line to line, "Z O" -> Z to O, "OS Z" does O and S to Z */ { "prefix_option_to_option", 0, STRING_K, &Prefix_option_to_option_DYN,0,0,0}, /* prefix these -Z options to start of options list on outgoing or filters */ { "prefix_z", 0, STRING_K, &Prefix_Z_DYN,0,0,0}, /* /etc/printcap files */ { "printcap_path", 0, STRING_K, &Printcap_path_DYN,1,0,"=" PRINTCAP_PATH}, /* printer status file name */ { "ps", 0, STRING_K, &Status_file_DYN,0,0,"=status"}, /* page width (in characters) */ { "pw", 0, INTEGER_K, &Page_width_DYN,0,0,"=80"}, /* page width in pixels (horizontal) */ { "px", 0, INTEGER_K, &Page_x_DYN,0,0,0}, /* page length in pixels (vertical) */ { "py", 0, INTEGER_K, &Page_y_DYN,0,0,0}, /* put queue name in control file */ { "qq", 0, FLAG_K, &Use_queuename_DYN,0,0,"=1"}, /* print queue control file name */ { "queue_control_file", 0, STRING_K, &Queue_control_file_DYN,0,0,"=control.pr"}, /* print queue lock file name */ { "queue_lock_file", 0, STRING_K, &Queue_lock_file_DYN,0,0,"=lock.pr"}, /* print queue status file name */ { "queue_status_file", 0, STRING_K, &Queue_status_file_DYN,0,0,"=status.pr"}, /* print queue unspooler pid file name */ { "queue_unspooler_file", 0, STRING_K, &Queue_unspooler_file_DYN,0,0,"=unspooler.pr"}, /* operations allowed to remote host (lpr=R,lprm=M,lpq=Q,lpq -v=V,lpc=C) */ { "remote_support", 0, STRING_K, &Remote_support_DYN,0,0,"=RMQVC"}, /* remove these -Z options from options list on outgoing or filters */ { "remove_z", 0, STRING_K, &Remove_Z_DYN,0,0,0}, /* report server as this value for LPQ status */ { "report_server_as", 0, STRING_K, &Report_server_as_DYN,0,0,0}, /* client requires lpd.conf, printcap */ { "require_configfiles", 0, FLAG_K, &Require_configfiles_DYN,0,0,"=" REQUIRE_CONFIGFILES}, /* require default queue to be explicitly set */ { "require_explicit_q", 0, FLAG_K, &Require_explicit_Q_DYN,0,0,"0"}, /* retry on ECONNREFUSED error */ { "retry_econnrefused", 0, FLAG_K, &Retry_ECONNREFUSED_DYN,0,0,"1"}, /* retry making connection even when link is down */ { "retry_nolink", 0, FLAG_K, &Retry_NOLINK_DYN,0,0,"1"}, /* return short status when specified remotehost */ { "return_short_status", 0, STRING_K, &Return_short_status_DYN,0,0,0}, /* set SO_REUSEADDR on outgoing ports */ { "reuse_addr", 0, FLAG_K, &Reuse_addr_DYN,0,0,0}, /* reverse LPQ status format when specified remotehost */ { "reverse_lpq_status", 0, STRING_K, &Reverse_lpq_status_DYN,0,0,0}, /* reverse priority order, z-aZ-A, i.e.- A is highest, z is lowest */ { "reverse_priority_order", 0, FLAG_K, &Reverse_priority_order_DYN,0,0,0}, /* restrict queue use to members of specified user groups */ { "rg", 0, STRING_K, &RestrictToGroupMembers_DYN,0,0,0}, /* remote-queue machine (hostname) (with rp) */ { "rm", 0, STRING_K, &RemoteHost_DYN,0,0,0}, /* routing filter, returns destinations */ { "router", 0, STRING_K, &Routing_filter_DYN,0,0,0}, /* remote-queue printer name (with rp) */ { "rp", 0, STRING_K, &RemotePrinter_DYN,0,0,0}, /* open the printer for reading and writing */ { "rw", 0, FLAG_K, &Read_write_DYN,0,0,0}, /* additional safe characters to use in control files */ { "safe_chars", 0, STRING_K, &Safe_chars_DYN,0,0,0}, /* save job when an error */ { "save_on_error", 0, FLAG_K, &Save_on_error_DYN,0,0,0}, /* save job when done */ { "save_when_done", 0, FLAG_K, &Save_when_done_DYN,0,0,0}, /* short banner (one line only) */ { "sb", 0, FLAG_K, &Short_banner_DYN,0,0,0}, /* spool directory (only ONE printer per directory!) */ { "sd", 0, STRING_K, &Spool_dir_DYN,0,0,SD_DEFAULT "/%P"}, /* send block of data, rather than individual files */ { "send_block_format", 0, FLAG_K, &Send_block_format_DYN,0,0,0}, /* send data files first, then control file */ { "send_data_first", 0, FLAG_K, &Send_data_first_DYN,0,0,0}, /* failure action for server to take after send_try attempts failed */ { "send_failure_action", 0, STRING_K, &Send_failure_action_DYN,0,0,"=remove"}, /* timeout for status or job file completion by filter or printer (default 0 - never time out) */ { "send_job_rw_timeout", 0, INTEGER_K, &Send_job_rw_timeout_DYN,0,0,"=0"}, /* timeout for read/write status or control operatons */ { "send_query_rw_timeout", 0, INTEGER_K, &Send_query_rw_timeout_DYN,0,0,"=30"}, /* numbers of times for server to try sending job - 0 is infinite */ { "send_try", 0, INTEGER_K, &Send_try_DYN,0,0,"=3"}, /* sendmail program */ { "sendmail", 0, STRING_K, &Sendmail_DYN,0,0,"=/usr/sbin/sendmail -oi -t"}, /* allow mail to user using the sendmail program */ { "sendmail_to_user", 0, FLAG_K, &Sendmail_to_user_DYN,0,0,"=1"}, /* server temporary file directory */ { "server_tmp_dir", 0, STRING_K, &Server_tmp_dir_DYN,0,0,"=/tmp"}, /* no form feed separator between job files */ { "sf", 0, FLAG_K, &No_FF_separator_DYN,0,0,"=1"}, /* suppress headers and/or banner page */ { "sh", 0, FLAG_K, &Suppress_header_DYN,0,0,0}, /* SHELL enviornment variable value for filters */ { "shell", 0, STRING_K, &Shell_DYN,0,0,"=/bin/sh"}, /* short status length in lines */ { "short_status_length", 0, INTEGER_K, &Short_status_length_DYN,0,0,"=3"}, /* set the SO_LINGER socket option */ { "socket_linger", 0, INTEGER_K, &Socket_linger_DYN,0,0,"=10"}, /* spool directory permissions */ { "spool_dir_perms", 0, INTEGER_K, &Spool_dir_perms_DYN,0,0,"=000700"}, /* spool file permissions */ { "spool_file_perms", 0, INTEGER_K, &Spool_file_perms_DYN,0,0,"=000600"}, /* name of queue that server serves (with sv) */ { "ss", 0, STRING_K, &Server_queue_name_DYN,0,0,0}, /* ssl signer cert file directory */ { "ssl_ca_file", 0, STRING_K, &Ssl_ca_file_DYN,0,0,"=" SSL_CA_FILE }, /* ssl signer cert files (concatenated) */ { "ssl_ca_path", 0, STRING_K, &Ssl_ca_path_DYN,0,0,0 }, /* ssl crl file (certificate revocation list) */ { "ssl_crl_file", 0, STRING_K, &Ssl_crl_file_DYN,0,0,"=" SSL_CRL_FILE }, /* ssl crl directory (certificate revocation list) */ { "ssl_crl_path", 0, STRING_K, &Ssl_crl_path_DYN,0,0,0 }, /* ssl server certificate */ { "ssl_server_cert", 0, STRING_K, &Ssl_server_cert_DYN,0,0,"=" SSL_SERVER_CERT }, /* ssl server cert password is in this file */ { "ssl_server_password_file", 0, STRING_K, &Ssl_server_password_file_DYN,0,0,"=" SSL_SERVER_PASSWORD_FILE }, /* stalled job timeout */ { "stalled_time", 0, INTEGER_K, &Stalled_time_DYN,0,0,"=120"}, /* stop processing queue on filter abort */ { "stop_on_abort", 0, FLAG_K, &Stop_on_abort_DYN,0,0,0}, /* stty commands to set output line characteristics */ { "stty", 0, STRING_K, &Stty_command_DYN,0,0,0}, /* suspend the OF filter or rerun it */ { "suspend_of_filter", 0, FLAG_K, &Suspend_OF_filter_DYN,0,0,"=1"}, /* names of servers for queue (with ss) */ { "sv", 0, STRING_K, &Server_names_DYN,0,0,0}, /* name of syslog device */ { "syslog_device", 0, STRING_K, &Syslog_device_DYN,0,0,"=/dev/console"}, /* trailer string to print when queue empties */ { "tr", 0, STRING_K, &Trailer_on_close_DYN,0,0,0}, /* translate outgoing job file formats - similar to tr(1) utility */ { "translate_format", 0, STRING_K, &Xlate_format_DYN,0,0,0}, /* translate incoming job file formats - similar to tr(1) utility */ { "translate_incoming_format", 0, STRING_K, &Xlate_incoming_format_DYN,0,0,0}, /* path for UNIX socket for localhost connections */ { "unix_socket_path", 0, STRING_K, &Unix_socket_path_DYN,0,0,"=" UNIXSOCKETPATH}, /* read and cache information */ { "use_info_cache", 0, FLAG_K, &Use_info_cache_DYN,0,0,"1"}, /* put queue name in control file */ { "use_shorthost", 0, FLAG_K, &Use_shorthost_DYN,0,0,0}, /* server user for SUID purposes */ { "user", 0, STRING_K, &Daemon_user_DYN,1,0,"=" USERID}, /* set user to be authenication user identification */ { "user_is_authuser", 0, FLAG_K, &User_is_authuser_DYN,0,0,0}, /* allow users to use local ${HOME}/.printcap */ { "user_printcap", 0, STRING_K, &User_printcap_DYN,1,0,".printcap"}, /* END */ { (char *)0,0,0,0,0,0,0 } } ; struct keywords DYN_var_list[] = { { "Logname_DYN", 0, STRING_K, &Logname_DYN,0,0,0}, { "ShortHost_FQDN", 0, STRING_K, &ShortHost_FQDN,0,0,0}, { "FQDNHost_FQDN", 0, STRING_K, &FQDNHost_FQDN,0,0,0}, { "Printer_DYN", 0, STRING_K, &Printer_DYN ,0,0,0}, { "Queue_name_DYN", 0, STRING_K, &Queue_name_DYN ,0,0,0}, { "Lp_device_DYN", 0, STRING_K, &Lp_device_DYN ,0,0,0}, { "RemotePrinter_DYN", 0, STRING_K, &RemotePrinter_DYN ,0,0,0}, { "RemoteHost_DYN", 0, STRING_K, &RemoteHost_DYN ,0,0,0}, { "FQDNRemote_FQDN", 0, STRING_K, &FQDNRemote_FQDN ,0,0,0}, { "ShortRemote_FQDN", 0, STRING_K, &ShortRemote_FQDN ,0,0,0}, { "Current_date_DYN", 0, STRING_K, &Current_date_DYN ,0,0,0}, { (char *)0,0,0,0,0,0,0 } } ; lprng-3.8.B/src/Makefile.in0000644000131400013140000041536311531672273012456 00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : lpdbin_PROGRAMS = lpd$(EXEEXT) bin_PROGRAMS = lpr$(EXEEXT) lpq$(EXEEXT) lprm$(EXEEXT) lpstat$(EXEEXT) sbin_PROGRAMS = lpc$(EXEEXT) checkpc$(EXEEXT) filter_PROGRAMS = lpf$(EXEEXT) lpbanner$(EXEEXT) noinst_PROGRAMS = monitor$(EXEEXT) @WITHPLUGINS_TRUE@plugin_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) \ @WITHPLUGINS_TRUE@ md5.so$(EXEEXT) test.so$(EXEEXT) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@am__append_1 = kerberos5.so @WITHPLUGINS_TRUE@@WITHSSL_TRUE@am__append_2 = ssl.so @WITHPLUGINS_FALSE@am__append_3 = common/md5.c auth/md5_auth.c auth/test_auth.c \ @WITHPLUGINS_FALSE@ auth/ssl_auth.c auth/krb5_auth.c subdir = src DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/pclbanner.in \ $(srcdir)/psbanner.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = pclbanner psbanner am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(filterdir)" \ "$(DESTDIR)$(lpdbindir)" "$(DESTDIR)$(plugindir)" \ "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(filterdir)" \ "$(DESTDIR)$(sbindir)" binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) filterPROGRAMS_INSTALL = $(INSTALL_PROGRAM) lpdbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@am__EXEEXT_1 = \ @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ kerberos5.so$(EXEEXT) @WITHPLUGINS_TRUE@@WITHSSL_TRUE@am__EXEEXT_2 = ssl.so$(EXEEXT) pluginPROGRAMS_INSTALL = $(INSTALL_PROGRAM) sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) PROGRAMS = $(bin_PROGRAMS) $(filter_PROGRAMS) $(lpdbin_PROGRAMS) \ $(noinst_PROGRAMS) $(plugin_PROGRAMS) $(sbin_PROGRAMS) am__objects_1 = child.$(OBJEXT) copyright.$(OBJEXT) debug.$(OBJEXT) \ errormsg.$(OBJEXT) fileopen.$(OBJEXT) gethostinfo.$(OBJEXT) \ getopt.$(OBJEXT) getprinter.$(OBJEXT) getqueue.$(OBJEXT) \ globmatch.$(OBJEXT) initialize.$(OBJEXT) linelist.$(OBJEXT) \ linksupport.$(OBJEXT) lockfile.$(OBJEXT) merge.$(OBJEXT) \ plp_snprintf.$(OBJEXT) proctitle.$(OBJEXT) utilities.$(OBJEXT) \ vars.$(OBJEXT) am_checkpc_OBJECTS = checkpc.$(OBJEXT) stty.$(OBJEXT) $(am__objects_1) checkpc_OBJECTS = $(am_checkpc_OBJECTS) checkpc_LDADD = $(LDADD) am__kerberos5_so_SOURCES_DIST = auth/krb5_auth.c @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@am_kerberos5_so_OBJECTS = \ @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ krb5_auth.$(OBJEXT) kerberos5_so_OBJECTS = $(am_kerberos5_so_OBJECTS) am__DEPENDENCIES_1 = @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@kerberos5_so_DEPENDENCIES = \ @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ $(am__DEPENDENCIES_1) kerberos5_so_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(kerberos5_so_LDFLAGS) $(LDFLAGS) -o $@ am_lpbanner_OBJECTS = lpbanner.$(OBJEXT) plp_snprintf.$(OBJEXT) lpbanner_OBJECTS = $(am_lpbanner_OBJECTS) lpbanner_LDADD = $(LDADD) am__lpc_SOURCES_DIST = common/lpc.c common/controlword.c \ common/child.c common/copyright.c common/debug.c \ common/errormsg.c common/fileopen.c common/gethostinfo.c \ common/getopt.c common/getprinter.c common/getqueue.c \ common/globmatch.c common/initialize.c common/linelist.c \ common/linksupport.c common/lockfile.c common/merge.c \ common/plp_snprintf.c common/proctitle.c common/utilities.c \ vars.c common/sendauth.c common/sendjob.c common/sendreq.c \ common/user_auth.c common/printjob.c common/md5.c \ auth/md5_auth.c auth/test_auth.c auth/ssl_auth.c \ auth/krb5_auth.c @WITHPLUGINS_FALSE@am__objects_2 = md5.$(OBJEXT) md5_auth.$(OBJEXT) \ @WITHPLUGINS_FALSE@ test_auth.$(OBJEXT) ssl_auth.$(OBJEXT) \ @WITHPLUGINS_FALSE@ krb5_auth.$(OBJEXT) am__objects_3 = $(am__objects_1) sendauth.$(OBJEXT) sendjob.$(OBJEXT) \ sendreq.$(OBJEXT) user_auth.$(OBJEXT) printjob.$(OBJEXT) \ $(am__objects_2) am_lpc_OBJECTS = lpc.$(OBJEXT) controlword.$(OBJEXT) $(am__objects_3) lpc_OBJECTS = $(am_lpc_OBJECTS) @WITHPLUGINS_FALSE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) \ @WITHPLUGINS_FALSE@ $(am__DEPENDENCIES_1) @WITHPLUGINS_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) lpc_DEPENDENCIES = $(am__DEPENDENCIES_2) lpc_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lpc_LDFLAGS) $(LDFLAGS) -o \ $@ am__lpd_SOURCES_DIST = common/lpd.c common/lpd_worker.c \ common/lpd_jobs.c common/lpd_control.c common/sendmail.c \ common/lpd_dispatch.c common/lpd_logger.c common/lpd_rcvjob.c \ common/lpd_remove.c common/lpd_secure.c common/lpd_status.c \ common/permission.c common/accounting.c common/controlword.c \ common/child.c common/copyright.c common/debug.c \ common/errormsg.c common/fileopen.c common/gethostinfo.c \ common/getopt.c common/getprinter.c common/getqueue.c \ common/globmatch.c common/initialize.c common/linelist.c \ common/linksupport.c common/lockfile.c common/merge.c \ common/plp_snprintf.c common/proctitle.c common/utilities.c \ vars.c common/sendauth.c common/sendjob.c common/sendreq.c \ common/user_auth.c common/printjob.c common/md5.c \ auth/md5_auth.c auth/test_auth.c auth/ssl_auth.c \ auth/krb5_auth.c common/openprinter.c common/stty.c am__objects_4 = $(am__objects_3) openprinter.$(OBJEXT) stty.$(OBJEXT) am_lpd_OBJECTS = lpd.$(OBJEXT) lpd_worker.$(OBJEXT) lpd_jobs.$(OBJEXT) \ lpd_control.$(OBJEXT) sendmail.$(OBJEXT) \ lpd_dispatch.$(OBJEXT) lpd_logger.$(OBJEXT) \ lpd_rcvjob.$(OBJEXT) lpd_remove.$(OBJEXT) lpd_secure.$(OBJEXT) \ lpd_status.$(OBJEXT) permission.$(OBJEXT) accounting.$(OBJEXT) \ controlword.$(OBJEXT) $(am__objects_4) lpd_OBJECTS = $(am_lpd_OBJECTS) lpd_DEPENDENCIES = $(am__DEPENDENCIES_2) lpd_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lpd_LDFLAGS) $(LDFLAGS) -o \ $@ am_lpf_OBJECTS = lpf.$(OBJEXT) plp_snprintf.$(OBJEXT) lpf_OBJECTS = $(am_lpf_OBJECTS) lpf_LDADD = $(LDADD) am__lpq_SOURCES_DIST = common/lpq.c common/child.c common/copyright.c \ common/debug.c common/errormsg.c common/fileopen.c \ common/gethostinfo.c common/getopt.c common/getprinter.c \ common/getqueue.c common/globmatch.c common/initialize.c \ common/linelist.c common/linksupport.c common/lockfile.c \ common/merge.c common/plp_snprintf.c common/proctitle.c \ common/utilities.c vars.c common/sendauth.c common/sendjob.c \ common/sendreq.c common/user_auth.c common/printjob.c \ common/md5.c auth/md5_auth.c auth/test_auth.c auth/ssl_auth.c \ auth/krb5_auth.c am_lpq_OBJECTS = lpq.$(OBJEXT) $(am__objects_3) lpq_OBJECTS = $(am_lpq_OBJECTS) lpq_DEPENDENCIES = $(am__DEPENDENCIES_2) lpq_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lpq_LDFLAGS) $(LDFLAGS) -o \ $@ am__lpr_SOURCES_DIST = common/lpr.c common/child.c common/copyright.c \ common/debug.c common/errormsg.c common/fileopen.c \ common/gethostinfo.c common/getopt.c common/getprinter.c \ common/getqueue.c common/globmatch.c common/initialize.c \ common/linelist.c common/linksupport.c common/lockfile.c \ common/merge.c common/plp_snprintf.c common/proctitle.c \ common/utilities.c vars.c common/sendauth.c common/sendjob.c \ common/sendreq.c common/user_auth.c common/printjob.c \ common/md5.c auth/md5_auth.c auth/test_auth.c auth/ssl_auth.c \ auth/krb5_auth.c common/openprinter.c common/stty.c am_lpr_OBJECTS = lpr.$(OBJEXT) $(am__objects_4) lpr_OBJECTS = $(am_lpr_OBJECTS) lpr_DEPENDENCIES = $(am__DEPENDENCIES_2) lpr_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lpr_LDFLAGS) $(LDFLAGS) -o \ $@ am__lprm_SOURCES_DIST = common/lprm.c common/child.c \ common/copyright.c common/debug.c common/errormsg.c \ common/fileopen.c common/gethostinfo.c common/getopt.c \ common/getprinter.c common/getqueue.c common/globmatch.c \ common/initialize.c common/linelist.c common/linksupport.c \ common/lockfile.c common/merge.c common/plp_snprintf.c \ common/proctitle.c common/utilities.c vars.c common/sendauth.c \ common/sendjob.c common/sendreq.c common/user_auth.c \ common/printjob.c common/md5.c auth/md5_auth.c \ auth/test_auth.c auth/ssl_auth.c auth/krb5_auth.c am_lprm_OBJECTS = lprm.$(OBJEXT) $(am__objects_3) lprm_OBJECTS = $(am_lprm_OBJECTS) lprm_DEPENDENCIES = $(am__DEPENDENCIES_2) lprm_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lprm_LDFLAGS) $(LDFLAGS) \ -o $@ am__lpstat_SOURCES_DIST = common/lpstat.c common/child.c \ common/copyright.c common/debug.c common/errormsg.c \ common/fileopen.c common/gethostinfo.c common/getopt.c \ common/getprinter.c common/getqueue.c common/globmatch.c \ common/initialize.c common/linelist.c common/linksupport.c \ common/lockfile.c common/merge.c common/plp_snprintf.c \ common/proctitle.c common/utilities.c vars.c common/sendauth.c \ common/sendjob.c common/sendreq.c common/user_auth.c \ common/printjob.c common/md5.c auth/md5_auth.c \ auth/test_auth.c auth/ssl_auth.c auth/krb5_auth.c am_lpstat_OBJECTS = lpstat.$(OBJEXT) $(am__objects_3) lpstat_OBJECTS = $(am_lpstat_OBJECTS) lpstat_DEPENDENCIES = $(am__DEPENDENCIES_2) lpstat_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(lpstat_LDFLAGS) \ $(LDFLAGS) -o $@ am__md5_so_SOURCES_DIST = auth/md5_auth.c common/md5.c @WITHPLUGINS_TRUE@am_md5_so_OBJECTS = md5_so-md5_auth.$(OBJEXT) \ @WITHPLUGINS_TRUE@ md5_so-md5.$(OBJEXT) md5_so_OBJECTS = $(am_md5_so_OBJECTS) md5_so_LDADD = $(LDADD) md5_so_LINK = $(CCLD) $(md5_so_CFLAGS) $(CFLAGS) $(md5_so_LDFLAGS) \ $(LDFLAGS) -o $@ am_monitor_OBJECTS = monitor.$(OBJEXT) $(am__objects_1) monitor_OBJECTS = $(am_monitor_OBJECTS) monitor_LDADD = $(LDADD) am__ssl_so_SOURCES_DIST = auth/ssl_auth.c @WITHPLUGINS_TRUE@@WITHSSL_TRUE@am_ssl_so_OBJECTS = \ @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ ssl_so-ssl_auth.$(OBJEXT) ssl_so_OBJECTS = $(am_ssl_so_OBJECTS) @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ssl_so_DEPENDENCIES = \ @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ $(am__DEPENDENCIES_1) ssl_so_LINK = $(CCLD) $(ssl_so_CFLAGS) $(CFLAGS) $(ssl_so_LDFLAGS) \ $(LDFLAGS) -o $@ am__test_so_SOURCES_DIST = auth/test_auth.c @WITHPLUGINS_TRUE@am_test_so_OBJECTS = test_so-test_auth.$(OBJEXT) test_so_OBJECTS = $(am_test_so_OBJECTS) test_so_LDADD = $(LDADD) test_so_LINK = $(CCLD) $(test_so_CFLAGS) $(CFLAGS) $(test_so_LDFLAGS) \ $(LDFLAGS) -o $@ filterSCRIPT_INSTALL = $(INSTALL_SCRIPT) sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT) SCRIPTS = $(filter_SCRIPTS) $(sbin_SCRIPTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ SOURCES = $(checkpc_SOURCES) $(kerberos5_so_SOURCES) \ $(lpbanner_SOURCES) $(lpc_SOURCES) $(lpd_SOURCES) \ $(lpf_SOURCES) $(lpq_SOURCES) $(lpr_SOURCES) $(lprm_SOURCES) \ $(lpstat_SOURCES) $(md5_so_SOURCES) $(monitor_SOURCES) \ $(ssl_so_SOURCES) $(test_so_SOURCES) DIST_SOURCES = $(checkpc_SOURCES) $(am__kerberos5_so_SOURCES_DIST) \ $(lpbanner_SOURCES) $(am__lpc_SOURCES_DIST) \ $(am__lpd_SOURCES_DIST) $(lpf_SOURCES) $(am__lpq_SOURCES_DIST) \ $(am__lpr_SOURCES_DIST) $(am__lprm_SOURCES_DIST) \ $(am__lpstat_SOURCES_DIST) $(am__md5_so_SOURCES_DIST) \ $(monitor_SOURCES) $(am__ssl_so_SOURCES_DIST) \ $(am__test_so_SOURCES_DIST) DATA = $(noinst_DATA) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHGRP = @CHGRP@ CHOWN = @CHOWN@ CLEAR = @CLEAR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_LIBS = @DL_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FILTER_LD_PATH = @FILTER_LD_PATH@ FILTER_PATH = @FILTER_PATH@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ INCLUDELPDCONFLOCAL = @INCLUDELPDCONFLOCAL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_MAN = @INSTALL_MAN@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KERBEROS = @KERBEROS@ KRB5CONFIG = @KRB5CONFIG@ KRB_LIBS = @KRB_LIBS@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCKFILE = @LOCKFILE@ LPD_CONF_PATH = @LPD_CONF_PATH@ LPD_LISTEN_PORT = @LPD_LISTEN_PORT@ LPD_PERMS_PATH = @LPD_PERMS_PATH@ LPD_PRINTCAP_PATH = @LPD_PRINTCAP_PATH@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NOREMOTE = @NOREMOTE@ OBJEXT = @OBJEXT@ OPENSSL = @OPENSSL@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PLUGINUSER_LDFLAGS = @PLUGINUSER_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PRINTCAP_PATH = @PRINTCAP_PATH@ PRIV_PORTS = @PRIV_PORTS@ PRUTIL = @PRUTIL@ SD_DEFAULT = @SD_DEFAULT@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSL_CA_FILE = @SSL_CA_FILE@ SSL_CA_KEY = @SSL_CA_KEY@ SSL_CERTS_DIR = @SSL_CERTS_DIR@ SSL_CRL_FILE = @SSL_CRL_FILE@ SSL_LDADD = @SSL_LDADD@ SSL_SERVER_CERT = @SSL_SERVER_CERT@ SSL_SERVER_PASSWORD_FILE = @SSL_SERVER_PASSWORD_FILE@ STRIP = @STRIP@ UNIXSOCKETPATH = @UNIXSOCKETPATH@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ filterdir = @filterdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lpdbindir = @lpdbindir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in CLEANFILES = *.tmp *core ? ?.bak ?.orig lpd.conf log lprng_certs lprng_index_certs DISTCLEANFILES = pclbanner psbanner EXTRA_DIST = pclbanner.in psbanner.in lprng_certs.sh lprng_index_certs.sh common/user_objs.c include/user_objs.h AUTHENTICATE/sserver.c AUTHENTICATE/sclient.c PATHDEFINES = "-DLOCKFILE=\"$(LOCKFILE)\"" \ "-DPRINTCAP_PATH=\"$(PRINTCAP_PATH)\"" \ "-DLPD_PRINTCAP_PATH=\"$(LPD_PRINTCAP_PATH)\"" \ "-DLPD_PERMS_PATH=\"$(LPD_PERMS_PATH)\"" \ "-DLPD_CONF_PATH=\"$(LPD_CONF_PATH)\"" \ "-DUNIXSOCKETPATH=\"$(UNIXSOCKETPATH)\"" \ "-DSSL_CA_FILE=\"$(SSL_CA_FILE)\"" \ "-DSSL_CA_KEY=\"$(SSL_CA_KEY)\"" \ "-DSSL_CRL_FILE=\"$(SSL_CRL_FILE)\"" \ "-DSSL_CERTS_DIR=\"$(SSL_CERTS_DIR)\"" \ "-DSSL_SERVER_CERT=\"$(SSL_SERVER_CERT)\"" \ "-DSSL_SERVER_PASSWORD_FILE=\"$(SSL_SERVER_PASSWORD_FILE)\"" \ "-DSD_DEFAULT=\"$(SD_DEFAULT)\"" \ "-DPLUGINDIR=\"$(plugindir)\"" AM_CPPFLAGS = -I$(srcdir)/include "-DLOCALEDIR=\"$(localedir)\"" sbin_SCRIPTS = lprng_certs lprng_index_certs filter_SCRIPTS = psbanner pclbanner noinst_DATA = lpd.conf # - think about making things suid at install time COMMON_SOURCES = common/child.c common/copyright.c common/debug.c \ common/errormsg.c common/fileopen.c common/gethostinfo.c \ common/getopt.c common/getprinter.c common/getqueue.c \ common/globmatch.c common/initialize.c common/linelist.c \ common/linksupport.c common/lockfile.c common/merge.c \ common/plp_snprintf.c common/proctitle.c common/utilities.c \ vars.c MORE_SOURCES = $(COMMON_SOURCES) common/sendauth.c common/sendjob.c \ common/sendreq.c common/user_auth.c common/printjob.c \ $(am__append_3) SEND_SOURCES = $(MORE_SOURCES) \ common/openprinter.c common/stty.c @WITHPLUGINS_FALSE@MORE_LDADD = $(SSL_LDADD) $(KRB_LIBS) # This is a crude hack, but better than needing libtool... @WITHPLUGINS_TRUE@MORE_LDADD = $(DL_LIBS) @WITHPLUGINS_FALSE@MORELDFLAGS = @WITHPLUGINS_TRUE@MORELDFLAGS = $(PLUGINUSER_LDFLAGS) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@kerberos5_so_SOURCES = auth/krb5_auth.c @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@kerberos5_so_LDFLAGS = $(PLUGIN_LDFLAGS) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@kerberos5_so_LDADD = $(KRB_LIBS) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@kerberor5_so_CFLAGS = $(PLUGIN_CFLAGS) @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ssl_so_SOURCES = auth/ssl_auth.c @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ssl_so_LDFLAGS = $(PLUGIN_LDFLAGS) @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ssl_so_CFLAGS = $(PLUGIN_CFLAGS) @WITHPLUGINS_TRUE@@WITHSSL_TRUE@ssl_so_LDADD = $(SSL_LDADD) @WITHPLUGINS_TRUE@md5_so_SOURCES = auth/md5_auth.c common/md5.c @WITHPLUGINS_TRUE@md5_so_LDFLAGS = $(PLUGIN_LDFLAGS) @WITHPLUGINS_TRUE@md5_so_CFLAGS = $(PLUGIN_CFLAGS) @WITHPLUGINS_TRUE@test_so_SOURCES = auth/test_auth.c @WITHPLUGINS_TRUE@test_so_LDFLAGS = $(PLUGIN_LDFLAGS) @WITHPLUGINS_TRUE@test_so_CFLAGS = $(PLUGIN_CFLAGS) lpd_SOURCES = common/lpd.c common/lpd_worker.c common/lpd_jobs.c \ common/lpd_control.c common/sendmail.c common/lpd_dispatch.c \ common/lpd_logger.c common/lpd_rcvjob.c common/lpd_remove.c \ common/lpd_secure.c common/lpd_status.c \ common/permission.c common/accounting.c common/controlword.c \ $(SEND_SOURCES) lpd_LDADD = $(MORE_LDADD) lpd_LDFLAGS = $(MORELDFLAGS) lpr_SOURCES = common/lpr.c $(SEND_SOURCES) lpr_LDADD = $(MORE_LDADD) lpr_LDFLAGS = $(MORELDFLAGS) lpq_SOURCES = common/lpq.c $(MORE_SOURCES) lpq_LDADD = $(MORE_LDADD) lpq_LDFLAGS = $(MORELDFLAGS) lpstat_SOURCES = common/lpstat.c $(MORE_SOURCES) lpstat_LDADD = $(MORE_LDADD) lpstat_LDFLAGS = $(MORELDFLAGS) lprm_SOURCES = common/lprm.c $(MORE_SOURCES) lprm_LDADD = $(MORE_LDADD) lprm_LDFLAGS = $(MORELDFLAGS) lpc_SOURCES = common/lpc.c common/controlword.c $(MORE_SOURCES) lpc_LDADD = $(MORE_LDADD) lpc_LDFLAGS = $(MORELDFLAGS) checkpc_SOURCES = common/checkpc.c common/stty.c $(COMMON_SOURCES) lpf_SOURCES = common/lpf.c common/plp_snprintf.c lpbanner_SOURCES = common/lpbanner.c common/plp_snprintf.c monitor_SOURCES = common/monitor.c $(COMMON_SOURCES) # sserver_SOURCES = AUTHENTICATE/sserver.c # sclient_SOURCES = AUTHENTICATE/sclient.c noinst_HEADERS = include/accounting.h include/checkpc.h include/child.h include/control.h include/copyright.h include/debug.h include/errorcodes.h include/errormsg.h include/fileopen.h include/gethostinfo.h include/getopt.h include/getprinter.h include/getqueue.h include/globmatch.h include/initialize.h include/krb5_auth.h include/license.h include/linelist.h include/linksupport.h include/lockfile.h include/lpc.h include/lpd_control.h include/lpd_dispatch.h include/lpd.h include/lpd_jobs.h include/lpd_logger.h include/lpd_rcvjob.h include/lpd_remove.h include/lpd_secure.h include/lpd_status.h include/lp.h include/lpq.h include/lpr.h include/lprm.h include/lpstat.h include/md5.h include/merge.h include/permission.h include/plp_snprintf.h include/portable.h include/printjob.h include/proctitle.h include/readstatus.h include/sendauth.h include/sendjob.h include/sendmail.h include/sendreq.h include/ssl_auth.h include/stty.h include/user_auth.h include/utilities.h include/openprinter.h include/lpd_worker.h # run make install with SAMPLESUFFIX="" to force files in their final position # (which will overwrite everything else you have there, you have been warned) SAMPLESUFFIX = .sample # run make install with INSTALLCONFIGEXAMPLES=No to not install them at all INSTALLCONFIGEXAMPLES = Yes all: all-am .SUFFIXES: .SUFFIXES: .c .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign src/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh pclbanner: $(top_builddir)/config.status $(srcdir)/pclbanner.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ psbanner: $(top_builddir)/config.status $(srcdir)/psbanner.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ rm -f "$(DESTDIR)$(bindir)/$$f"; \ done clean-binPROGRAMS: -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) install-filterPROGRAMS: $(filter_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(filterdir)" || $(MKDIR_P) "$(DESTDIR)$(filterdir)" @list='$(filter_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(filterPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(filterdir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(filterPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(filterdir)/$$f" || exit 1; \ else :; fi; \ done uninstall-filterPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(filter_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(filterdir)/$$f'"; \ rm -f "$(DESTDIR)$(filterdir)/$$f"; \ done clean-filterPROGRAMS: -test -z "$(filter_PROGRAMS)" || rm -f $(filter_PROGRAMS) install-lpdbinPROGRAMS: $(lpdbin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(lpdbindir)" || $(MKDIR_P) "$(DESTDIR)$(lpdbindir)" @list='$(lpdbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(lpdbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(lpdbindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(lpdbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(lpdbindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-lpdbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(lpdbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(lpdbindir)/$$f'"; \ rm -f "$(DESTDIR)$(lpdbindir)/$$f"; \ done clean-lpdbinPROGRAMS: -test -z "$(lpdbin_PROGRAMS)" || rm -f $(lpdbin_PROGRAMS) clean-noinstPROGRAMS: -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) install-pluginPROGRAMS: $(plugin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @list='$(plugin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(pluginPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(plugindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(pluginPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(plugindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-pluginPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(plugin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(plugindir)/$$f'"; \ rm -f "$(DESTDIR)$(plugindir)/$$f"; \ done clean-pluginPROGRAMS: -test -z "$(plugin_PROGRAMS)" || rm -f $(plugin_PROGRAMS) install-sbinPROGRAMS: $(sbin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_PROGRAMS)'; for p in $$list; do \ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ if test -f $$p \ ; then \ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ else :; fi; \ done uninstall-sbinPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(sbin_PROGRAMS)'; for p in $$list; do \ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ rm -f "$(DESTDIR)$(sbindir)/$$f"; \ done clean-sbinPROGRAMS: -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS) checkpc$(EXEEXT): $(checkpc_OBJECTS) $(checkpc_DEPENDENCIES) @rm -f checkpc$(EXEEXT) $(LINK) $(checkpc_OBJECTS) $(checkpc_LDADD) $(LIBS) kerberos5.so$(EXEEXT): $(kerberos5_so_OBJECTS) $(kerberos5_so_DEPENDENCIES) @rm -f kerberos5.so$(EXEEXT) $(kerberos5_so_LINK) $(kerberos5_so_OBJECTS) $(kerberos5_so_LDADD) $(LIBS) lpbanner$(EXEEXT): $(lpbanner_OBJECTS) $(lpbanner_DEPENDENCIES) @rm -f lpbanner$(EXEEXT) $(LINK) $(lpbanner_OBJECTS) $(lpbanner_LDADD) $(LIBS) lpc$(EXEEXT): $(lpc_OBJECTS) $(lpc_DEPENDENCIES) @rm -f lpc$(EXEEXT) $(lpc_LINK) $(lpc_OBJECTS) $(lpc_LDADD) $(LIBS) lpd$(EXEEXT): $(lpd_OBJECTS) $(lpd_DEPENDENCIES) @rm -f lpd$(EXEEXT) $(lpd_LINK) $(lpd_OBJECTS) $(lpd_LDADD) $(LIBS) lpf$(EXEEXT): $(lpf_OBJECTS) $(lpf_DEPENDENCIES) @rm -f lpf$(EXEEXT) $(LINK) $(lpf_OBJECTS) $(lpf_LDADD) $(LIBS) lpq$(EXEEXT): $(lpq_OBJECTS) $(lpq_DEPENDENCIES) @rm -f lpq$(EXEEXT) $(lpq_LINK) $(lpq_OBJECTS) $(lpq_LDADD) $(LIBS) lpr$(EXEEXT): $(lpr_OBJECTS) $(lpr_DEPENDENCIES) @rm -f lpr$(EXEEXT) $(lpr_LINK) $(lpr_OBJECTS) $(lpr_LDADD) $(LIBS) lprm$(EXEEXT): $(lprm_OBJECTS) $(lprm_DEPENDENCIES) @rm -f lprm$(EXEEXT) $(lprm_LINK) $(lprm_OBJECTS) $(lprm_LDADD) $(LIBS) lpstat$(EXEEXT): $(lpstat_OBJECTS) $(lpstat_DEPENDENCIES) @rm -f lpstat$(EXEEXT) $(lpstat_LINK) $(lpstat_OBJECTS) $(lpstat_LDADD) $(LIBS) md5.so$(EXEEXT): $(md5_so_OBJECTS) $(md5_so_DEPENDENCIES) @rm -f md5.so$(EXEEXT) $(md5_so_LINK) $(md5_so_OBJECTS) $(md5_so_LDADD) $(LIBS) monitor$(EXEEXT): $(monitor_OBJECTS) $(monitor_DEPENDENCIES) @rm -f monitor$(EXEEXT) $(LINK) $(monitor_OBJECTS) $(monitor_LDADD) $(LIBS) ssl.so$(EXEEXT): $(ssl_so_OBJECTS) $(ssl_so_DEPENDENCIES) @rm -f ssl.so$(EXEEXT) $(ssl_so_LINK) $(ssl_so_OBJECTS) $(ssl_so_LDADD) $(LIBS) test.so$(EXEEXT): $(test_so_OBJECTS) $(test_so_DEPENDENCIES) @rm -f test.so$(EXEEXT) $(test_so_LINK) $(test_so_OBJECTS) $(test_so_LDADD) $(LIBS) install-filterSCRIPTS: $(filter_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(filterdir)" || $(MKDIR_P) "$(DESTDIR)$(filterdir)" @list='$(filter_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(filterSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(filterdir)/$$f'"; \ $(filterSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(filterdir)/$$f"; \ else :; fi; \ done uninstall-filterSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(filter_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(filterdir)/$$f'"; \ rm -f "$(DESTDIR)$(filterdir)/$$f"; \ done install-sbinSCRIPTS: $(sbin_SCRIPTS) @$(NORMAL_INSTALL) test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" @list='$(sbin_SCRIPTS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f $$d$$p; then \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \ else :; fi; \ done uninstall-sbinSCRIPTS: @$(NORMAL_UNINSTALL) @list='$(sbin_SCRIPTS)'; for p in $$list; do \ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \ echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ rm -f "$(DESTDIR)$(sbindir)/$$f"; \ done mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/accounting.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkpc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controlword.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copyright.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/errormsg.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileopen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gethostinfo.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getprinter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getqueue.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/globmatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/initialize.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krb5_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linelist.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/linksupport.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockfile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpbanner.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_control.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_dispatch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_jobs.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_logger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_rcvjob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_remove.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_secure.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_status.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpd_worker.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lprm.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpstat.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_so-md5.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_so-md5_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/merge.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/monitor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/openprinter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/permission.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plp_snprintf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/printjob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/proctitle.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendauth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendjob.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendmail.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sendreq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ssl_so-ssl_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stty.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_so-test_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_auth.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utilities.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vars.Po@am__quote@ .c.o: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` checkpc.o: common/checkpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT checkpc.o -MD -MP -MF $(DEPDIR)/checkpc.Tpo -c -o checkpc.o `test -f 'common/checkpc.c' || echo '$(srcdir)/'`common/checkpc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/checkpc.Tpo $(DEPDIR)/checkpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/checkpc.c' object='checkpc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o checkpc.o `test -f 'common/checkpc.c' || echo '$(srcdir)/'`common/checkpc.c checkpc.obj: common/checkpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT checkpc.obj -MD -MP -MF $(DEPDIR)/checkpc.Tpo -c -o checkpc.obj `if test -f 'common/checkpc.c'; then $(CYGPATH_W) 'common/checkpc.c'; else $(CYGPATH_W) '$(srcdir)/common/checkpc.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/checkpc.Tpo $(DEPDIR)/checkpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/checkpc.c' object='checkpc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o checkpc.obj `if test -f 'common/checkpc.c'; then $(CYGPATH_W) 'common/checkpc.c'; else $(CYGPATH_W) '$(srcdir)/common/checkpc.c'; fi` stty.o: common/stty.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stty.o -MD -MP -MF $(DEPDIR)/stty.Tpo -c -o stty.o `test -f 'common/stty.c' || echo '$(srcdir)/'`common/stty.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stty.Tpo $(DEPDIR)/stty.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/stty.c' object='stty.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stty.o `test -f 'common/stty.c' || echo '$(srcdir)/'`common/stty.c stty.obj: common/stty.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT stty.obj -MD -MP -MF $(DEPDIR)/stty.Tpo -c -o stty.obj `if test -f 'common/stty.c'; then $(CYGPATH_W) 'common/stty.c'; else $(CYGPATH_W) '$(srcdir)/common/stty.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/stty.Tpo $(DEPDIR)/stty.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/stty.c' object='stty.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stty.obj `if test -f 'common/stty.c'; then $(CYGPATH_W) 'common/stty.c'; else $(CYGPATH_W) '$(srcdir)/common/stty.c'; fi` child.o: common/child.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT child.o -MD -MP -MF $(DEPDIR)/child.Tpo -c -o child.o `test -f 'common/child.c' || echo '$(srcdir)/'`common/child.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/child.Tpo $(DEPDIR)/child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/child.c' object='child.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o child.o `test -f 'common/child.c' || echo '$(srcdir)/'`common/child.c child.obj: common/child.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT child.obj -MD -MP -MF $(DEPDIR)/child.Tpo -c -o child.obj `if test -f 'common/child.c'; then $(CYGPATH_W) 'common/child.c'; else $(CYGPATH_W) '$(srcdir)/common/child.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/child.Tpo $(DEPDIR)/child.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/child.c' object='child.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o child.obj `if test -f 'common/child.c'; then $(CYGPATH_W) 'common/child.c'; else $(CYGPATH_W) '$(srcdir)/common/child.c'; fi` copyright.o: common/copyright.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT copyright.o -MD -MP -MF $(DEPDIR)/copyright.Tpo -c -o copyright.o `test -f 'common/copyright.c' || echo '$(srcdir)/'`common/copyright.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/copyright.Tpo $(DEPDIR)/copyright.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/copyright.c' object='copyright.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o copyright.o `test -f 'common/copyright.c' || echo '$(srcdir)/'`common/copyright.c copyright.obj: common/copyright.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT copyright.obj -MD -MP -MF $(DEPDIR)/copyright.Tpo -c -o copyright.obj `if test -f 'common/copyright.c'; then $(CYGPATH_W) 'common/copyright.c'; else $(CYGPATH_W) '$(srcdir)/common/copyright.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/copyright.Tpo $(DEPDIR)/copyright.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/copyright.c' object='copyright.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o copyright.obj `if test -f 'common/copyright.c'; then $(CYGPATH_W) 'common/copyright.c'; else $(CYGPATH_W) '$(srcdir)/common/copyright.c'; fi` debug.o: common/debug.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT debug.o -MD -MP -MF $(DEPDIR)/debug.Tpo -c -o debug.o `test -f 'common/debug.c' || echo '$(srcdir)/'`common/debug.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/debug.Tpo $(DEPDIR)/debug.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/debug.c' object='debug.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o debug.o `test -f 'common/debug.c' || echo '$(srcdir)/'`common/debug.c debug.obj: common/debug.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT debug.obj -MD -MP -MF $(DEPDIR)/debug.Tpo -c -o debug.obj `if test -f 'common/debug.c'; then $(CYGPATH_W) 'common/debug.c'; else $(CYGPATH_W) '$(srcdir)/common/debug.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/debug.Tpo $(DEPDIR)/debug.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/debug.c' object='debug.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o debug.obj `if test -f 'common/debug.c'; then $(CYGPATH_W) 'common/debug.c'; else $(CYGPATH_W) '$(srcdir)/common/debug.c'; fi` errormsg.o: common/errormsg.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errormsg.o -MD -MP -MF $(DEPDIR)/errormsg.Tpo -c -o errormsg.o `test -f 'common/errormsg.c' || echo '$(srcdir)/'`common/errormsg.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/errormsg.Tpo $(DEPDIR)/errormsg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/errormsg.c' object='errormsg.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errormsg.o `test -f 'common/errormsg.c' || echo '$(srcdir)/'`common/errormsg.c errormsg.obj: common/errormsg.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT errormsg.obj -MD -MP -MF $(DEPDIR)/errormsg.Tpo -c -o errormsg.obj `if test -f 'common/errormsg.c'; then $(CYGPATH_W) 'common/errormsg.c'; else $(CYGPATH_W) '$(srcdir)/common/errormsg.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/errormsg.Tpo $(DEPDIR)/errormsg.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/errormsg.c' object='errormsg.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o errormsg.obj `if test -f 'common/errormsg.c'; then $(CYGPATH_W) 'common/errormsg.c'; else $(CYGPATH_W) '$(srcdir)/common/errormsg.c'; fi` fileopen.o: common/fileopen.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fileopen.o -MD -MP -MF $(DEPDIR)/fileopen.Tpo -c -o fileopen.o `test -f 'common/fileopen.c' || echo '$(srcdir)/'`common/fileopen.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fileopen.Tpo $(DEPDIR)/fileopen.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/fileopen.c' object='fileopen.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fileopen.o `test -f 'common/fileopen.c' || echo '$(srcdir)/'`common/fileopen.c fileopen.obj: common/fileopen.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fileopen.obj -MD -MP -MF $(DEPDIR)/fileopen.Tpo -c -o fileopen.obj `if test -f 'common/fileopen.c'; then $(CYGPATH_W) 'common/fileopen.c'; else $(CYGPATH_W) '$(srcdir)/common/fileopen.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/fileopen.Tpo $(DEPDIR)/fileopen.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/fileopen.c' object='fileopen.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fileopen.obj `if test -f 'common/fileopen.c'; then $(CYGPATH_W) 'common/fileopen.c'; else $(CYGPATH_W) '$(srcdir)/common/fileopen.c'; fi` gethostinfo.o: common/gethostinfo.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gethostinfo.o -MD -MP -MF $(DEPDIR)/gethostinfo.Tpo -c -o gethostinfo.o `test -f 'common/gethostinfo.c' || echo '$(srcdir)/'`common/gethostinfo.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/gethostinfo.Tpo $(DEPDIR)/gethostinfo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/gethostinfo.c' object='gethostinfo.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gethostinfo.o `test -f 'common/gethostinfo.c' || echo '$(srcdir)/'`common/gethostinfo.c gethostinfo.obj: common/gethostinfo.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gethostinfo.obj -MD -MP -MF $(DEPDIR)/gethostinfo.Tpo -c -o gethostinfo.obj `if test -f 'common/gethostinfo.c'; then $(CYGPATH_W) 'common/gethostinfo.c'; else $(CYGPATH_W) '$(srcdir)/common/gethostinfo.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/gethostinfo.Tpo $(DEPDIR)/gethostinfo.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/gethostinfo.c' object='gethostinfo.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gethostinfo.obj `if test -f 'common/gethostinfo.c'; then $(CYGPATH_W) 'common/gethostinfo.c'; else $(CYGPATH_W) '$(srcdir)/common/gethostinfo.c'; fi` getopt.o: common/getopt.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt.o -MD -MP -MF $(DEPDIR)/getopt.Tpo -c -o getopt.o `test -f 'common/getopt.c' || echo '$(srcdir)/'`common/getopt.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getopt.Tpo $(DEPDIR)/getopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getopt.c' object='getopt.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt.o `test -f 'common/getopt.c' || echo '$(srcdir)/'`common/getopt.c getopt.obj: common/getopt.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getopt.obj -MD -MP -MF $(DEPDIR)/getopt.Tpo -c -o getopt.obj `if test -f 'common/getopt.c'; then $(CYGPATH_W) 'common/getopt.c'; else $(CYGPATH_W) '$(srcdir)/common/getopt.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getopt.Tpo $(DEPDIR)/getopt.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getopt.c' object='getopt.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getopt.obj `if test -f 'common/getopt.c'; then $(CYGPATH_W) 'common/getopt.c'; else $(CYGPATH_W) '$(srcdir)/common/getopt.c'; fi` getprinter.o: common/getprinter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getprinter.o -MD -MP -MF $(DEPDIR)/getprinter.Tpo -c -o getprinter.o `test -f 'common/getprinter.c' || echo '$(srcdir)/'`common/getprinter.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getprinter.Tpo $(DEPDIR)/getprinter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getprinter.c' object='getprinter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getprinter.o `test -f 'common/getprinter.c' || echo '$(srcdir)/'`common/getprinter.c getprinter.obj: common/getprinter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getprinter.obj -MD -MP -MF $(DEPDIR)/getprinter.Tpo -c -o getprinter.obj `if test -f 'common/getprinter.c'; then $(CYGPATH_W) 'common/getprinter.c'; else $(CYGPATH_W) '$(srcdir)/common/getprinter.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getprinter.Tpo $(DEPDIR)/getprinter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getprinter.c' object='getprinter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getprinter.obj `if test -f 'common/getprinter.c'; then $(CYGPATH_W) 'common/getprinter.c'; else $(CYGPATH_W) '$(srcdir)/common/getprinter.c'; fi` getqueue.o: common/getqueue.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getqueue.o -MD -MP -MF $(DEPDIR)/getqueue.Tpo -c -o getqueue.o `test -f 'common/getqueue.c' || echo '$(srcdir)/'`common/getqueue.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getqueue.Tpo $(DEPDIR)/getqueue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getqueue.c' object='getqueue.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getqueue.o `test -f 'common/getqueue.c' || echo '$(srcdir)/'`common/getqueue.c getqueue.obj: common/getqueue.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT getqueue.obj -MD -MP -MF $(DEPDIR)/getqueue.Tpo -c -o getqueue.obj `if test -f 'common/getqueue.c'; then $(CYGPATH_W) 'common/getqueue.c'; else $(CYGPATH_W) '$(srcdir)/common/getqueue.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/getqueue.Tpo $(DEPDIR)/getqueue.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/getqueue.c' object='getqueue.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o getqueue.obj `if test -f 'common/getqueue.c'; then $(CYGPATH_W) 'common/getqueue.c'; else $(CYGPATH_W) '$(srcdir)/common/getqueue.c'; fi` globmatch.o: common/globmatch.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT globmatch.o -MD -MP -MF $(DEPDIR)/globmatch.Tpo -c -o globmatch.o `test -f 'common/globmatch.c' || echo '$(srcdir)/'`common/globmatch.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/globmatch.Tpo $(DEPDIR)/globmatch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/globmatch.c' object='globmatch.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o globmatch.o `test -f 'common/globmatch.c' || echo '$(srcdir)/'`common/globmatch.c globmatch.obj: common/globmatch.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT globmatch.obj -MD -MP -MF $(DEPDIR)/globmatch.Tpo -c -o globmatch.obj `if test -f 'common/globmatch.c'; then $(CYGPATH_W) 'common/globmatch.c'; else $(CYGPATH_W) '$(srcdir)/common/globmatch.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/globmatch.Tpo $(DEPDIR)/globmatch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/globmatch.c' object='globmatch.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o globmatch.obj `if test -f 'common/globmatch.c'; then $(CYGPATH_W) 'common/globmatch.c'; else $(CYGPATH_W) '$(srcdir)/common/globmatch.c'; fi` initialize.o: common/initialize.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT initialize.o -MD -MP -MF $(DEPDIR)/initialize.Tpo -c -o initialize.o `test -f 'common/initialize.c' || echo '$(srcdir)/'`common/initialize.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/initialize.Tpo $(DEPDIR)/initialize.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/initialize.c' object='initialize.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o initialize.o `test -f 'common/initialize.c' || echo '$(srcdir)/'`common/initialize.c initialize.obj: common/initialize.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT initialize.obj -MD -MP -MF $(DEPDIR)/initialize.Tpo -c -o initialize.obj `if test -f 'common/initialize.c'; then $(CYGPATH_W) 'common/initialize.c'; else $(CYGPATH_W) '$(srcdir)/common/initialize.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/initialize.Tpo $(DEPDIR)/initialize.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/initialize.c' object='initialize.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o initialize.obj `if test -f 'common/initialize.c'; then $(CYGPATH_W) 'common/initialize.c'; else $(CYGPATH_W) '$(srcdir)/common/initialize.c'; fi` linelist.o: common/linelist.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linelist.o -MD -MP -MF $(DEPDIR)/linelist.Tpo -c -o linelist.o `test -f 'common/linelist.c' || echo '$(srcdir)/'`common/linelist.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/linelist.Tpo $(DEPDIR)/linelist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/linelist.c' object='linelist.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linelist.o `test -f 'common/linelist.c' || echo '$(srcdir)/'`common/linelist.c linelist.obj: common/linelist.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linelist.obj -MD -MP -MF $(DEPDIR)/linelist.Tpo -c -o linelist.obj `if test -f 'common/linelist.c'; then $(CYGPATH_W) 'common/linelist.c'; else $(CYGPATH_W) '$(srcdir)/common/linelist.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/linelist.Tpo $(DEPDIR)/linelist.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/linelist.c' object='linelist.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linelist.obj `if test -f 'common/linelist.c'; then $(CYGPATH_W) 'common/linelist.c'; else $(CYGPATH_W) '$(srcdir)/common/linelist.c'; fi` linksupport.o: common/linksupport.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linksupport.o -MD -MP -MF $(DEPDIR)/linksupport.Tpo -c -o linksupport.o `test -f 'common/linksupport.c' || echo '$(srcdir)/'`common/linksupport.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/linksupport.Tpo $(DEPDIR)/linksupport.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/linksupport.c' object='linksupport.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linksupport.o `test -f 'common/linksupport.c' || echo '$(srcdir)/'`common/linksupport.c linksupport.obj: common/linksupport.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT linksupport.obj -MD -MP -MF $(DEPDIR)/linksupport.Tpo -c -o linksupport.obj `if test -f 'common/linksupport.c'; then $(CYGPATH_W) 'common/linksupport.c'; else $(CYGPATH_W) '$(srcdir)/common/linksupport.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/linksupport.Tpo $(DEPDIR)/linksupport.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/linksupport.c' object='linksupport.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o linksupport.obj `if test -f 'common/linksupport.c'; then $(CYGPATH_W) 'common/linksupport.c'; else $(CYGPATH_W) '$(srcdir)/common/linksupport.c'; fi` lockfile.o: common/lockfile.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lockfile.o -MD -MP -MF $(DEPDIR)/lockfile.Tpo -c -o lockfile.o `test -f 'common/lockfile.c' || echo '$(srcdir)/'`common/lockfile.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lockfile.Tpo $(DEPDIR)/lockfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lockfile.c' object='lockfile.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lockfile.o `test -f 'common/lockfile.c' || echo '$(srcdir)/'`common/lockfile.c lockfile.obj: common/lockfile.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lockfile.obj -MD -MP -MF $(DEPDIR)/lockfile.Tpo -c -o lockfile.obj `if test -f 'common/lockfile.c'; then $(CYGPATH_W) 'common/lockfile.c'; else $(CYGPATH_W) '$(srcdir)/common/lockfile.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lockfile.Tpo $(DEPDIR)/lockfile.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lockfile.c' object='lockfile.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lockfile.obj `if test -f 'common/lockfile.c'; then $(CYGPATH_W) 'common/lockfile.c'; else $(CYGPATH_W) '$(srcdir)/common/lockfile.c'; fi` merge.o: common/merge.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT merge.o -MD -MP -MF $(DEPDIR)/merge.Tpo -c -o merge.o `test -f 'common/merge.c' || echo '$(srcdir)/'`common/merge.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/merge.Tpo $(DEPDIR)/merge.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/merge.c' object='merge.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o merge.o `test -f 'common/merge.c' || echo '$(srcdir)/'`common/merge.c merge.obj: common/merge.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT merge.obj -MD -MP -MF $(DEPDIR)/merge.Tpo -c -o merge.obj `if test -f 'common/merge.c'; then $(CYGPATH_W) 'common/merge.c'; else $(CYGPATH_W) '$(srcdir)/common/merge.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/merge.Tpo $(DEPDIR)/merge.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/merge.c' object='merge.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o merge.obj `if test -f 'common/merge.c'; then $(CYGPATH_W) 'common/merge.c'; else $(CYGPATH_W) '$(srcdir)/common/merge.c'; fi` plp_snprintf.o: common/plp_snprintf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plp_snprintf.o -MD -MP -MF $(DEPDIR)/plp_snprintf.Tpo -c -o plp_snprintf.o `test -f 'common/plp_snprintf.c' || echo '$(srcdir)/'`common/plp_snprintf.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plp_snprintf.Tpo $(DEPDIR)/plp_snprintf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/plp_snprintf.c' object='plp_snprintf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plp_snprintf.o `test -f 'common/plp_snprintf.c' || echo '$(srcdir)/'`common/plp_snprintf.c plp_snprintf.obj: common/plp_snprintf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plp_snprintf.obj -MD -MP -MF $(DEPDIR)/plp_snprintf.Tpo -c -o plp_snprintf.obj `if test -f 'common/plp_snprintf.c'; then $(CYGPATH_W) 'common/plp_snprintf.c'; else $(CYGPATH_W) '$(srcdir)/common/plp_snprintf.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/plp_snprintf.Tpo $(DEPDIR)/plp_snprintf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/plp_snprintf.c' object='plp_snprintf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plp_snprintf.obj `if test -f 'common/plp_snprintf.c'; then $(CYGPATH_W) 'common/plp_snprintf.c'; else $(CYGPATH_W) '$(srcdir)/common/plp_snprintf.c'; fi` proctitle.o: common/proctitle.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT proctitle.o -MD -MP -MF $(DEPDIR)/proctitle.Tpo -c -o proctitle.o `test -f 'common/proctitle.c' || echo '$(srcdir)/'`common/proctitle.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/proctitle.Tpo $(DEPDIR)/proctitle.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/proctitle.c' object='proctitle.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o proctitle.o `test -f 'common/proctitle.c' || echo '$(srcdir)/'`common/proctitle.c proctitle.obj: common/proctitle.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT proctitle.obj -MD -MP -MF $(DEPDIR)/proctitle.Tpo -c -o proctitle.obj `if test -f 'common/proctitle.c'; then $(CYGPATH_W) 'common/proctitle.c'; else $(CYGPATH_W) '$(srcdir)/common/proctitle.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/proctitle.Tpo $(DEPDIR)/proctitle.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/proctitle.c' object='proctitle.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o proctitle.obj `if test -f 'common/proctitle.c'; then $(CYGPATH_W) 'common/proctitle.c'; else $(CYGPATH_W) '$(srcdir)/common/proctitle.c'; fi` utilities.o: common/utilities.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utilities.o -MD -MP -MF $(DEPDIR)/utilities.Tpo -c -o utilities.o `test -f 'common/utilities.c' || echo '$(srcdir)/'`common/utilities.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/utilities.Tpo $(DEPDIR)/utilities.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/utilities.c' object='utilities.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utilities.o `test -f 'common/utilities.c' || echo '$(srcdir)/'`common/utilities.c utilities.obj: common/utilities.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT utilities.obj -MD -MP -MF $(DEPDIR)/utilities.Tpo -c -o utilities.obj `if test -f 'common/utilities.c'; then $(CYGPATH_W) 'common/utilities.c'; else $(CYGPATH_W) '$(srcdir)/common/utilities.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/utilities.Tpo $(DEPDIR)/utilities.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/utilities.c' object='utilities.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o utilities.obj `if test -f 'common/utilities.c'; then $(CYGPATH_W) 'common/utilities.c'; else $(CYGPATH_W) '$(srcdir)/common/utilities.c'; fi` krb5_auth.o: auth/krb5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT krb5_auth.o -MD -MP -MF $(DEPDIR)/krb5_auth.Tpo -c -o krb5_auth.o `test -f 'auth/krb5_auth.c' || echo '$(srcdir)/'`auth/krb5_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/krb5_auth.Tpo $(DEPDIR)/krb5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/krb5_auth.c' object='krb5_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o krb5_auth.o `test -f 'auth/krb5_auth.c' || echo '$(srcdir)/'`auth/krb5_auth.c krb5_auth.obj: auth/krb5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT krb5_auth.obj -MD -MP -MF $(DEPDIR)/krb5_auth.Tpo -c -o krb5_auth.obj `if test -f 'auth/krb5_auth.c'; then $(CYGPATH_W) 'auth/krb5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/krb5_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/krb5_auth.Tpo $(DEPDIR)/krb5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/krb5_auth.c' object='krb5_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o krb5_auth.obj `if test -f 'auth/krb5_auth.c'; then $(CYGPATH_W) 'auth/krb5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/krb5_auth.c'; fi` lpbanner.o: common/lpbanner.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpbanner.o -MD -MP -MF $(DEPDIR)/lpbanner.Tpo -c -o lpbanner.o `test -f 'common/lpbanner.c' || echo '$(srcdir)/'`common/lpbanner.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpbanner.Tpo $(DEPDIR)/lpbanner.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpbanner.c' object='lpbanner.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpbanner.o `test -f 'common/lpbanner.c' || echo '$(srcdir)/'`common/lpbanner.c lpbanner.obj: common/lpbanner.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpbanner.obj -MD -MP -MF $(DEPDIR)/lpbanner.Tpo -c -o lpbanner.obj `if test -f 'common/lpbanner.c'; then $(CYGPATH_W) 'common/lpbanner.c'; else $(CYGPATH_W) '$(srcdir)/common/lpbanner.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpbanner.Tpo $(DEPDIR)/lpbanner.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpbanner.c' object='lpbanner.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpbanner.obj `if test -f 'common/lpbanner.c'; then $(CYGPATH_W) 'common/lpbanner.c'; else $(CYGPATH_W) '$(srcdir)/common/lpbanner.c'; fi` lpc.o: common/lpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpc.o -MD -MP -MF $(DEPDIR)/lpc.Tpo -c -o lpc.o `test -f 'common/lpc.c' || echo '$(srcdir)/'`common/lpc.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpc.Tpo $(DEPDIR)/lpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpc.c' object='lpc.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpc.o `test -f 'common/lpc.c' || echo '$(srcdir)/'`common/lpc.c lpc.obj: common/lpc.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpc.obj -MD -MP -MF $(DEPDIR)/lpc.Tpo -c -o lpc.obj `if test -f 'common/lpc.c'; then $(CYGPATH_W) 'common/lpc.c'; else $(CYGPATH_W) '$(srcdir)/common/lpc.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpc.Tpo $(DEPDIR)/lpc.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpc.c' object='lpc.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpc.obj `if test -f 'common/lpc.c'; then $(CYGPATH_W) 'common/lpc.c'; else $(CYGPATH_W) '$(srcdir)/common/lpc.c'; fi` controlword.o: common/controlword.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controlword.o -MD -MP -MF $(DEPDIR)/controlword.Tpo -c -o controlword.o `test -f 'common/controlword.c' || echo '$(srcdir)/'`common/controlword.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/controlword.Tpo $(DEPDIR)/controlword.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/controlword.c' object='controlword.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controlword.o `test -f 'common/controlword.c' || echo '$(srcdir)/'`common/controlword.c controlword.obj: common/controlword.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT controlword.obj -MD -MP -MF $(DEPDIR)/controlword.Tpo -c -o controlword.obj `if test -f 'common/controlword.c'; then $(CYGPATH_W) 'common/controlword.c'; else $(CYGPATH_W) '$(srcdir)/common/controlword.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/controlword.Tpo $(DEPDIR)/controlword.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/controlword.c' object='controlword.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o controlword.obj `if test -f 'common/controlword.c'; then $(CYGPATH_W) 'common/controlword.c'; else $(CYGPATH_W) '$(srcdir)/common/controlword.c'; fi` sendauth.o: common/sendauth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendauth.o -MD -MP -MF $(DEPDIR)/sendauth.Tpo -c -o sendauth.o `test -f 'common/sendauth.c' || echo '$(srcdir)/'`common/sendauth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendauth.Tpo $(DEPDIR)/sendauth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendauth.c' object='sendauth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendauth.o `test -f 'common/sendauth.c' || echo '$(srcdir)/'`common/sendauth.c sendauth.obj: common/sendauth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendauth.obj -MD -MP -MF $(DEPDIR)/sendauth.Tpo -c -o sendauth.obj `if test -f 'common/sendauth.c'; then $(CYGPATH_W) 'common/sendauth.c'; else $(CYGPATH_W) '$(srcdir)/common/sendauth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendauth.Tpo $(DEPDIR)/sendauth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendauth.c' object='sendauth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendauth.obj `if test -f 'common/sendauth.c'; then $(CYGPATH_W) 'common/sendauth.c'; else $(CYGPATH_W) '$(srcdir)/common/sendauth.c'; fi` sendjob.o: common/sendjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendjob.o -MD -MP -MF $(DEPDIR)/sendjob.Tpo -c -o sendjob.o `test -f 'common/sendjob.c' || echo '$(srcdir)/'`common/sendjob.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendjob.Tpo $(DEPDIR)/sendjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendjob.c' object='sendjob.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendjob.o `test -f 'common/sendjob.c' || echo '$(srcdir)/'`common/sendjob.c sendjob.obj: common/sendjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendjob.obj -MD -MP -MF $(DEPDIR)/sendjob.Tpo -c -o sendjob.obj `if test -f 'common/sendjob.c'; then $(CYGPATH_W) 'common/sendjob.c'; else $(CYGPATH_W) '$(srcdir)/common/sendjob.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendjob.Tpo $(DEPDIR)/sendjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendjob.c' object='sendjob.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendjob.obj `if test -f 'common/sendjob.c'; then $(CYGPATH_W) 'common/sendjob.c'; else $(CYGPATH_W) '$(srcdir)/common/sendjob.c'; fi` sendreq.o: common/sendreq.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendreq.o -MD -MP -MF $(DEPDIR)/sendreq.Tpo -c -o sendreq.o `test -f 'common/sendreq.c' || echo '$(srcdir)/'`common/sendreq.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendreq.Tpo $(DEPDIR)/sendreq.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendreq.c' object='sendreq.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendreq.o `test -f 'common/sendreq.c' || echo '$(srcdir)/'`common/sendreq.c sendreq.obj: common/sendreq.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendreq.obj -MD -MP -MF $(DEPDIR)/sendreq.Tpo -c -o sendreq.obj `if test -f 'common/sendreq.c'; then $(CYGPATH_W) 'common/sendreq.c'; else $(CYGPATH_W) '$(srcdir)/common/sendreq.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendreq.Tpo $(DEPDIR)/sendreq.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendreq.c' object='sendreq.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendreq.obj `if test -f 'common/sendreq.c'; then $(CYGPATH_W) 'common/sendreq.c'; else $(CYGPATH_W) '$(srcdir)/common/sendreq.c'; fi` user_auth.o: common/user_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT user_auth.o -MD -MP -MF $(DEPDIR)/user_auth.Tpo -c -o user_auth.o `test -f 'common/user_auth.c' || echo '$(srcdir)/'`common/user_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/user_auth.Tpo $(DEPDIR)/user_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/user_auth.c' object='user_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o user_auth.o `test -f 'common/user_auth.c' || echo '$(srcdir)/'`common/user_auth.c user_auth.obj: common/user_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT user_auth.obj -MD -MP -MF $(DEPDIR)/user_auth.Tpo -c -o user_auth.obj `if test -f 'common/user_auth.c'; then $(CYGPATH_W) 'common/user_auth.c'; else $(CYGPATH_W) '$(srcdir)/common/user_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/user_auth.Tpo $(DEPDIR)/user_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/user_auth.c' object='user_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o user_auth.obj `if test -f 'common/user_auth.c'; then $(CYGPATH_W) 'common/user_auth.c'; else $(CYGPATH_W) '$(srcdir)/common/user_auth.c'; fi` printjob.o: common/printjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT printjob.o -MD -MP -MF $(DEPDIR)/printjob.Tpo -c -o printjob.o `test -f 'common/printjob.c' || echo '$(srcdir)/'`common/printjob.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/printjob.Tpo $(DEPDIR)/printjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/printjob.c' object='printjob.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o printjob.o `test -f 'common/printjob.c' || echo '$(srcdir)/'`common/printjob.c printjob.obj: common/printjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT printjob.obj -MD -MP -MF $(DEPDIR)/printjob.Tpo -c -o printjob.obj `if test -f 'common/printjob.c'; then $(CYGPATH_W) 'common/printjob.c'; else $(CYGPATH_W) '$(srcdir)/common/printjob.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/printjob.Tpo $(DEPDIR)/printjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/printjob.c' object='printjob.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o printjob.obj `if test -f 'common/printjob.c'; then $(CYGPATH_W) 'common/printjob.c'; else $(CYGPATH_W) '$(srcdir)/common/printjob.c'; fi` md5.o: common/md5.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5.o -MD -MP -MF $(DEPDIR)/md5.Tpo -c -o md5.o `test -f 'common/md5.c' || echo '$(srcdir)/'`common/md5.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5.Tpo $(DEPDIR)/md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/md5.c' object='md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5.o `test -f 'common/md5.c' || echo '$(srcdir)/'`common/md5.c md5.obj: common/md5.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5.obj -MD -MP -MF $(DEPDIR)/md5.Tpo -c -o md5.obj `if test -f 'common/md5.c'; then $(CYGPATH_W) 'common/md5.c'; else $(CYGPATH_W) '$(srcdir)/common/md5.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5.Tpo $(DEPDIR)/md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/md5.c' object='md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5.obj `if test -f 'common/md5.c'; then $(CYGPATH_W) 'common/md5.c'; else $(CYGPATH_W) '$(srcdir)/common/md5.c'; fi` md5_auth.o: auth/md5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5_auth.o -MD -MP -MF $(DEPDIR)/md5_auth.Tpo -c -o md5_auth.o `test -f 'auth/md5_auth.c' || echo '$(srcdir)/'`auth/md5_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_auth.Tpo $(DEPDIR)/md5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/md5_auth.c' object='md5_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5_auth.o `test -f 'auth/md5_auth.c' || echo '$(srcdir)/'`auth/md5_auth.c md5_auth.obj: auth/md5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT md5_auth.obj -MD -MP -MF $(DEPDIR)/md5_auth.Tpo -c -o md5_auth.obj `if test -f 'auth/md5_auth.c'; then $(CYGPATH_W) 'auth/md5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/md5_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_auth.Tpo $(DEPDIR)/md5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/md5_auth.c' object='md5_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o md5_auth.obj `if test -f 'auth/md5_auth.c'; then $(CYGPATH_W) 'auth/md5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/md5_auth.c'; fi` test_auth.o: auth/test_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_auth.o -MD -MP -MF $(DEPDIR)/test_auth.Tpo -c -o test_auth.o `test -f 'auth/test_auth.c' || echo '$(srcdir)/'`auth/test_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_auth.Tpo $(DEPDIR)/test_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/test_auth.c' object='test_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_auth.o `test -f 'auth/test_auth.c' || echo '$(srcdir)/'`auth/test_auth.c test_auth.obj: auth/test_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT test_auth.obj -MD -MP -MF $(DEPDIR)/test_auth.Tpo -c -o test_auth.obj `if test -f 'auth/test_auth.c'; then $(CYGPATH_W) 'auth/test_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/test_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_auth.Tpo $(DEPDIR)/test_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/test_auth.c' object='test_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o test_auth.obj `if test -f 'auth/test_auth.c'; then $(CYGPATH_W) 'auth/test_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/test_auth.c'; fi` ssl_auth.o: auth/ssl_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ssl_auth.o -MD -MP -MF $(DEPDIR)/ssl_auth.Tpo -c -o ssl_auth.o `test -f 'auth/ssl_auth.c' || echo '$(srcdir)/'`auth/ssl_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ssl_auth.Tpo $(DEPDIR)/ssl_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/ssl_auth.c' object='ssl_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ssl_auth.o `test -f 'auth/ssl_auth.c' || echo '$(srcdir)/'`auth/ssl_auth.c ssl_auth.obj: auth/ssl_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ssl_auth.obj -MD -MP -MF $(DEPDIR)/ssl_auth.Tpo -c -o ssl_auth.obj `if test -f 'auth/ssl_auth.c'; then $(CYGPATH_W) 'auth/ssl_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/ssl_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ssl_auth.Tpo $(DEPDIR)/ssl_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/ssl_auth.c' object='ssl_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ssl_auth.obj `if test -f 'auth/ssl_auth.c'; then $(CYGPATH_W) 'auth/ssl_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/ssl_auth.c'; fi` lpd.o: common/lpd.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd.o -MD -MP -MF $(DEPDIR)/lpd.Tpo -c -o lpd.o `test -f 'common/lpd.c' || echo '$(srcdir)/'`common/lpd.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd.Tpo $(DEPDIR)/lpd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd.c' object='lpd.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd.o `test -f 'common/lpd.c' || echo '$(srcdir)/'`common/lpd.c lpd.obj: common/lpd.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd.obj -MD -MP -MF $(DEPDIR)/lpd.Tpo -c -o lpd.obj `if test -f 'common/lpd.c'; then $(CYGPATH_W) 'common/lpd.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd.Tpo $(DEPDIR)/lpd.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd.c' object='lpd.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd.obj `if test -f 'common/lpd.c'; then $(CYGPATH_W) 'common/lpd.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd.c'; fi` lpd_worker.o: common/lpd_worker.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_worker.o -MD -MP -MF $(DEPDIR)/lpd_worker.Tpo -c -o lpd_worker.o `test -f 'common/lpd_worker.c' || echo '$(srcdir)/'`common/lpd_worker.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_worker.Tpo $(DEPDIR)/lpd_worker.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_worker.c' object='lpd_worker.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_worker.o `test -f 'common/lpd_worker.c' || echo '$(srcdir)/'`common/lpd_worker.c lpd_worker.obj: common/lpd_worker.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_worker.obj -MD -MP -MF $(DEPDIR)/lpd_worker.Tpo -c -o lpd_worker.obj `if test -f 'common/lpd_worker.c'; then $(CYGPATH_W) 'common/lpd_worker.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_worker.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_worker.Tpo $(DEPDIR)/lpd_worker.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_worker.c' object='lpd_worker.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_worker.obj `if test -f 'common/lpd_worker.c'; then $(CYGPATH_W) 'common/lpd_worker.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_worker.c'; fi` lpd_jobs.o: common/lpd_jobs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_jobs.o -MD -MP -MF $(DEPDIR)/lpd_jobs.Tpo -c -o lpd_jobs.o `test -f 'common/lpd_jobs.c' || echo '$(srcdir)/'`common/lpd_jobs.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_jobs.Tpo $(DEPDIR)/lpd_jobs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_jobs.c' object='lpd_jobs.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_jobs.o `test -f 'common/lpd_jobs.c' || echo '$(srcdir)/'`common/lpd_jobs.c lpd_jobs.obj: common/lpd_jobs.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_jobs.obj -MD -MP -MF $(DEPDIR)/lpd_jobs.Tpo -c -o lpd_jobs.obj `if test -f 'common/lpd_jobs.c'; then $(CYGPATH_W) 'common/lpd_jobs.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_jobs.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_jobs.Tpo $(DEPDIR)/lpd_jobs.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_jobs.c' object='lpd_jobs.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_jobs.obj `if test -f 'common/lpd_jobs.c'; then $(CYGPATH_W) 'common/lpd_jobs.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_jobs.c'; fi` lpd_control.o: common/lpd_control.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_control.o -MD -MP -MF $(DEPDIR)/lpd_control.Tpo -c -o lpd_control.o `test -f 'common/lpd_control.c' || echo '$(srcdir)/'`common/lpd_control.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_control.Tpo $(DEPDIR)/lpd_control.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_control.c' object='lpd_control.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_control.o `test -f 'common/lpd_control.c' || echo '$(srcdir)/'`common/lpd_control.c lpd_control.obj: common/lpd_control.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_control.obj -MD -MP -MF $(DEPDIR)/lpd_control.Tpo -c -o lpd_control.obj `if test -f 'common/lpd_control.c'; then $(CYGPATH_W) 'common/lpd_control.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_control.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_control.Tpo $(DEPDIR)/lpd_control.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_control.c' object='lpd_control.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_control.obj `if test -f 'common/lpd_control.c'; then $(CYGPATH_W) 'common/lpd_control.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_control.c'; fi` sendmail.o: common/sendmail.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendmail.o -MD -MP -MF $(DEPDIR)/sendmail.Tpo -c -o sendmail.o `test -f 'common/sendmail.c' || echo '$(srcdir)/'`common/sendmail.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendmail.Tpo $(DEPDIR)/sendmail.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendmail.c' object='sendmail.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendmail.o `test -f 'common/sendmail.c' || echo '$(srcdir)/'`common/sendmail.c sendmail.obj: common/sendmail.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sendmail.obj -MD -MP -MF $(DEPDIR)/sendmail.Tpo -c -o sendmail.obj `if test -f 'common/sendmail.c'; then $(CYGPATH_W) 'common/sendmail.c'; else $(CYGPATH_W) '$(srcdir)/common/sendmail.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/sendmail.Tpo $(DEPDIR)/sendmail.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/sendmail.c' object='sendmail.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sendmail.obj `if test -f 'common/sendmail.c'; then $(CYGPATH_W) 'common/sendmail.c'; else $(CYGPATH_W) '$(srcdir)/common/sendmail.c'; fi` lpd_dispatch.o: common/lpd_dispatch.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_dispatch.o -MD -MP -MF $(DEPDIR)/lpd_dispatch.Tpo -c -o lpd_dispatch.o `test -f 'common/lpd_dispatch.c' || echo '$(srcdir)/'`common/lpd_dispatch.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_dispatch.Tpo $(DEPDIR)/lpd_dispatch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_dispatch.c' object='lpd_dispatch.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_dispatch.o `test -f 'common/lpd_dispatch.c' || echo '$(srcdir)/'`common/lpd_dispatch.c lpd_dispatch.obj: common/lpd_dispatch.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_dispatch.obj -MD -MP -MF $(DEPDIR)/lpd_dispatch.Tpo -c -o lpd_dispatch.obj `if test -f 'common/lpd_dispatch.c'; then $(CYGPATH_W) 'common/lpd_dispatch.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_dispatch.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_dispatch.Tpo $(DEPDIR)/lpd_dispatch.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_dispatch.c' object='lpd_dispatch.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_dispatch.obj `if test -f 'common/lpd_dispatch.c'; then $(CYGPATH_W) 'common/lpd_dispatch.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_dispatch.c'; fi` lpd_logger.o: common/lpd_logger.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_logger.o -MD -MP -MF $(DEPDIR)/lpd_logger.Tpo -c -o lpd_logger.o `test -f 'common/lpd_logger.c' || echo '$(srcdir)/'`common/lpd_logger.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_logger.Tpo $(DEPDIR)/lpd_logger.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_logger.c' object='lpd_logger.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_logger.o `test -f 'common/lpd_logger.c' || echo '$(srcdir)/'`common/lpd_logger.c lpd_logger.obj: common/lpd_logger.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_logger.obj -MD -MP -MF $(DEPDIR)/lpd_logger.Tpo -c -o lpd_logger.obj `if test -f 'common/lpd_logger.c'; then $(CYGPATH_W) 'common/lpd_logger.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_logger.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_logger.Tpo $(DEPDIR)/lpd_logger.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_logger.c' object='lpd_logger.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_logger.obj `if test -f 'common/lpd_logger.c'; then $(CYGPATH_W) 'common/lpd_logger.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_logger.c'; fi` lpd_rcvjob.o: common/lpd_rcvjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_rcvjob.o -MD -MP -MF $(DEPDIR)/lpd_rcvjob.Tpo -c -o lpd_rcvjob.o `test -f 'common/lpd_rcvjob.c' || echo '$(srcdir)/'`common/lpd_rcvjob.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_rcvjob.Tpo $(DEPDIR)/lpd_rcvjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_rcvjob.c' object='lpd_rcvjob.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_rcvjob.o `test -f 'common/lpd_rcvjob.c' || echo '$(srcdir)/'`common/lpd_rcvjob.c lpd_rcvjob.obj: common/lpd_rcvjob.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_rcvjob.obj -MD -MP -MF $(DEPDIR)/lpd_rcvjob.Tpo -c -o lpd_rcvjob.obj `if test -f 'common/lpd_rcvjob.c'; then $(CYGPATH_W) 'common/lpd_rcvjob.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_rcvjob.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_rcvjob.Tpo $(DEPDIR)/lpd_rcvjob.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_rcvjob.c' object='lpd_rcvjob.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_rcvjob.obj `if test -f 'common/lpd_rcvjob.c'; then $(CYGPATH_W) 'common/lpd_rcvjob.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_rcvjob.c'; fi` lpd_remove.o: common/lpd_remove.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_remove.o -MD -MP -MF $(DEPDIR)/lpd_remove.Tpo -c -o lpd_remove.o `test -f 'common/lpd_remove.c' || echo '$(srcdir)/'`common/lpd_remove.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_remove.Tpo $(DEPDIR)/lpd_remove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_remove.c' object='lpd_remove.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_remove.o `test -f 'common/lpd_remove.c' || echo '$(srcdir)/'`common/lpd_remove.c lpd_remove.obj: common/lpd_remove.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_remove.obj -MD -MP -MF $(DEPDIR)/lpd_remove.Tpo -c -o lpd_remove.obj `if test -f 'common/lpd_remove.c'; then $(CYGPATH_W) 'common/lpd_remove.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_remove.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_remove.Tpo $(DEPDIR)/lpd_remove.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_remove.c' object='lpd_remove.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_remove.obj `if test -f 'common/lpd_remove.c'; then $(CYGPATH_W) 'common/lpd_remove.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_remove.c'; fi` lpd_secure.o: common/lpd_secure.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_secure.o -MD -MP -MF $(DEPDIR)/lpd_secure.Tpo -c -o lpd_secure.o `test -f 'common/lpd_secure.c' || echo '$(srcdir)/'`common/lpd_secure.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_secure.Tpo $(DEPDIR)/lpd_secure.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_secure.c' object='lpd_secure.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_secure.o `test -f 'common/lpd_secure.c' || echo '$(srcdir)/'`common/lpd_secure.c lpd_secure.obj: common/lpd_secure.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_secure.obj -MD -MP -MF $(DEPDIR)/lpd_secure.Tpo -c -o lpd_secure.obj `if test -f 'common/lpd_secure.c'; then $(CYGPATH_W) 'common/lpd_secure.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_secure.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_secure.Tpo $(DEPDIR)/lpd_secure.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_secure.c' object='lpd_secure.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_secure.obj `if test -f 'common/lpd_secure.c'; then $(CYGPATH_W) 'common/lpd_secure.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_secure.c'; fi` lpd_status.o: common/lpd_status.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_status.o -MD -MP -MF $(DEPDIR)/lpd_status.Tpo -c -o lpd_status.o `test -f 'common/lpd_status.c' || echo '$(srcdir)/'`common/lpd_status.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_status.Tpo $(DEPDIR)/lpd_status.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_status.c' object='lpd_status.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_status.o `test -f 'common/lpd_status.c' || echo '$(srcdir)/'`common/lpd_status.c lpd_status.obj: common/lpd_status.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpd_status.obj -MD -MP -MF $(DEPDIR)/lpd_status.Tpo -c -o lpd_status.obj `if test -f 'common/lpd_status.c'; then $(CYGPATH_W) 'common/lpd_status.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_status.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpd_status.Tpo $(DEPDIR)/lpd_status.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpd_status.c' object='lpd_status.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpd_status.obj `if test -f 'common/lpd_status.c'; then $(CYGPATH_W) 'common/lpd_status.c'; else $(CYGPATH_W) '$(srcdir)/common/lpd_status.c'; fi` permission.o: common/permission.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT permission.o -MD -MP -MF $(DEPDIR)/permission.Tpo -c -o permission.o `test -f 'common/permission.c' || echo '$(srcdir)/'`common/permission.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/permission.Tpo $(DEPDIR)/permission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/permission.c' object='permission.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o permission.o `test -f 'common/permission.c' || echo '$(srcdir)/'`common/permission.c permission.obj: common/permission.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT permission.obj -MD -MP -MF $(DEPDIR)/permission.Tpo -c -o permission.obj `if test -f 'common/permission.c'; then $(CYGPATH_W) 'common/permission.c'; else $(CYGPATH_W) '$(srcdir)/common/permission.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/permission.Tpo $(DEPDIR)/permission.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/permission.c' object='permission.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o permission.obj `if test -f 'common/permission.c'; then $(CYGPATH_W) 'common/permission.c'; else $(CYGPATH_W) '$(srcdir)/common/permission.c'; fi` accounting.o: common/accounting.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT accounting.o -MD -MP -MF $(DEPDIR)/accounting.Tpo -c -o accounting.o `test -f 'common/accounting.c' || echo '$(srcdir)/'`common/accounting.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/accounting.Tpo $(DEPDIR)/accounting.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/accounting.c' object='accounting.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o accounting.o `test -f 'common/accounting.c' || echo '$(srcdir)/'`common/accounting.c accounting.obj: common/accounting.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT accounting.obj -MD -MP -MF $(DEPDIR)/accounting.Tpo -c -o accounting.obj `if test -f 'common/accounting.c'; then $(CYGPATH_W) 'common/accounting.c'; else $(CYGPATH_W) '$(srcdir)/common/accounting.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/accounting.Tpo $(DEPDIR)/accounting.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/accounting.c' object='accounting.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o accounting.obj `if test -f 'common/accounting.c'; then $(CYGPATH_W) 'common/accounting.c'; else $(CYGPATH_W) '$(srcdir)/common/accounting.c'; fi` openprinter.o: common/openprinter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT openprinter.o -MD -MP -MF $(DEPDIR)/openprinter.Tpo -c -o openprinter.o `test -f 'common/openprinter.c' || echo '$(srcdir)/'`common/openprinter.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/openprinter.Tpo $(DEPDIR)/openprinter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/openprinter.c' object='openprinter.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o openprinter.o `test -f 'common/openprinter.c' || echo '$(srcdir)/'`common/openprinter.c openprinter.obj: common/openprinter.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT openprinter.obj -MD -MP -MF $(DEPDIR)/openprinter.Tpo -c -o openprinter.obj `if test -f 'common/openprinter.c'; then $(CYGPATH_W) 'common/openprinter.c'; else $(CYGPATH_W) '$(srcdir)/common/openprinter.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/openprinter.Tpo $(DEPDIR)/openprinter.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/openprinter.c' object='openprinter.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o openprinter.obj `if test -f 'common/openprinter.c'; then $(CYGPATH_W) 'common/openprinter.c'; else $(CYGPATH_W) '$(srcdir)/common/openprinter.c'; fi` lpf.o: common/lpf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpf.o -MD -MP -MF $(DEPDIR)/lpf.Tpo -c -o lpf.o `test -f 'common/lpf.c' || echo '$(srcdir)/'`common/lpf.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpf.Tpo $(DEPDIR)/lpf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpf.c' object='lpf.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpf.o `test -f 'common/lpf.c' || echo '$(srcdir)/'`common/lpf.c lpf.obj: common/lpf.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpf.obj -MD -MP -MF $(DEPDIR)/lpf.Tpo -c -o lpf.obj `if test -f 'common/lpf.c'; then $(CYGPATH_W) 'common/lpf.c'; else $(CYGPATH_W) '$(srcdir)/common/lpf.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpf.Tpo $(DEPDIR)/lpf.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpf.c' object='lpf.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpf.obj `if test -f 'common/lpf.c'; then $(CYGPATH_W) 'common/lpf.c'; else $(CYGPATH_W) '$(srcdir)/common/lpf.c'; fi` lpq.o: common/lpq.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpq.o -MD -MP -MF $(DEPDIR)/lpq.Tpo -c -o lpq.o `test -f 'common/lpq.c' || echo '$(srcdir)/'`common/lpq.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpq.Tpo $(DEPDIR)/lpq.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpq.c' object='lpq.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpq.o `test -f 'common/lpq.c' || echo '$(srcdir)/'`common/lpq.c lpq.obj: common/lpq.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpq.obj -MD -MP -MF $(DEPDIR)/lpq.Tpo -c -o lpq.obj `if test -f 'common/lpq.c'; then $(CYGPATH_W) 'common/lpq.c'; else $(CYGPATH_W) '$(srcdir)/common/lpq.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpq.Tpo $(DEPDIR)/lpq.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpq.c' object='lpq.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpq.obj `if test -f 'common/lpq.c'; then $(CYGPATH_W) 'common/lpq.c'; else $(CYGPATH_W) '$(srcdir)/common/lpq.c'; fi` lpr.o: common/lpr.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpr.o -MD -MP -MF $(DEPDIR)/lpr.Tpo -c -o lpr.o `test -f 'common/lpr.c' || echo '$(srcdir)/'`common/lpr.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpr.Tpo $(DEPDIR)/lpr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpr.c' object='lpr.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpr.o `test -f 'common/lpr.c' || echo '$(srcdir)/'`common/lpr.c lpr.obj: common/lpr.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpr.obj -MD -MP -MF $(DEPDIR)/lpr.Tpo -c -o lpr.obj `if test -f 'common/lpr.c'; then $(CYGPATH_W) 'common/lpr.c'; else $(CYGPATH_W) '$(srcdir)/common/lpr.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpr.Tpo $(DEPDIR)/lpr.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpr.c' object='lpr.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpr.obj `if test -f 'common/lpr.c'; then $(CYGPATH_W) 'common/lpr.c'; else $(CYGPATH_W) '$(srcdir)/common/lpr.c'; fi` lprm.o: common/lprm.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lprm.o -MD -MP -MF $(DEPDIR)/lprm.Tpo -c -o lprm.o `test -f 'common/lprm.c' || echo '$(srcdir)/'`common/lprm.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lprm.Tpo $(DEPDIR)/lprm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lprm.c' object='lprm.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lprm.o `test -f 'common/lprm.c' || echo '$(srcdir)/'`common/lprm.c lprm.obj: common/lprm.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lprm.obj -MD -MP -MF $(DEPDIR)/lprm.Tpo -c -o lprm.obj `if test -f 'common/lprm.c'; then $(CYGPATH_W) 'common/lprm.c'; else $(CYGPATH_W) '$(srcdir)/common/lprm.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lprm.Tpo $(DEPDIR)/lprm.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lprm.c' object='lprm.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lprm.obj `if test -f 'common/lprm.c'; then $(CYGPATH_W) 'common/lprm.c'; else $(CYGPATH_W) '$(srcdir)/common/lprm.c'; fi` lpstat.o: common/lpstat.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpstat.o -MD -MP -MF $(DEPDIR)/lpstat.Tpo -c -o lpstat.o `test -f 'common/lpstat.c' || echo '$(srcdir)/'`common/lpstat.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpstat.Tpo $(DEPDIR)/lpstat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpstat.c' object='lpstat.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpstat.o `test -f 'common/lpstat.c' || echo '$(srcdir)/'`common/lpstat.c lpstat.obj: common/lpstat.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpstat.obj -MD -MP -MF $(DEPDIR)/lpstat.Tpo -c -o lpstat.obj `if test -f 'common/lpstat.c'; then $(CYGPATH_W) 'common/lpstat.c'; else $(CYGPATH_W) '$(srcdir)/common/lpstat.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/lpstat.Tpo $(DEPDIR)/lpstat.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/lpstat.c' object='lpstat.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpstat.obj `if test -f 'common/lpstat.c'; then $(CYGPATH_W) 'common/lpstat.c'; else $(CYGPATH_W) '$(srcdir)/common/lpstat.c'; fi` md5_so-md5_auth.o: auth/md5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -MT md5_so-md5_auth.o -MD -MP -MF $(DEPDIR)/md5_so-md5_auth.Tpo -c -o md5_so-md5_auth.o `test -f 'auth/md5_auth.c' || echo '$(srcdir)/'`auth/md5_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_so-md5_auth.Tpo $(DEPDIR)/md5_so-md5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/md5_auth.c' object='md5_so-md5_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -c -o md5_so-md5_auth.o `test -f 'auth/md5_auth.c' || echo '$(srcdir)/'`auth/md5_auth.c md5_so-md5_auth.obj: auth/md5_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -MT md5_so-md5_auth.obj -MD -MP -MF $(DEPDIR)/md5_so-md5_auth.Tpo -c -o md5_so-md5_auth.obj `if test -f 'auth/md5_auth.c'; then $(CYGPATH_W) 'auth/md5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/md5_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_so-md5_auth.Tpo $(DEPDIR)/md5_so-md5_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/md5_auth.c' object='md5_so-md5_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -c -o md5_so-md5_auth.obj `if test -f 'auth/md5_auth.c'; then $(CYGPATH_W) 'auth/md5_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/md5_auth.c'; fi` md5_so-md5.o: common/md5.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -MT md5_so-md5.o -MD -MP -MF $(DEPDIR)/md5_so-md5.Tpo -c -o md5_so-md5.o `test -f 'common/md5.c' || echo '$(srcdir)/'`common/md5.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_so-md5.Tpo $(DEPDIR)/md5_so-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/md5.c' object='md5_so-md5.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -c -o md5_so-md5.o `test -f 'common/md5.c' || echo '$(srcdir)/'`common/md5.c md5_so-md5.obj: common/md5.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -MT md5_so-md5.obj -MD -MP -MF $(DEPDIR)/md5_so-md5.Tpo -c -o md5_so-md5.obj `if test -f 'common/md5.c'; then $(CYGPATH_W) 'common/md5.c'; else $(CYGPATH_W) '$(srcdir)/common/md5.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/md5_so-md5.Tpo $(DEPDIR)/md5_so-md5.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/md5.c' object='md5_so-md5.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(md5_so_CFLAGS) $(CFLAGS) -c -o md5_so-md5.obj `if test -f 'common/md5.c'; then $(CYGPATH_W) 'common/md5.c'; else $(CYGPATH_W) '$(srcdir)/common/md5.c'; fi` monitor.o: common/monitor.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT monitor.o -MD -MP -MF $(DEPDIR)/monitor.Tpo -c -o monitor.o `test -f 'common/monitor.c' || echo '$(srcdir)/'`common/monitor.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/monitor.Tpo $(DEPDIR)/monitor.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/monitor.c' object='monitor.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o monitor.o `test -f 'common/monitor.c' || echo '$(srcdir)/'`common/monitor.c monitor.obj: common/monitor.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT monitor.obj -MD -MP -MF $(DEPDIR)/monitor.Tpo -c -o monitor.obj `if test -f 'common/monitor.c'; then $(CYGPATH_W) 'common/monitor.c'; else $(CYGPATH_W) '$(srcdir)/common/monitor.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/monitor.Tpo $(DEPDIR)/monitor.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='common/monitor.c' object='monitor.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o monitor.obj `if test -f 'common/monitor.c'; then $(CYGPATH_W) 'common/monitor.c'; else $(CYGPATH_W) '$(srcdir)/common/monitor.c'; fi` ssl_so-ssl_auth.o: auth/ssl_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssl_so_CFLAGS) $(CFLAGS) -MT ssl_so-ssl_auth.o -MD -MP -MF $(DEPDIR)/ssl_so-ssl_auth.Tpo -c -o ssl_so-ssl_auth.o `test -f 'auth/ssl_auth.c' || echo '$(srcdir)/'`auth/ssl_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ssl_so-ssl_auth.Tpo $(DEPDIR)/ssl_so-ssl_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/ssl_auth.c' object='ssl_so-ssl_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssl_so_CFLAGS) $(CFLAGS) -c -o ssl_so-ssl_auth.o `test -f 'auth/ssl_auth.c' || echo '$(srcdir)/'`auth/ssl_auth.c ssl_so-ssl_auth.obj: auth/ssl_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssl_so_CFLAGS) $(CFLAGS) -MT ssl_so-ssl_auth.obj -MD -MP -MF $(DEPDIR)/ssl_so-ssl_auth.Tpo -c -o ssl_so-ssl_auth.obj `if test -f 'auth/ssl_auth.c'; then $(CYGPATH_W) 'auth/ssl_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/ssl_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/ssl_so-ssl_auth.Tpo $(DEPDIR)/ssl_so-ssl_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/ssl_auth.c' object='ssl_so-ssl_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ssl_so_CFLAGS) $(CFLAGS) -c -o ssl_so-ssl_auth.obj `if test -f 'auth/ssl_auth.c'; then $(CYGPATH_W) 'auth/ssl_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/ssl_auth.c'; fi` test_so-test_auth.o: auth/test_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_so_CFLAGS) $(CFLAGS) -MT test_so-test_auth.o -MD -MP -MF $(DEPDIR)/test_so-test_auth.Tpo -c -o test_so-test_auth.o `test -f 'auth/test_auth.c' || echo '$(srcdir)/'`auth/test_auth.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_so-test_auth.Tpo $(DEPDIR)/test_so-test_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/test_auth.c' object='test_so-test_auth.o' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_so_CFLAGS) $(CFLAGS) -c -o test_so-test_auth.o `test -f 'auth/test_auth.c' || echo '$(srcdir)/'`auth/test_auth.c test_so-test_auth.obj: auth/test_auth.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_so_CFLAGS) $(CFLAGS) -MT test_so-test_auth.obj -MD -MP -MF $(DEPDIR)/test_so-test_auth.Tpo -c -o test_so-test_auth.obj `if test -f 'auth/test_auth.c'; then $(CYGPATH_W) 'auth/test_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/test_auth.c'; fi` @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/test_so-test_auth.Tpo $(DEPDIR)/test_so-test_auth.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='auth/test_auth.c' object='test_so-test_auth.obj' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(test_so_CFLAGS) $(CFLAGS) -c -o test_so-test_auth.obj `if test -f 'auth/test_auth.c'; then $(CYGPATH_W) 'auth/test_auth.c'; else $(CYGPATH_W) '$(srcdir)/auth/test_auth.c'; fi` ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) tags=; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$tags$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$tags $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && cd $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) $$here distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(SCRIPTS) $(DATA) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(filterdir)" "$(DESTDIR)$(lpdbindir)" "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(filterdir)" "$(DESTDIR)$(sbindir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) @WITHKERBEROS_FALSE@uninstall-local: @WITHPLUGINS_FALSE@uninstall-local: clean: clean-am clean-am: clean-binPROGRAMS clean-filterPROGRAMS clean-generic \ clean-lpdbinPROGRAMS clean-noinstPROGRAMS clean-pluginPROGRAMS \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-filterPROGRAMS install-filterSCRIPTS \ install-lpdbinPROGRAMS install-pluginPROGRAMS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook install-dvi: install-dvi-am install-exec-am: install-binPROGRAMS install-sbinPROGRAMS \ install-sbinSCRIPTS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-filterPROGRAMS \ uninstall-filterSCRIPTS uninstall-local \ uninstall-lpdbinPROGRAMS uninstall-pluginPROGRAMS \ uninstall-sbinPROGRAMS uninstall-sbinSCRIPTS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook .MAKE: install-am install-data-am install-exec-am install-strip \ uninstall-am .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-filterPROGRAMS clean-generic clean-lpdbinPROGRAMS \ clean-noinstPROGRAMS clean-pluginPROGRAMS clean-sbinPROGRAMS \ ctags distclean distclean-compile distclean-generic \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-data-hook install-dvi install-dvi-am \ install-exec install-exec-am install-exec-hook \ install-filterPROGRAMS install-filterSCRIPTS install-html \ install-html-am install-info install-info-am \ install-lpdbinPROGRAMS install-man install-pdf install-pdf-am \ install-pluginPROGRAMS install-ps install-ps-am \ install-sbinPROGRAMS install-sbinSCRIPTS install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-filterPROGRAMS \ uninstall-filterSCRIPTS uninstall-hook uninstall-local \ uninstall-lpdbinPROGRAMS uninstall-pluginPROGRAMS \ uninstall-sbinPROGRAMS uninstall-sbinSCRIPTS # were not even compiled in the old build system # and may have issues hidden before because of static linking: # noinst_PROGRAMS = sserver sclient uninstall-hook: rm -f $(DESTDIR)$(bindir)/lp $(DESTDIR)$(bindir)/cancel @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ rm -f $(DESTDIR)$(plugindir)/kerberos.so $(DESTDIR)$(plugindir)/k5conn.so install-exec-hook: rm -f $(DESTDIR)$(bindir)/lp $(DESTDIR)$(bindir)/cancel ln $(DESTDIR)$(bindir)/lpr $(DESTDIR)$(bindir)/lp ln $(DESTDIR)$(bindir)/lprm $(DESTDIR)$(bindir)/cancel @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ $(mkdir_p) $(DESTDIR)$(plugindir) @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ ln -sf kerberos5.so $(DESTDIR)$(plugindir)/kerberos.so @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ ln -sf kerberos5.so $(DESTDIR)$(plugindir)/k5conn.so @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@uninstall-local: @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ if test -l $(DESTDIR)$(plugindir)/k5conn.so ; then \ @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ rm $(DESTDIR)$(plugindir)/k5conn.so ; fi @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ if test -l $(DESTDIR)$(plugindir)/kerberos.so ; then \ @WITHKERBEROS_TRUE@@WITHPLUGINS_TRUE@ rm $(DESTDIR)$(plugindir)/kerberos.so ; fi # vars.c needs all the defines for defaults. # This only adds them for vars.c, which might need GNU make # if your make does not support it, try to add them to the # global AM_CPPFLAGS vars.$(OBJEXT): AM_CPPFLAGS += $(PATHDEFINES) vars.$(OBJEXT): ../config.h ./lpd.conf: vars.c ../config.h set -e; \ rm -f $@ ; \ $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(PATHDEFINES) -C $(srcdir)/vars.c \ | $(SHELL) ../UTILS/make_lpd_conf '$(VERSION)' '$(LPD_CONF_PATH).local' >> $@ \ || rm $@ %: %.sh Makefile set -e ; \ rm -f $@ ; \ sed \ -e "s,@OPENSSL.,@OPENSSL@," \ -e "s,@SSL_CA_FILE.,@SSL_CA_FILE@," \ -e "s,@SSL_CA_KEY.,@SSL_CA_KEY@," \ -e "s,@SSL_CRL_FILE.,@SSL_CRL_FILE@," \ -e "s,@SSL_SERVER_CERT.,@SSL_SERVER_CERT@," \ -e "s,@SSL_SERVER_PASSWORD_FILE.,@SSL_SERVER_PASSWORD_FILE@," \ -e "s,@SSL_CERTS_DIR.,@SSL_CERTS_DIR@," \ $< >$@ chmod 755 $@ install-data-hook: lpd.conf $(mkinstalldirs) $(DESTDIR)$(configdir) if [ "$(INSTALLCONFIGEXAMPLES)" = "Yes" ] ; then \ $(INSTALL_DATA) lpd.conf $(DESTDIR)$(LPD_CONF_PATH)$(SAMPLESUFFIX) ;\ fi # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lprng-3.8.B/src/auth/0000777000131400013140000000000011531672400011412 500000000000000lprng-3.8.B/src/auth/krb5_auth.c0000644000131400013140000011531611531672131013366 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errorcodes.h" #include "fileopen.h" #include "child.h" #include "getqueue.h" #include "linksupport.h" #include "gethostinfo.h" #include "permission.h" #include "lpd_secure.h" #include "lpd_dispatch.h" #include "user_auth.h" #include "krb5_auth.h" #if defined(KERBEROS) /* * deprecated: krb5_auth_con_initivector, krb5_get_in_tkt_with_keytab * WARNING: the current set of KRB5 support examples are not compatible * with the legacy LPRng use of the KRB utility functions. This means * that sooner or later it will be necessary to severly upgrade LPRng * or to use an older version of Kerberos */ # define KRB5_DEPRECATED 1 # define KRB5_PRIVATE 1 # include # if defined(HAVE_COM_ERR_H) # include # endif # undef FREE_KRB_DATA # if defined(HAVE_KRB5_FREE_DATA_CONTENTS) # define FREE_KRB_DATA(context,data,suffix) krb5_free_data_contents(context,&data); data suffix = 0 # else # if defined(HAVE_KRB5_XFREE) # define FREE_KRB_DATA(context,data,suffix) krb5_xfree(data suffix); data suffix = 0 # else # if !defined(HAVE_KRB_XFREE) # define FREE_KRB_DATA(context,data,suffix) krb_xfree(data suffix); data suffix = 0 # else # error missing krb_xfree value or definition # endif # endif # endif # ifdef HAVE_KRB5_READ_MESSAGE # define read_message krb5_read_message # define write_message krb5_write_message # else static int net_read( int fd, char *buf, int len ) { int remaining = len; while (remaining) { int r; r = read(fd, buf, remaining); if (r <= 0) return (r); remaining -=r; } return (len); } static krb5_error_code read_message( krb5_context context, krb5_pointer fdp, krb5_data *inbuf ) { krb5_int32 len; int len2, ilen; char *buf = NULL; int fd = *( (int *) fdp); if ((len2 = net_read( fd, (char *)&len, 4)) != 4) return((len2 < 0) ? errno : ECONNABORTED); len = ntohl(len); if ((len & (signed) VALID_UINT_BITS) != len) /* Overflow size_t??? */ return ENOMEM; inbuf->length = ilen = (int) len; if (ilen) { /* * We may want to include a sanity check here someday.... */ buf = malloc_or_die( ilen, __FILE__,__LINE__ ); if ((len2 = net_read( fd, buf, ilen)) != ilen) { free(buf); return((len2 < 0) ? errno : ECONNABORTED); } } inbuf->data = buf; return(0); } static int net_write( int fd, const char * buf, int len ) { int written; int total_len = len; while (len >0) { written = write(fd, buf, len); if (written <= 0) return (written); len -= written; } return (total_len); } static krb5_error_code write_message( krb5_context context, krb5_pointer fdp, krb5_data *outbuf ) { krb5_int32 len; int fd = *( (int *) fdp); len = htonl(outbuf->length); if (net_write( fd, (char *)&len, 4) < 0) { return(errno); } if (outbuf->length && (net_write(fd, outbuf->data, outbuf->length) < 0)) { return(errno); } return(0); } # endif /* * server_krb5_auth( * char *keytabfile, server key tab file - /etc/lpr.keytab * char *service, service is usually "lpr" * char *prinicpal, specifically supply principal name * int sock, socket for communications * char *auth, int len authname buffer, max size * char *err, int errlen error message buffer, max size * RETURNS: 0 if successful, non-zero otherwise, error message in err * Note: there is a memory leak if authentication fails, so this * should not be done in the main or non-exiting process */ extern int des_read( krb5_context context, krb5_encrypt_block *eblock, int fd, int transfer_timeout, char *buf, int len, char *err, int errlen ); extern int des_write( krb5_context context, krb5_encrypt_block *eblock, int fd, char *buf, int len, char *err, int errlen ); /* we make these statics */ static krb5_context context = 0; static krb5_auth_context auth_context = 0; static krb5_keytab keytab = 0; /* Allow specification on command line */ static krb5_principal server = 0; static krb5_ticket * ticket = 0; static int server_krb5_auth( char *keytabfile, char *service, char *server_principal, int sock, char **auth, char *err, int errlen, char *file, int use_crypt_transfer ) { int retval = 0; int fd = -1; krb5_data inbuf, outbuf; struct stat statb; int status; char *cname = 0; DEBUG1("server_krb5_auth: keytab '%s', service '%s', principal '%s', sock %d, file '%s'", keytabfile, service, server_principal, sock, file ); if( !keytabfile ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "no server keytab file", Is_server?"on server":"on client" ); retval = 1; goto done; } if( (fd = Checkread(keytabfile,&statb)) == -1 ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "cannot open server keytab file '%s' - %s", Is_server?"on server":"on client", keytabfile, Errormsg(errno) ); retval = 1; goto done; } close(fd); err[0] = 0; if ((retval = krb5_init_context(&context))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_init_context failed - '%s' ", Is_server?"on server":"on client", error_message(retval) ); goto done; } if( keytab == 0 && (retval = krb5_kt_resolve(context, keytabfile, &keytab) ) ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_kt_resolve failed - file %s '%s'", Is_server?"on server":"on client", keytabfile, error_message(retval) ); goto done; } if(server_principal){ if ((retval = krb5_parse_name(context,server_principal, &server))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "when parsing name '%s'" " - %s", Is_server?"on server":"on client", server_principal, error_message(retval) ); goto done; } } else { if ((retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &server))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_sname_to_principal failed - service %s '%s'", Is_server?"on server":"on client", service, error_message(retval)); goto done; } } if((retval = krb5_unparse_name(context, server, &cname))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_unparse_name failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } DEBUG1("server_krb5_auth: server '%s'", cname ); if((retval = krb5_recvauth(context, &auth_context, (krb5_pointer)&sock, service , server, 0, /* no flags */ keytab, /* default keytab is NULL */ &ticket))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_recvauth '%s' failed '%s'", Is_server?"on server":"on client", cname, error_message(retval)); goto done; } /* Get client name */ if((retval = krb5_unparse_name(context, ticket->enc_part2->client, &cname))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_unparse_name failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } if( auth ) *auth = safestrdup( cname,__FILE__,__LINE__); DEBUG1( "server_krb5_auth: client '%s'", cname ); /* initialize the initial vector */ if((retval = krb5_auth_con_initivector(context, auth_context))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_auth_con_initvector failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); if((retval = krb5_auth_con_genaddrs(context, auth_context, sock, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_auth_con_genaddr failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } memset( &inbuf, 0, sizeof(inbuf) ); memset( &outbuf, 0, sizeof(outbuf) ); fd = Checkwrite( file, &statb, O_WRONLY|O_TRUNC, 1, 0 ); DEBUG1( "server_krb5_auth: opened for write '%s', fd %d", file, fd ); if( fd < 0 ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "file open failed: %s", Is_server?"on server":"on client", Errormsg(errno)); retval = 1; goto done; } if( use_crypt_transfer ) { while( (retval = read_message(context,&sock,&inbuf)) == 0 ){ if(DEBUGL5){ char small[16]; memcpy(small,inbuf.data,sizeof(small)-1); small[sizeof(small)-1] = 0; LOGDEBUG( "server_krb5_auth: got %d, '%s'", inbuf.length, small ); } if((retval = krb5_rd_priv(context,auth_context, &inbuf,&outbuf,NULL))){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "krb5_rd_priv failed: %s", Is_server?"on server":"on client", error_message(retval)); retval = 1; goto done; } status = Write_fd_len( fd, outbuf.data, outbuf.length ); if( status < 0 ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "write to file failed: %s", Is_server?"on server":"on client", Errormsg(errno)); retval = 1; goto done; } FREE_KRB_DATA(context,inbuf,.data); FREE_KRB_DATA(context,outbuf,.data); inbuf.length = 0; outbuf.length = 0; } } else { char buffer[SMALLBUFFER]; while( (retval = ok_read( sock, buffer, sizeof(buffer))) > 0 ){ if( Write_fd_len( fd, buffer, retval ) < 0 ){ plp_snprintf( err, errlen, "%s server_krb5_auth failed - " "write to file failed: %s", Is_server?"on server":"on client", Errormsg(errno)); retval = 1; goto done; } } } close(fd); fd = -1; retval = 0; done: if( cname ) free(cname); cname = 0; if( retval ){ if( fd >= 0 ) close(fd); if( ticket ) krb5_free_ticket(context, ticket); ticket = 0; if( context && server ) krb5_free_principal(context, server); server = 0; if( context && auth_context) krb5_auth_con_free(context, auth_context ); auth_context = 0; if( context ) krb5_free_context(context); context = 0; } DEBUG1( "server_krb5_auth: retval %d, error: '%s'", retval, err ); return(retval); } static int server_krb5_status( int sock, char *err, int errlen, char *file, int use_crypt_transfer ) { int fd = -1; int retval = 0; struct stat statb; char buffer[SMALLBUFFER]; krb5_data inbuf, outbuf; err[0] = 0; memset( &inbuf, 0, sizeof(inbuf) ); memset( &outbuf, 0, sizeof(outbuf) ); fd = Checkread( file, &statb ); if( fd < 0 ){ plp_snprintf( err, errlen, "file open failed: %s", Errormsg(errno)); retval = 1; goto done; } DEBUG1( "server_krb5_status: sock '%d', file size %0.0f", sock, (double)(statb.st_size)); while( (retval = ok_read( fd,buffer,sizeof(buffer)-1)) > 0 ){ if( use_crypt_transfer ) { inbuf.length = retval; inbuf.data = buffer; buffer[retval] = 0; DEBUG4("server_krb5_status: sending '%s'", buffer ); if((retval = krb5_mk_priv(context,auth_context, &inbuf,&outbuf,NULL))){ plp_snprintf( err, errlen, "%s server_krb5_status failed - " "krb5_mk_priv failed: %s", Is_server?"on server":"on client", error_message(retval)); retval = 1; goto done; } DEBUG4("server_krb5_status: encoded length '%d'", outbuf.length ); if((retval= write_message(context,&sock,&outbuf))){ plp_snprintf( err, errlen, "%s server_krb5_status failed - " "write_message failed: %s", Is_server?"on server":"on client", error_message(retval)); retval = 1; goto done; } FREE_KRB_DATA(context,outbuf,.data); memset((char *)&outbuf, 0, sizeof(outbuf)); } else { if( Write_fd_len( sock, buffer, retval ) < 0 ){ plp_snprintf( err, errlen, "%s server_krb5_status failed - " "write_message failed: %s", Is_server?"on server":"on client", Errormsg(errno)); retval = 1; goto done; } } } DEBUG1("server_krb5_status: done" ); done: if( fd >= 0 ) close(fd); if( ticket ) krb5_free_ticket(context, ticket); ticket = 0; if( context && server ) krb5_free_principal(context, server); server = 0; if( context && auth_context) krb5_auth_con_free(context, auth_context ); auth_context = 0; if( context ) krb5_free_context(context); context = 0; DEBUG1( "server_krb5_status: retval %d, error: '%s'", retval, err ); return(retval); } /* * client_krb5_auth( * char * keytabfile - keytabfile, NULL for users, file name for server * char * service -service, usually "lpr" * char * host - server host name * char * principal - server principal * int options - options for server to server * char *life - lifetime of ticket * char *renew_time - renewal time of ticket * char *err, int errlen - buffer for error messages * char *file - file to transfer * int use_crypt_transfer - transfer using encryption */ # define KRB5_DEFAULT_OPTIONS 0 # define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ # define VALIDATE 0 # define RENEW 1 extern krb5_error_code krb5_tgt_gen( krb5_context context, krb5_ccache ccache, krb5_principal server, krb5_data *outbuf, int opt ); static int client_krb5_auth( char *keytabfile, char *service, char *host, char *server_principal, int options, char *life, char *renew_time, int sock, char *err, int errlen, char *file, int use_crypt_transfer ) { krb5_context context = 0; krb5_principal client = 0, server = 0; krb5_error *err_ret = 0; krb5_ap_rep_enc_part *rep_ret = 0; krb5_data cksum_data; krb5_ccache ccdef; krb5_auth_context auth_context = 0; krb5_timestamp now; krb5_deltat lifetime = KRB5_DEFAULT_LIFE; /* -l option */ krb5_creds my_creds; krb5_creds *out_creds = 0; krb5_keytab keytab = 0; krb5_deltat rlife = 0; krb5_address **addrs = (krb5_address **)0; krb5_encrypt_block eblock; /* eblock for encrypt/decrypt */ krb5_data inbuf, outbuf; int retval = 0; char *cname = 0; char *sname = 0; int fd = -1, len; char buffer[SMALLBUFFER]; struct stat statb; err[0] = 0; DEBUG1( "client_krb5_auth: euid/egid %d/%d, ruid/rguid %d/%d, keytab '%s'," " service '%s', host '%s', sock %d, file '%s'", geteuid(),getegid(), getuid(),getgid(), keytabfile, service, host, sock, file ); if( !safestrcasecmp(host,LOCALHOST) ){ host = FQDNHost_FQDN; } memset((char *)&my_creds, 0, sizeof(my_creds)); memset((char *)&outbuf, 0, sizeof(outbuf)); memset((char *)&eblock, 0, sizeof(eblock)); options |= KRB5_DEFAULT_OPTIONS; if ((retval = krb5_init_context(&context))){ plp_snprintf( err, errlen, "%s krb5_init_context failed - '%s' ", Is_server?"on server":"on client", error_message(retval) ); goto done; } #if 0 if (!valid_cksumtype(CKSUMTYPE_CRC32)) { plp_snprintf( err, errlen, "valid_cksumtype CKSUMTYPE_CRC32 - %s", error_message(KRB5_PROG_SUMTYPE_NOSUPP) ); retval = 1; goto done; } #endif DEBUG1( "client_krb5_auth: using host='%s', server_principal '%s'", host, server_principal ); if(server_principal){ if ((retval = krb5_parse_name(context,server_principal, &server))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "when parsing name '%s'" " - %s", Is_server?"on server":"on client", server_principal, error_message(retval) ); goto done; } } else { /* XXX perhaps we want a better metric for determining localhost? */ if (strncasecmp("localhost", host, sizeof(host))) retval = krb5_sname_to_principal(context, host, service, KRB5_NT_SRV_HST, &server); else /* Let libkrb5 figure out its notion of the local host */ retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &server); if (retval) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "when parsing service/host '%s'/'%s'" " - %s", Is_server?"on server":"on client", service,host,error_message(retval) ); goto done; } } if((retval = krb5_unparse_name(context, server, &sname))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " " krb5_unparse_name of 'server' failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } DEBUG1( "client_krb5_auth: server '%s'", sname ); my_creds.server = server; if( keytabfile ){ if ((retval = krb5_sname_to_principal(context, NULL, service, KRB5_NT_SRV_HST, &client))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "when parsing name '%s'" " - %s", Is_server?"on server":"on client", service, error_message(retval) ); goto done; } if(cname)free(cname); cname = 0; if((retval = krb5_unparse_name(context, client, &cname))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_unparse_name of 'me' failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } DEBUG1("client_krb5_auth: client '%s'", cname ); my_creds.client = client; if((retval = krb5_kt_resolve(context, keytabfile, &keytab))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "resolving keytab '%s'" " '%s' - ", Is_server?"on server":"on client", keytabfile, error_message(retval) ); goto done; } if ((retval = krb5_timeofday(context, &now))) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "getting time of day" " - '%s'", Is_server?"on server":"on client", error_message(retval) ); goto done; } if( life && (retval = krb5_string_to_deltat(life, &lifetime)) ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "bad lifetime value '%s'" " '%s' - ", Is_server?"on server":"on client", life, error_message(retval) ); goto done; } if( renew_time ){ options |= KDC_OPT_RENEWABLE; if( (retval = krb5_string_to_deltat(renew_time, &rlife))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "bad renew time value '%s'" " '%s' - ", Is_server?"on server":"on client", renew_time, error_message(retval) ); goto done; } } if((retval = krb5_cc_default(context, &ccdef))) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "while getting default ccache" " - %s", Is_server?"on server":"on client", error_message(retval) ); goto done; } my_creds.times.starttime = 0; /* start timer when request */ my_creds.times.endtime = now + lifetime; if(options & KDC_OPT_RENEWABLE) { my_creds.times.renew_till = now + rlife; } else { my_creds.times.renew_till = 0; } if(options & KDC_OPT_VALIDATE){ /* stripped down version of krb5_mk_req */ if( (retval = krb5_tgt_gen(context, ccdef, server, &outbuf, VALIDATE))) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "validating tgt" " - %s", Is_server?"on server":"on client", error_message(retval) ); DEBUG1("%s", err ); } } if (options & KDC_OPT_RENEW) { /* stripped down version of krb5_mk_req */ if( (retval = krb5_tgt_gen(context, ccdef, server, &outbuf, RENEW))) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "renewing tgt" " - %s", Is_server?"on server":"on client", error_message(retval) ); DEBUG1("%s", err ); } } if((retval = krb5_get_in_tkt_with_keytab(context, options, addrs, 0, 0, keytab, 0, &my_creds, 0))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "while getting initial credentials" " - %s", Is_server?"on server":"on client", error_message(retval) ); goto done; } /* update the credentials */ if( (retval = krb5_cc_initialize (context, ccdef, client)) ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "when initializing cache" " - %s", Is_server?"on server":"on client", error_message(retval) ); goto done; } if( (retval = krb5_cc_store_cred(context, ccdef, &my_creds))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "while storing credentials" " - %s", Is_server?"on server":"on client", error_message(retval) ); goto done; } } else { /* we set RUID to user */ if( Is_server ){ To_ruid( DaemonUID ); } else { To_ruid( OriginalRUID ); } if((retval = krb5_cc_default(context, &ccdef))){ plp_snprintf( err, errlen, "%s krb5_cc_default failed - %s", Is_server?"on server":"on client", error_message( retval ) ); goto done; } if((retval = krb5_cc_get_principal(context, ccdef, &client))){ plp_snprintf( err, errlen, "%s krb5_cc_get_principal failed - %s", Is_server?"on server":"on client", error_message( retval ) ); goto done; } if( Is_server ){ To_daemon(); } else { To_user(); } if(cname)free(cname); cname = 0; if((retval = krb5_unparse_name(context, client, &cname))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_unparse_name of 'me' failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } DEBUG1( "client_krb5_auth: client '%s'", cname ); my_creds.client = client; } cksum_data.data = host; cksum_data.length = safestrlen(host); if((retval = krb5_auth_con_init(context, &auth_context))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_auth_con_init failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } if((retval = krb5_auth_con_genaddrs(context, auth_context, sock, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR | KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_auth_con_genaddr failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } retval = krb5_sendauth(context, &auth_context, (krb5_pointer) &sock, service, client, server, AP_OPTS_MUTUAL_REQUIRED, &cksum_data, &my_creds, ccdef, &err_ret, &rep_ret, &out_creds); if (retval){ if( err_ret == 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_sendauth failed - %s", Is_server?"on server":"on client", error_message( retval ) ); } else { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_sendauth - mutual authentication failed - %*s", Is_server?"on server":"on client", err_ret->text.length, err_ret->text.data); } goto done; } else if (rep_ret == 0) { plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_sendauth - did not do mutual authentication", Is_server?"on server":"on client" ); retval = 1; goto done; } else { DEBUG1("client_krb5_auth: sequence number %d", rep_ret->seq_number ); } /* initialize the initial vector */ if((retval = krb5_auth_con_initivector(context, auth_context))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_auth_con_initvector failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } krb5_auth_con_setflags(context, auth_context, KRB5_AUTH_CONTEXT_DO_SEQUENCE); memset( &inbuf, 0, sizeof(inbuf) ); memset( &outbuf, 0, sizeof(outbuf) ); fd = Checkread( file, &statb ); if( fd < 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth: could not open for reading '%s' - '%s'", Is_server?"on server":"on client", file, Errormsg(errno) ); retval = 1; goto done; } DEBUG1( "client_krb5_auth: opened for read %s, fd %d, size %0.0f", file, fd, (double)statb.st_size ); while( (len = ok_read( fd, buffer, sizeof(buffer)-1 )) > 0 ){ if( use_crypt_transfer ){ inbuf.data = buffer; inbuf.length = len; if((retval = krb5_mk_priv(context, auth_context, &inbuf, &outbuf, NULL))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_mk_priv failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } if((retval = write_message(context, (void *)&sock, &outbuf))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "write_message failed: %s", Is_server?"on server":"on client", error_message(retval)); goto done; } DEBUG4( "client_krb5_auth: freeing data"); FREE_KRB_DATA(context,outbuf,.data); } else { if(Write_fd_len(sock, buffer,len) < 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "write_message failed: %s", Is_server?"on server":"on client", Errormsg(errno)); goto done; } } } if( len < 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "client_krb5_auth: file read failed '%s' - '%s'", file, Is_server?"on server":"on client", Errormsg(errno) ); retval = 1; goto done; } close(fd); fd = -1; DEBUG1( "client_krb5_auth: file copy finished %s", file ); if( shutdown(sock, 1) == -1 ){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "shutdown failed '%s'", Is_server?"on server":"on client", Errormsg(errno) ); retval = 1; goto done; } fd = Checkwrite( file, &statb, O_WRONLY|O_TRUNC, 1, 0 ); if( fd < 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth: could not open for writing '%s' - '%s'", Is_server?"on server":"on client", file, Errormsg(errno) ); retval = 1; goto done; } if( use_crypt_transfer ){ while((retval = read_message( context,&sock,&inbuf))==0){ if((retval = krb5_rd_priv(context, auth_context, &inbuf, &outbuf, NULL))){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "krb5_rd_priv failed - %s", Is_server?"on server":"on client", Errormsg(errno) ); retval = 1; goto done; } if(Write_fd_len(fd,outbuf.data,outbuf.length) < 0){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "write to '%s' failed - %s", Is_server?"on server":"on client", file, Errormsg(errno) ); retval = 1; goto done; } FREE_KRB_DATA(context,inbuf,.data); FREE_KRB_DATA(context,outbuf,.data); } } else { while( (retval = ok_read( sock, buffer, sizeof(buffer))) > 0 ){ if(Write_fd_len(fd,buffer,retval) < 0){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "write to '%s' failed - %s", Is_server?"on server":"on client", file, Errormsg(errno) ); retval = 1; goto done; } } } close(fd); fd = -1; fd = Checkread( file, &statb ); err[0] = 0; if( fd < 0 ){ plp_snprintf( err, errlen, "%s client_krb5_auth: could not open for reading '%s' - '%s'", Is_server?"on server":"on client", file, Errormsg(errno) ); retval = 1; goto done; } DEBUG1( "client_krb5_auth: reopened for read %s, fd %d, size %0.0f", file, fd, (double)statb.st_size ); if( dup2(fd,sock) == -1){ plp_snprintf( err, errlen, "%s client_krb5_auth failed - " "dup2(%d,%d) failed - '%s'", Is_server?"on server":"on client", fd, sock, Errormsg(errno) ); } retval = 0; done: if( fd >= 0 && fd != sock ) close(fd); DEBUG4( "client_krb5_auth: freeing my_creds"); krb5_free_cred_contents( context, &my_creds ); DEBUG4( "client_krb5_auth: freeing rep_ret"); if( rep_ret ) krb5_free_ap_rep_enc_part( context, rep_ret ); rep_ret = 0; DEBUG4( "client_krb5_auth: freeing err_ret"); if( err_ret ) krb5_free_error( context, err_ret ); err_ret = 0; DEBUG4( "client_krb5_auth: freeing auth_context"); if( auth_context) krb5_auth_con_free(context, auth_context ); auth_context = 0; DEBUG4( "client_krb5_auth: freeing context"); if( context ) krb5_free_context(context); context = 0; DEBUG1( "client_krb5_auth: retval %d, error '%s'",retval, err ); return(retval); } #if 0 /* * remote_principal_krb5( * char * service -service, usually "lpr" * char * host - server host name * char *buffer, int bufferlen - buffer for credentials * get the principal name of the remote service */ static int remote_principal_krb5( char *service, char *host, char *err, int errlen ) { krb5_context context = 0; krb5_principal server = 0; int retval = 0; char *cname = 0; DEBUG1("remote_principal_krb5: service '%s', host '%s'", service, host ); if ((retval = krb5_init_context(&context))){ plp_snprintf( err, errlen, "%s '%s'", "krb5_init_context failed - '%s' ", error_message(retval) ); goto done; } if((retval = krb5_sname_to_principal(context, host, service, KRB5_NT_SRV_HST, &server))){ plp_snprintf( err, errlen, "krb5_sname_to_principal %s/%s failed - %s", service, host, error_message(retval) ); goto done; } if((retval = krb5_unparse_name(context, server, &cname))){ plp_snprintf( err, errlen, "krb5_unparse_name failed - %s", error_message(retval)); goto done; } strncpy( err, cname, errlen ); done: if( cname ) free(cname); cname = 0; if( server ) krb5_free_principal(context, server); server = 0; if( context ) krb5_free_context(context); context = 0; DEBUG1( "remote_principal_krb5: retval %d, result: '%s'",retval, err ); return(retval); } #endif /* * Initialize a credentials cache. */ # define KRB5_DEFAULT_OPTIONS 0 # define KRB5_DEFAULT_LIFE 60*60*10 /* 10 hours */ # define VALIDATE 0 # define RENEW 1 /* stripped down version of krb5_mk_req */ krb5_error_code krb5_tgt_gen( krb5_context context, krb5_ccache ccache, krb5_principal server, krb5_data *outbuf, int opt ) { krb5_error_code retval; krb5_creds * credsp; krb5_creds creds; /* obtain ticket & session key */ memset((char *)&creds, 0, sizeof(creds)); if ((retval = krb5_copy_principal(context, server, &creds.server))) goto cleanup; if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) goto cleanup_creds; if(opt == VALIDATE) { if ((retval = krb5_get_credentials_validate(context, 0, ccache, &creds, &credsp))) goto cleanup_creds; } else { if ((retval = krb5_get_credentials_renew(context, 0, ccache, &creds, &credsp))) goto cleanup_creds; } /* we don't actually need to do the mk_req, just get the creds. */ cleanup_creds: krb5_free_cred_contents(context, &creds); cleanup: return retval; } char *storage; int nstored = 0; char *store_ptr; krb5_data desinbuf,desoutbuf; # define ENCBUFFERSIZE 2*LARGEBUFFER int des_read( krb5_context context, krb5_encrypt_block *eblock, int fd, int transfer_timeout, char *buf, int len, char *err, int errlen ) { int nreturned = 0; long net_len,rd_len; int cc; unsigned char len_buf[4]; if( len <= 0 ) return(len); if( desinbuf.data == 0 ){ desinbuf.data = malloc_or_die( ENCBUFFERSIZE, __FILE__,__LINE__ ); storage = malloc_or_die( ENCBUFFERSIZE, __FILE__,__LINE__ ); } if (nstored >= len) { memcpy(buf, store_ptr, len); store_ptr += len; nstored -= len; return(len); } else if (nstored) { memcpy(buf, store_ptr, nstored); nreturned += nstored; buf += nstored; len -= nstored; nstored = 0; } if ((cc = Read_fd_len_timeout(transfer_timeout, fd, (char*)len_buf, 4)) != 4) { /* XXX can't read enough, pipe must have closed */ return(0); } rd_len = ((len_buf[0]<<24) | (len_buf[1]<<16) | (len_buf[2]<<8) | len_buf[3]); net_len = krb5_encrypt_size(rd_len,eblock->crypto_entry); if ((net_len <= 0) || (net_len > ENCBUFFERSIZE )) { /* preposterous length; assume out-of-sync; only recourse is to close connection, so return 0 */ plp_snprintf( err, errlen, "des_read: " "read size problem"); return(-1); } if ((cc = Read_fd_len_timeout( transfer_timeout, fd, desinbuf.data, net_len)) != net_len) { /* pipe must have closed, return 0 */ plp_snprintf( err, errlen, "des_read: " "Read error: length received %d != expected %d.", (int)cc, (int)net_len); return(-1); } /* decrypt info */ if((cc = krb5_decrypt(context, desinbuf.data, (krb5_pointer) storage, net_len, eblock, 0))){ plp_snprintf( err, errlen, "des_read: " "Cannot decrypt data from network - %s", error_message(cc) ); return(-1); } store_ptr = storage; nstored = rd_len; if (nstored > len) { memcpy(buf, store_ptr, len); nreturned += len; store_ptr += len; nstored -= len; } else { memcpy(buf, store_ptr, nstored); nreturned += nstored; nstored = 0; } return(nreturned); } int des_write( krb5_context context, krb5_encrypt_block *eblock, int fd, char *buf, int len, char *err, int errlen ) { char len_buf[4]; int cc; if( len <= 0 ) return( len ); if( desoutbuf.data == 0 ){ desoutbuf.data = malloc_or_die( ENCBUFFERSIZE, __FILE__,__LINE__ ); } desoutbuf.length = krb5_encrypt_size(len, eblock->crypto_entry); if (desoutbuf.length > ENCBUFFERSIZE ){ plp_snprintf( err, errlen, "des_write: " "Write size problem - wanted %d", desoutbuf.length); return(-1); } if ((cc=krb5_encrypt(context, (krb5_pointer)buf, desoutbuf.data, len, eblock, 0))){ plp_snprintf( err, errlen, "des_write: " "Write encrypt problem. - %s", error_message(cc)); return(-1); } len_buf[0] = (len & 0xff000000) >> 24; len_buf[1] = (len & 0xff0000) >> 16; len_buf[2] = (len & 0xff00) >> 8; len_buf[3] = (len & 0xff); if( Write_fd_len(fd, len_buf, 4) < 0 ){ plp_snprintf( err, errlen, "des_write: " "Could not write len_buf - %s", Errormsg( errno )); return(-1); } if(Write_fd_len(fd, desoutbuf.data,desoutbuf.length) < 0 ){ plp_snprintf( err, errlen, "des_write: " "Could not write data - %s", Errormsg(errno)); return(-1); } else return(len); } static int Krb5_receive_work( int *sock, int transfer_timeout, char *user, char *jobsize, int from_server, char *authtype, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security, char *tempfile, SECURE_WORKER_PROC do_secure_work, int use_crypt_transfer) { int status = 0; char *from = 0; char *keytab = 0; char *service = 0; char *principal = 0; errmsg[0] = 0; DEBUG1("Krb5_receive_work: tempfile '%s', use_crypt_transfer %d", tempfile, use_crypt_transfer ); keytab = Find_str_value(info,"keytab"); service = Find_str_value(info,"service"); if( !(principal = Find_str_value(info,"server_principal")) ){ principal = Find_str_value(info,"id"); } if( Write_fd_len( *sock, "", 1 ) < 0 ){ status = JABORT; plp_snprintf( errmsg, errlen, "Krb5_receive_work: ACK 0 write errmsg - %s", Errormsg(errno) ); } else if( (status = server_krb5_auth( keytab, service, principal, *sock, &from, errmsg, errlen, tempfile, use_crypt_transfer )) ){ if( errmsg[0] == 0 ){ plp_snprintf( errmsg, errlen, "Krb5_receive_work: server_krb5_auth failed - no reason given" ); } } else { DEBUGF(DRECV1)("Krb5_receive_work: from '%s'", from ); Set_str_value( header_info, FROM, from ); status = do_secure_work( jobsize, from_server, tempfile, header_info ); if( server_krb5_status( *sock, errmsg, errlen, tempfile, use_crypt_transfer ) ){ plp_snprintf( errmsg, errlen, "Krb5_receive_work: status send failed - '%s'", errmsg ); } } #if 0 if( *errmsg ){ logmsg(LOG_INFO, "%s", errmsg ); } #endif if( from ) free(from); from = 0; return(status); } static int Krb5_receive( int *sock, int transfer_timeout, char *user, char *jobsize, int from_server, char *authtype, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security, char *tempfile, SECURE_WORKER_PROC do_secure_work) { DEBUG1("Krb5_receive: starting"); return Krb5_receive_work( sock, transfer_timeout, user, jobsize, from_server, authtype, info, errmsg, errlen, header_info, security, tempfile, do_secure_work, 1 ); } static int Krb5_receive_nocrypt( int *sock, int transfer_timeout, char *user, char *jobsize, int from_server, char *authtype, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security, char *tempfile, SECURE_WORKER_PROC do_secure_work) { DEBUG1("Krb5_receive_nocrypt: starting"); return Krb5_receive_work( sock, transfer_timeout, user, jobsize, from_server, authtype, info, errmsg, errlen, header_info, security, tempfile, do_secure_work, 0 ); } /* * * The following routines simply implement the encryption and transfer of * the files and/or values * * By default, when sending a command, the file will contain: * key=value lines. * KEY PURPOSE * client client or user name * from originator - server if forwarding, client otherwise * command command to send * */ static int Krb5_send_work( int *sock, int transfer_timeout, char *tempfile, char *error, int errlen, const struct security *security, struct line_list *info, int use_crypt_transfer ) { char *keyfile = 0; int status = 0, fd = -1; struct stat statb; char *principal = 0; char *service = 0; char *life, *renew; DEBUG1("Krb5_send_work: tempfile '%s', use_crypt_transfer %d", tempfile, use_crypt_transfer ); life = renew = 0; if( Is_server ){ if( !(keyfile = Find_str_value(info,"keytab")) ){ plp_snprintf( error, errlen, "no server keytab file" ); status = JFAIL; goto error; } DEBUG1("Krb5_send_work: keyfile '%s'", keyfile ); if( (fd = Checkread(keyfile,&statb)) == -1 ){ plp_snprintf( error, errlen, "cannot open server keytab file - %s", Errormsg(errno) ); status = JFAIL; goto error; } close(fd); principal = Find_str_value(info,"forward_principal"); } else { if( !(principal = Find_str_value(info,"server_principal")) ){ principal = Find_str_value(info,"id"); } } service = Find_str_value(info, "service" ); life = Find_str_value(info, "life"); renew = Find_str_value(info, "renew" ); status= client_krb5_auth( keyfile, service, RemoteHost_DYN, /* remote host */ principal, /* principle name of the remote server */ 0, /* options */ life, /* lifetime of server ticket */ renew, /* renewable time of server ticket */ *sock, error, errlen, tempfile, use_crypt_transfer ); DEBUG1("Krb5_send_work: client_krb5_auth returned '%d' - error '%s'", status, error ); if( status && error[0] == 0 ){ plp_snprintf( error, errlen, "krb5 authenticated transfer to remote host failed"); } #if 0 if( error[0] ){ DEBUG2("Krb5_send_work: writing error to file '%s'", error ); if( safestrlen(error) < errlen-2 ){ memmove( error+1, error, safestrlen(error)+1 ); error[0] = ' '; } if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ plp_snprintf(error,errlen, "Krb5_send_work: open '%s' for write failed - %s", tempfile, Errormsg(errno)); } Write_fd_str(fd,error); close( fd ); fd = -1; error[0] = 0; } #endif error: return(status); } static int Krb5_send( int *sock, int transfer_timeout, char *tempfile, char *error, int errlen, const struct security *security, struct line_list *info ) { return Krb5_send_work( sock, transfer_timeout, tempfile, error, errlen, security, info, 1 ); } static int Krb5_send_nocrypt( int *sock, int transfer_timeout, char *tempfile, char *error, int errlen, const struct security *security, struct line_list *info ) { return Krb5_send_work( sock, transfer_timeout, tempfile, error, errlen, security, info, 0 ); } const struct security kerberos5_auth = { "kerberos*", "kerberos", "kerberos", IP_SOCKET_ONLY, 0, Krb5_send, 0, Krb5_receive }; const struct security k5conn_auth = { "k5conn", "k5conn", "kerberos", IP_SOCKET_ONLY, 0, Krb5_send_nocrypt, 0, Krb5_receive_nocrypt }; #ifdef WITHPLUGINS plugin_get_func getter_name(kerberos5); size_t getter_name(kerberos5)(const struct security **s, size_t max) { if( max > 0 ) s[0] = &kerberos5_auth; if( max > 1 ) s[1] = &k5conn_auth; return 2; } #endif #endif lprng-3.8.B/src/auth/test_auth.c0000644000131400013140000001774111531672131013505 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-1999, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #include "lp.h" #include "user_auth.h" #include "krb5_auth.h" #include "errorcodes.h" #include "fileopen.h" #include "linksupport.h" #include "child.h" #include "getqueue.h" #include "lpd_secure.h" #include "lpd_dispatch.h" #include "permission.h" #if 0 /* Test_connect: send the validation information expect to get back NULL or error message */ static int Test_connect( struct job *job UNUSED, int *sock, int transfer_timeout, char *errmsg, int errlen, struct security *security UNUSED, struct line_list *info ) { const char *secure = "TEST\n"; int status = 0, ack = 0; if(DEBUGL1)Dump_line_list("Test_connect: info", info ); DEBUG3("Test_connect: sending '%s'", secure); status = Link_send( RemoteHost_DYN, sock, transfer_timeout, secure, safestrlen(secure), &ack ); DEBUG3("Test_connect: status '%s'", Link_err_str(status) ); if( status ){ plp_snprintf(errmsg, errlen, "Test_connect: error '%s'", Link_err_str(status) ); status = JFAIL; } if( ack ){ plp_snprintf(errmsg, errlen, "Test_connect: ack '%d'", ack ); status = JFAIL; } return( status ); } static int Test_accept( int *sock, int transfer_timeout, char *user UNUSED, char *jobsize UNUSED, int from_server UNUSED, char *authtype UNUSED, char *errmsg, int errlen, struct line_list *info, struct line_list *header_info, struct security *security UNUSED) { int status, len; char input[SMALLBUFFER]; DEBUGFC(DRECV1)Dump_line_list("Test_accept: info", info ); DEBUGFC(DRECV1)Dump_line_list("Test_accept: header_info", header_info ); len = sizeof(input)-1; status = Link_line_read(ShortRemote_FQDN,sock, transfer_timeout,input,&len); if( len >= 0 ) input[len] = 0; if( status ){ plp_snprintf(errmsg,errlen, "error '%s' READ from %s@%s", Link_err_str(status), RemotePrinter_DYN, RemoteHost_DYN ); goto error; } DEBUG1( "Test_accept: read status %d, len %d, '%s'", status, len, input ); if( (status = Link_send( RemoteHost_DYN, sock, transfer_timeout, "", 1, 0 )) ){ plp_snprintf(errmsg,errlen, "error '%s' ACK to %s@%s", Link_err_str(status), RemotePrinter_DYN, RemoteHost_DYN ); goto error; } DEBUG1( "Test_accept: ACK sent"); error: return( status ); } #endif /************************************************************** *Test_send: *A simple implementation for testing user supplied authentication * * Simply send the authentication information to the remote end * destination=test <- destination ID (URL encoded) * (destination ID from above) * server=test <- if originating from server, the server key (URL encoded) * (originator ID from above) * client=papowell <- client id * (client ID from above) * input=%04t1 <- input that is * **************************************************************/ static int Test_send( int *sock, int transfer_timeout, char *tempfile, char *errmsg, int errlen, const struct security *security UNUSED, struct line_list *info ) { char buffer[LARGEBUFFER]; struct stat statb; int tempfd, len; int status = 0; if(DEBUGL1)Dump_line_list("Test_send: info", info ); DEBUG1("Test_send: sending on socket %d", *sock ); if( (tempfd = Checkread(tempfile,&statb)) < 0){ plp_snprintf(errmsg, errlen, "Test_send: open '%s' for read failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } DEBUG1("Test_send: starting read"); while( (len = Read_fd_len_timeout( transfer_timeout, tempfd, buffer, sizeof(buffer)-1 )) > 0 ){ buffer[len] = 0; DEBUG4("Test_send: file information '%s'", buffer ); if( write( *sock, buffer, len) != len ){ plp_snprintf(errmsg, errlen, "Test_send: write to socket failed - %s", Errormsg(errno) ); status = JABORT; goto error; } } if( len < 0 ){ plp_snprintf(errmsg, errlen, "Test_send: read from '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } close(tempfd); tempfd = -1; /* we close the writing side */ shutdown( *sock, 1 ); DEBUG1("Test_send: sent file" ); if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ plp_snprintf(errmsg, errlen, "Test_send: open '%s' for write failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } DEBUG1("Test_send: starting read"); while( (len = Read_fd_len_timeout(transfer_timeout, *sock,buffer,sizeof(buffer)-1)) > 0 ){ buffer[len] = 0; DEBUG4("Test_send: socket information '%s'", buffer); if( write(tempfd,buffer,len) != len ){ plp_snprintf(errmsg, errlen, "Test_send: write to '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } } close( tempfd ); tempfd = -1; error: return(status); } static int Test_receive( int *sock, int transfer_timeout, char *user UNUSED, char *jobsize, int from_server, char *authtype UNUSED, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security UNUSED, char *tempfile, SECURE_WORKER_PROC do_secure_work) { int tempfd, status, n; char buffer[LARGEBUFFER]; struct stat statb; tempfd = -1; DEBUGFC(DRECV1)Dump_line_list("Test_receive: info", info ); DEBUGFC(DRECV1)Dump_line_list("Test_receive: header_info", header_info ); /* do validation and then write 0 */ if( Write_fd_len( *sock, "", 1 ) < 0 ){ status = JABORT; plp_snprintf( errmsg, errlen, "Test_receive: ACK 0 write error - %s", Errormsg(errno) ); goto error; } /* open a file for the output */ if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Test_receive: reopen of '%s' for write failed", tempfile ); } DEBUGF(DRECV1)("Test_receive: starting read from socket %d", *sock ); while( (n = Read_fd_len_timeout(transfer_timeout, *sock, buffer,sizeof(buffer)-1)) > 0 ){ buffer[n] = 0; DEBUGF(DRECV4)("Test_receive: remote read '%d' '%s'", n, buffer ); if( write( tempfd,buffer,n ) != n ){ DEBUGF(DRECV1)( "Test_receive: bad write to '%s' - '%s'", tempfile, Errormsg(errno) ); status = JFAIL; goto error; } } if( n < 0 ){ DEBUGF(DRECV1)("Test_receive: bad read '%d' getting command", n ); status = JFAIL; goto error; } close(tempfd); tempfd = -1; DEBUGF(DRECV4)("Test_receive: end read" ); /*** at this point you can check the format of the received file, etc. *** if you have an error message at this point, you should write it *** to the socket, and arrange protocol can handle this. ***/ status = do_secure_work( jobsize, from_server, tempfile, header_info ); /*** if an error message is returned, you should write this *** message to the tempfile and the proceed to send the contents ***/ DEBUGF(DRECV1)("Test_receive: doing reply" ); if( (tempfd = Checkread(tempfile,&statb)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Test_receive: reopen of '%s' for write failed", tempfile ); } while( (n = Read_fd_len_timeout(transfer_timeout, tempfd, buffer,sizeof(buffer)-1)) > 0 ){ buffer[n] = 0; DEBUGF(DRECV4)("Test_receive: sending '%d' '%s'", n, buffer ); if( write( *sock,buffer,n ) != n ){ DEBUGF(DRECV1)( "Test_receive: bad write to socket - '%s'", Errormsg(errno) ); status = JFAIL; goto error; } } if( n < 0 ){ DEBUGF(DRECV1)("Test_receive: bad read '%d' getting status", n ); status = JFAIL; goto error; } DEBUGF(DRECV1)("Test_receive: reply done" ); error: if( tempfd>=0) close(tempfd); tempfd = -1; return(status); } const struct security test_auth = { "test", "test", "test", 0, 0, Test_send, 0, Test_receive }; #ifdef WITHPLUGINS plugin_get_func getter_name(test); size_t getter_name(test)(const struct security **s, size_t max) { if( max > 0 ) *s = &test_auth; return 1; } #endif lprng-3.8.B/src/auth/md5_auth.c0000644000131400013140000005054311531672131013210 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-1999, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ #include "lp.h" #include "user_auth.h" #include "krb5_auth.h" #include "errorcodes.h" #include "fileopen.h" #include "linksupport.h" #include "child.h" #include "getqueue.h" #include "lpd_secure.h" #include "lpd_dispatch.h" #include "permission.h" /* * md5 authentication Connection Level: md5_connect and md5_verify The client and server do a handshake, exchanging salts and values as follows: Client connects to server Server sends 'salt' Client gets user and user secret gets server id and server secret makes 'userid serverid' hashs the whole mess and gets md5 hash (see code) sends 'userid serverid XXXXXXX' where XXXXX is md5 hash Server checks userid and server, generates the same hash if values match, all is happy File Transfer: md5_send and md5 receive Client connects to server Server sends 'salt' Client get user and user secret gets server id and server secret hashes the mess and the file Sends the hash followed by the file Server reads the file gets the hash dumps the rest of stuff into a file get user and user secret gets server id and server secret hashes the mess and the file checks to see that all is well performs action Client keyfile: xxx=yyy key where xxx is md5_id=xxx value from printcap yyy should be sent to server as the 'from' value Server keyfile: yyy=key where yyy is the 'from' id value */ #include "md5.h" /* Set the name of the file we'll be getting our key from. The keyfile should only be readable by the owner and by whatever group the user programs run as. This way, nobody can write their own authentication module */ /* key length (for MD5, it's 16) */ #define KEY_LENGTH MD5_KEY_LENGTH /* The md5 hashing function, which does the real work */ static void MDString( const unsigned char *inString, unsigned char *outstring, int inlen) { MD5_CONTEXT mdContext; MD5Init (&mdContext); MD5Update(&mdContext, inString, inlen); MD5Final(&mdContext, outstring); } static void MDFile( int fd, unsigned char *outstring ) { MD5_CONTEXT mdContext; unsigned char buffer[LARGEBUFFER]; int n; MD5Init (&mdContext); while( (n = ok_read( fd, buffer, sizeof(buffer))) > 0 ){ MD5Update(&mdContext, buffer, n); } MD5Final(&mdContext, outstring); } static char *hexstr( const unsigned char *str, int len, char *outbuf, int outlen ) { int i, j; for( i = 0; i < len && 2*(i+1) < outlen ; ++i ){ j = ((unsigned char *)str)[i]; plp_snprintf(&outbuf[2*i],4, "%02x",j); } if( outlen > 0 ) outbuf[2*i] = 0; return( outbuf ); } static int md5key( const char *keyfile, char *name, char *key, int keysize, char *errmsg, int errlen ) { const char *keyvalue; int i, keylength = -1; struct line_list keys; Init_line_list( &keys ); memset(key,0,keysize); /* void Read_file_list( int required, struct line_list *model, char *str, const char *linesep, int sort, const char *keysep, int uniq, int trim, int marker, int doinclude, int nocomment, int depth, int maxdepth ) */ Read_file_list( /*required*/0, /*model*/&keys, /*str*/(char *)keyfile, /*linesep*/Line_ends,/*sort*/1, /*keysep*/Option_value_sep,/*uniq*/1, /*trim*/1, /*marker*/0, /*doinclude*/0, /*nocomment*/1,/*depth*/0,/*maxdepth*/4 ); /* read in the key from the key file */ keyvalue = Find_exists_value( &keys, name,Hash_value_sep ); if( keyvalue == 0 ){ plp_snprintf(errmsg, errlen, "md5key: no key for '%s' in '%s'", name, keyfile ); goto error; } DEBUG1("md5key: key '%s'", keyvalue ); /* copy to string */ for(i = 0; keyvalue[i] && i < keysize; ++i ){ key[i] = keyvalue[i]; } keylength = i; error: Free_line_list( &keys ); return( keylength ); } /************************************************************** *md5_send: *A simple implementation for testing user supplied authentication * The info line_list has the following fields * client=papowell <- client id, can be forwarded * destination=test <- destination ID - use for remote key * forward_id=test <- forward_id from configuration/printcap * from=papowell <- originator ID - use for local key * id=test <- id from configuration/printcap * * The start of the actual file has: * destination=test <- destination ID (URL encoded) * (destination ID from above) * server=test <- if originating from server, the server key (URL encoded) * (originator ID from above) * client=papowell <- client id * (client ID from above) * input=%04t1 <- input that is * If you need to set a 'secure id' then you set the 'FROM' * **************************************************************/ static int md5_send( int *sock, int transfer_timeout, char *tempfile, char *errmsg, int errlen, const struct security *security UNUSED, struct line_list *info ) { unsigned char destkey[KEY_LENGTH+1]; unsigned char challenge[KEY_LENGTH+1]; unsigned char response[KEY_LENGTH+1]; unsigned char filehash[KEY_LENGTH+1]; int destkeylength, i, n; char smallbuffer[SMALLBUFFER]; char keybuffer[SMALLBUFFER]; char *s, *dest; const char *keyfile; char buffer[LARGEBUFFER]; struct stat statb; int tempfd = -1, len, ack; int status = 0; errmsg[0] = 0; if(DEBUGL1)Dump_line_list("md5_send: info", info ); if( !Is_server ){ /* we get the value of the MD5KEYFILE variable */ keyfile = getenv("MD5KEYFILE"); if( keyfile == 0 ){ plp_snprintf(errmsg, errlen, "md5_send: no MD5KEYFILE environment variable" ); goto error; } } else { keyfile = Find_exists_value( info, "server_keyfile",Hash_value_sep ); if( keyfile == 0 ){ plp_snprintf(errmsg, errlen, "md5_send: no md5_server_keyfile entry" ); goto error; } } dest = Find_str_value( info, DESTINATION ); if( dest == 0 ){ plp_snprintf(errmsg, errlen, "md5_send: no '%s' value in info", DESTINATION ); goto error; } if( (destkeylength = md5key( keyfile, dest, keybuffer, sizeof(keybuffer), errmsg, errlen ) ) <= 0 ){ goto error; } if( (s = strpbrk(keybuffer,Whitespace)) ){ *s++ = 0; while( (isspace(cval(s))) ) ++s; if( *s == 0 ){ plp_snprintf(errmsg, errlen, "md5_send: no '%s' value in keyfile", dest ); goto error; } dest = keybuffer; } else { s = keybuffer; dest = Find_str_value( info, FROM ); if( !dest ){ plp_snprintf(errmsg,errlen, "md5_send: no '%s' value in info", FROM ); goto error; } } destkeylength = safestrlen(s); if( destkeylength > KEY_LENGTH ) destkeylength = KEY_LENGTH; memcpy( destkey, s, destkeylength ); DEBUG1("md5_send: sending on socket %d", *sock ); /* Read the challenge dest server */ len = sizeof(buffer); if( (n = Link_line_read(ShortRemote_FQDN,sock, transfer_timeout,buffer,&len)) ){ plp_snprintf(errmsg, errlen, "md5_send: error reading challenge - '%s'", Link_err_str(n) ); goto error; } else if( len == 0 ){ plp_snprintf(errmsg, errlen, "md5_send: zero length challenge"); goto error; } DEBUG1("md5_send: challenge '%s'", buffer ); n = safestrlen(buffer); if( n == 0 || n % 2 || n/2 > KEY_LENGTH ){ plp_snprintf(errmsg, errlen, "md5_send: bad challenge length '%d'", safestrlen(buffer) ); goto error; } memset(challenge, 0, sizeof(challenge)); smallbuffer[2] = 0; for(i = 0; buffer[2*i] && i < KEY_LENGTH; ++i ){ memcpy(smallbuffer,&buffer[2*i],2); challenge[i] = strtol(smallbuffer,0,16); } DEBUG1("md5_send: decoded challenge '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUG1("md5_send: destkey '%s'", hexstr( destkey, KEY_LENGTH, buffer, sizeof(buffer) )); /* xor the challenge with the dest key */ n = 0; len = destkeylength; for(i = 0; i < KEY_LENGTH; i++){ challenge[i] = (challenge[i]^destkey[n]); n=(n+1)%len; } DEBUG1("md5_send: challenge^destkey '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUG1("md5_send: challenge^destkey^idkey '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUG1("md5_send: opening tempfile '%s'", tempfile ); if( (tempfd = Checkread(tempfile,&statb)) < 0){ plp_snprintf(errmsg, errlen, "md5_send: open '%s' for read failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } DEBUG1("md5_send: doing md5 of file"); MDFile( tempfd, filehash); DEBUG1("md5_send: filehash '%s'", hexstr( filehash, KEY_LENGTH, buffer, sizeof(buffer) )); /* xor the challenge with the file key */ n = 0; len = KEY_LENGTH; for(i = 0; i < KEY_LENGTH; i++){ challenge[i] = (challenge[i]^filehash[n]); n=(n+1)%len; } DEBUG1("md5_send: challenge^destkey^idkey^filehash '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); plp_snprintf( smallbuffer, sizeof(smallbuffer), "%s", dest ); /* now we xor the buffer with the key */ len = safestrlen(smallbuffer); DEBUG1("md5_send: idstuff len %d '%s'", len, smallbuffer ); n = 0; for(i = 0; i < len; i++){ challenge[n] = (challenge[n]^smallbuffer[i]); n=(n+1)%KEY_LENGTH; } DEBUG1("md5_send: result challenge^destkey^idkey^filehash^idstuff '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); /* now, MD5 hash the string */ MDString(challenge, response, KEY_LENGTH); /* return the response to the server */ hexstr( response, KEY_LENGTH, buffer, sizeof(buffer) ); n = safestrlen(smallbuffer); plp_snprintf(smallbuffer+n, sizeof(smallbuffer)-n-1, " %s", buffer ); DEBUG1("md5_send: sending response '%s'", smallbuffer ); safestrncat(smallbuffer,"\n"); ack = 0; if( (n = Link_send( RemoteHost_DYN, sock, transfer_timeout, smallbuffer, safestrlen(smallbuffer), &ack )) || ack ){ /* keep the other end dest trying to read */ if( (s = strchr(smallbuffer,'\n')) ) *s = 0; plp_snprintf(errmsg,errlen, "error '%s'\n sending str '%s' to %s@%s", Link_err_str(n), smallbuffer, RemotePrinter_DYN, RemoteHost_DYN ); goto error; } if( lseek( tempfd, 0, SEEK_SET ) == -1 ){ plp_snprintf(errmsg,errlen, "md5_send: seek failed - '%s'", Errormsg(errno) ); goto error; } DEBUG1("md5_send: starting transfer of file"); while( (len = Read_fd_len_timeout( transfer_timeout, tempfd, buffer, sizeof(buffer)-1 )) > 0 ){ buffer[len] = 0; DEBUG4("md5_send: file information '%s'", buffer ); if( write( *sock, buffer, len) != len ){ plp_snprintf(errmsg, errlen, "md5_send: write to socket failed - %s", Errormsg(errno) ); status = JABORT; goto error; } } if( len < 0 ){ plp_snprintf(errmsg, errlen, "md5_send: read dest '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } close(tempfd); tempfd = -1; /* we close the writing side */ shutdown( *sock, 1 ); DEBUG1("md5_send: sent file" ); if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ plp_snprintf(errmsg, errlen, "md5_send: open '%s' for write failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } DEBUG1("md5_send: starting read of response"); if( (len = Read_fd_len_timeout(transfer_timeout, *sock,buffer,1)) > 0 ){ n = cval(buffer); DEBUG4("md5_send: response byte '%d'", n); status = n; if( isprint(n) && write(tempfd,buffer,1) != 1 ){ plp_snprintf(errmsg, errlen, "md5_send: write to '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } } while( (len = Read_fd_len_timeout(transfer_timeout, *sock,buffer,sizeof(buffer)-1)) > 0 ){ buffer[len] = 0; DEBUG4("md5_send: socket information '%s'", buffer); if( write(tempfd,buffer,len) != len ){ plp_snprintf(errmsg, errlen, "md5_send: write to '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } } close( tempfd ); tempfd = -1; error: if( tempfd >= 0 ) close(tempfd); tempfd = -1; return(status); } static int md5_receive( int *sock, int transfer_timeout, char *user UNUSED, char *jobsize, int from_server, char *authtype UNUSED, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security UNUSED, char *tempfile, SECURE_WORKER_PROC do_secure_work) { char input[SMALLBUFFER]; char buffer[LARGEBUFFER]; char keybuffer[LARGEBUFFER]; int destkeylength, i, n, len, tempfd = -1; char *s, *dest, *hash; const char *keyfile; unsigned char destkey[KEY_LENGTH+1]; unsigned char challenge[KEY_LENGTH+1]; unsigned char response[KEY_LENGTH+1]; unsigned char filehash[KEY_LENGTH+1]; struct stat statb; int status_error = 0; double size; if(DEBUGL1)Dump_line_list("md5_receive: info", info ); if(DEBUGL1)Dump_line_list("md5_receive: header_info", header_info ); /* do validation and then write 0 */ if( !Is_server ){ plp_snprintf(errmsg, errlen, "md5_receive: not server" ); goto error; } else { keyfile = Find_exists_value( info, "server_keyfile",Hash_value_sep ); if( keyfile == 0 ){ plp_snprintf(errmsg, errlen, "md5_receive: no md5_server_keyfile entry" ); goto error; } } DEBUGF(DRECV1)("md5_receive: sending ACK" ); if( (n = Link_send( RemoteHost_DYN, sock, transfer_timeout, "", 1, 0 )) ){ plp_snprintf(errmsg,errlen, "error '%s' ACK to %s@%s", Link_err_str(n), RemotePrinter_DYN, RemoteHost_DYN ); goto error; } /* First, seed the random number generator */ srand(time(NULL)); /* Now, fill the challenge with 16 random values */ for(i = 0; i < KEY_LENGTH; i++){ challenge[i] = rand() >> 8; } hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) ); DEBUGF(DRECV1)("md5_receive: sending challenge '%s'", buffer ); safestrncat(buffer,"\n"); /* Send the challenge to the client */ if( (n = Link_send( RemoteHost_DYN, sock, transfer_timeout, buffer, safestrlen(buffer), 0 )) ){ /* keep the other end dest trying to read */ if( (s = strchr(buffer,'\n')) ) *s = 0; plp_snprintf(errmsg,errlen, "error '%s' sending str '%s' to %s@%s", Link_err_str(n), buffer, RemotePrinter_DYN, RemoteHost_DYN ); goto error; } /* now read response */ DEBUGF(DRECV1)("md5_receive: reading response"); len = sizeof(input)-1; if( (n = Link_line_read(ShortRemote_FQDN,sock, transfer_timeout,input,&len) )){ plp_snprintf(errmsg, errlen, "md5_receive: error reading challenge - '%s'", Link_err_str(n) ); goto error; } else if( len == 0 ){ plp_snprintf(errmsg, errlen, "md5_receive: zero length response"); goto error; } else if( len >= (int)sizeof( input) -2 ){ plp_snprintf(errmsg, errlen, "md5_receive: response too long"); goto error; } DEBUGF(DRECV1)("md5_receive: response '%s'", input ); dest = input; if( (s = strchr(input,' ')) ) *s++ = 0; if( s ){ hash = s; if( strpbrk(hash,Whitespace) ){ plp_snprintf(errmsg, errlen, "md5_receive: malformed response" ); goto error; } n = safestrlen(hash); if( n == 0 || n%2 ){ plp_snprintf(errmsg, errlen, "md5_receive: bad response hash length '%d'", n ); goto error; } } else { plp_snprintf(errmsg, errlen, "md5_receive: no 'hash' in response" ); goto error; } DEBUGF(DRECV1)("md5_receive: dest '%s', hash '%s', prefix '%s'", dest, hash, buffer ); if( (destkeylength = md5key( keyfile, dest, keybuffer, KEY_LENGTH, errmsg, errlen ) ) <= 0 ){ goto error; } if( (s = strpbrk(keybuffer,Whitespace)) ){ *s++ = 0; while( isspace(cval(s))) ++s; } else { s = keybuffer; } destkeylength = safestrlen(s); if( destkeylength > KEY_LENGTH ) destkeylength = KEY_LENGTH; memcpy(destkey,s,destkeylength); DEBUGF(DRECV1)("md5_receive: success, sending ACK" ); if((n = Link_send( RemoteHost_DYN, sock, transfer_timeout, "", 1, 0 )) ){ /* keep the other end dest trying to read */ plp_snprintf(errmsg,errlen, "error '%s' sending ACK to %s@%s", Link_err_str(n), RemotePrinter_DYN, RemoteHost_DYN ); goto error; } DEBUGF(DRECV1)("md5_receive: reading file" ); /* open a file for the output */ if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ plp_snprintf(errmsg, errlen, "md5_receive: reopen of '%s' for write failed", tempfile ); } DEBUGF(DRECV1)("md5_receive: starting read dest socket %d", *sock ); while( (n = Read_fd_len_timeout(transfer_timeout, *sock, buffer,sizeof(buffer)-1)) > 0 ){ buffer[n] = 0; DEBUGF(DRECV4)("md5_receive: remote read '%d' '%s'", n, buffer ); if( write( tempfd,buffer,n ) != n ){ plp_snprintf(errmsg, errlen, "md5_receive: bad write to '%s' - '%s'", tempfile, Errormsg(errno) ); goto error; } } if( n < 0 ){ plp_snprintf(errmsg, errlen, "md5_receive: bad read '%d' reading file ", n ); goto error; } close(tempfd); tempfd = -1; DEBUGF(DRECV4)("md5_receive: end read" ); DEBUG1("md5_receive: opening tempfile '%s'", tempfile ); if( (tempfd = Checkread(tempfile,&statb)) < 0){ plp_snprintf(errmsg, errlen, "md5_receive: open '%s' for read failed - %s", tempfile, Errormsg(errno) ); goto error; } DEBUG1("md5_receive: doing md5 of file"); MDFile( tempfd, filehash); DEBUG1("md5_receive: filehash '%s'", hexstr( filehash, KEY_LENGTH, buffer, sizeof(buffer) )); close(tempfd); tempfd = -1; DEBUGF(DRECV1)("md5_receive: challenge '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUGF(DRECV1)("md5_receive: destkey '%s'", hexstr( destkey, KEY_LENGTH, buffer, sizeof(buffer) )); /* xor the challenge with the dest key */ n = 0; len = destkeylength; for(i = 0; i < KEY_LENGTH; i++){ challenge[i] = (challenge[i]^destkey[n]); n=(n+1)%len; } DEBUGF(DRECV1)("md5_receive: challenge^destkey '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUGF(DRECV1)("md5_receive: challenge^destkey^idkey '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); DEBUGF(DRECV1)("md5_receive: filehash '%s'", hexstr( filehash, KEY_LENGTH, buffer, sizeof(buffer) )); /* xor the challenge with the file key */ n = 0; len = KEY_LENGTH; for(i = 0; i < KEY_LENGTH; i++){ challenge[i] = (challenge[i]^filehash[n]); n=(n+1)%len; } DEBUGF(DRECV1)("md5_receive: challenge^destkey^idkey^filehash '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); /* now we xor the buffer with the key */ len = safestrlen(input); DEBUGF(DRECV1)("md5_receive: idstuff len %d '%s'", len, input ); n = 0; for(i = 0; i < len; i++){ challenge[n] = (challenge[n]^(unsigned char)input[i]); n=(n+1)%KEY_LENGTH; } DEBUGF(DRECV1)("md5_receive: result challenge^destkey^idkey^filehash^deststuff '%s'", hexstr( challenge, KEY_LENGTH, buffer, sizeof(buffer) )); /* now, MD5 hash the string */ MDString(challenge, response, KEY_LENGTH); hexstr( response, KEY_LENGTH, buffer, sizeof(buffer) ); DEBUGF(DRECV1)("md5_receive: calculated hash '%s'", buffer ); DEBUGF(DRECV1)("md5_receive: sent hash '%s'", hash ); if( strcmp( buffer, hash ) ){ plp_snprintf(errmsg, errlen, "md5_receive: bad response value"); goto error; } DEBUGF(DRECV1)("md5_receive: success" ); Set_str_value(header_info,FROM,dest); status_error = do_secure_work( jobsize, from_server, tempfile, header_info ); DEBUGF(DRECV1)("md5_receive: Do_secure_work returned %d", status_error ); /* we now have the encoded output */ if( (tempfd = Checkread(tempfile,&statb)) < 0 ){ plp_snprintf( errmsg, errlen, "md5_receive: reopen of '%s' for read failed - %s", tempfile, Errormsg(errno) ); goto error; } size = statb.st_size; DEBUGF(DRECV1)( "md5_receive: return status encoded size %0.0f", size); if( size || status_error ){ buffer[0] = ACK_FAIL; write( *sock,buffer,1 ); while( (n = Read_fd_len_timeout(transfer_timeout, tempfd, buffer,sizeof(buffer)-1)) > 0 ){ buffer[n] = 0; DEBUGF(DRECV4)("md5_receive: sending '%d' '%s'", n, buffer ); if( write( *sock,buffer,n ) != n ){ plp_snprintf( errmsg, errlen, "md5_receive: bad write to socket - '%s'", Errormsg(errno) ); goto error; } } if( n < 0 ){ plp_snprintf( errmsg, errlen, "md5_receive: read '%s' failed - %s", tempfile, Errormsg(errno) ); goto error; } } else { write( *sock,"",1 ); } return( 0 ); error: return(JFAIL); } const struct security md5_auth = { "md5", "md5", "md5", 0, 0, md5_send, 0, md5_receive }; #ifdef WITHPLUGINS plugin_get_func getter_name(md5); size_t getter_name(md5)(const struct security **s, size_t max) { if( max > 0 ) *s = &md5_auth; return 1; } #endif lprng-3.8.B/src/auth/ssl_auth.c0000644000131400013140000006560511531672131013331 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "fileopen.h" #include "errorcodes.h" #include "getqueue.h" #ifdef SSL_ENABLE /* The Kerberos 5 support is MIT-specific. */ #define OPENSSL_NO_KRB5 #include #include #include "user_auth.h" #include "lpd_secure.h" #include "ssl_auth.h" /* The code for the SSL support routines has been taken from various places, including: OpenSSL Example Programs 20020110 by Eric Rescorla January 10, 2002 Edition SHAMELESS PLUG Extremely detailed coverage of SSL/TLS can be found in _SSL_and_TLS:_Designing_and_Building_Secure_Systems_ Eric Rescorla Addison-Wesley, 2001 ISBN 0-201-61598-3 The code for fetchmail: ftp://ftp.ccil.org/pub/esr/fetchmail http://www.tuxedo.org/~esr/fetchmail The code for Lynx The Lynx homepage is . http://lynx.isc.org/release ftp://lynx.isc.org/release The code for stunnel http://www.stunnel.org And, of course, the SSL examples http://www.openssl.org openssl-0.9.6c Just to make it silly, I have used small snippets of various parts of all these programs, and as far as I can tell, do not need to include the GNU copyleft, licenses, or other stuff. This allows me to distribute this under the BSD license or GLIB license. This is all much sillyness simply to be clear of encumberment and cost me a couple of weeks work. Patick Powell Sat May 11 16:30:07 PDT 2002 */ static char *Set_ERR_str( char *header, char *errmsg, int errlen ); static int SSL_Initialize_ctx( SSL_CTX **ctx_ret, char *errmsg, int errlen ); static void Destroy_ctx(SSL_CTX *ctx); static void Get_cert_info( SSL *ssl, struct line_list *info ); static int Open_SSL_connection( int sock, SSL_CTX *ctx, SSL **ssl_ret, struct line_list *info, char *errmsg, int errlen ); static int Accept_SSL_connection( int sock, int timeout, SSL_CTX *ctx, SSL **ssl_ret, struct line_list *info, char *errmsg, int errlen ); static int Write_SSL_connection( int timeout, SSL *ssl, char *buffer, int len, char *errmsg, int errlen ); static int Gets_SSL_connection( int timeout, SSL *ssl, char *inbuffer, int len, char *errmsg, int errlen ); static int Read_SSL_connection( int timeout, SSL *ssl, char *inbuffer, int *len, char *errmsg, int errlen ); static int Close_SSL_connection( int sock, SSL *ssl ); static const char * Error_SSL_name( int i ); /* * The callback for getting a password for the * private key. You need to return it in the buffer. * If you are a server: * read from SSL_server_password_file * If you are a client: * check for SSL_PASSWORD (actual value) * check for SSL_PASSWORD_PATH (read the file) */ static char password_value[ 64 ]; static int Password_callback( char *pass,int len, int rwflag,void *userdata) { DEBUG1("Password_callback: returning '%s'", password_value); if( safestrlen( password_value ) >= len ){ Errorcode = JABORT; fatal(LOG_ERR, "Passwd_callback: password len %d longer then max len %d", safestrlen(password_value), len ); } mystrncpy(pass,password_value,len); return(safestrlen(pass)); } static void SSL_init(void) { static int ssl_init; if( !ssl_init ){ /* Global system initialization*/ SSL_library_init(); SSL_load_error_strings(); ssl_init = 1; } } /* * char *Set_ERR_str( char *header, char *errmsg, int errlen ) * - generate the SSL error message */ static char *Set_ERR_str( char *header, char *errmsg, int errlen ) { unsigned long e; errmsg[0] = 0; if( header ){ snprintf(errmsg, errlen, "%s: ", header ); } while( ERR_peek_error() ){ int n = strlen(errmsg); e = ERR_get_error(); ERR_error_string_n( e, errmsg+n, errlen -n ); if( ERR_peek_error() ){ n = strlen(errmsg); plp_snprintf(errmsg+n,errlen-n, "\n"); } } return( errmsg ); } /* * static char *getuservals( char *env, char *homedir, char *file, char *buf, int maxlen ) * get a file name from an environment variable or create it. * if env value, check to make sure file exists * if make up, check and if not present, then return null */ static char *getuservals( char *env, char *homedir, char *file, char *buf, int maxlen ) { char *s = 0; struct stat statb; if( env ) s = getenv(env); if( !s ){ plp_snprintf(buf,maxlen, "%s/%s", homedir, file ); s = buf; while( s && (s = strchr(s,'/')) ){ if( cval(s+1) == '/' ){ memmove(s,s+1,safestrlen(s+1)+1); } else { ++s; } } s = buf; } if( s && stat(s,&statb) ){ Errorcode = JABORT; fatal(LOG_ERR, "getuservals: cannot stat '%s' - %s", s, Errormsg(errno) ); } return(s); } /* * SSL_Initialize_ctx - initialize SSL context */ static int SSL_Initialize_ctx( SSL_CTX **ctx_ret, char *errmsg, int errlen ) { char *certpath, *certfile, *cp, *cf; char *mycert; SSL_METHOD *meth = 0; SSL_CTX *ctx = 0; char header[SMALLBUFFER]; char cabuf[MAXPATHLEN], certbuf[MAXPATHLEN], pwbuf[MAXPATHLEN]; struct stat statb; int pid; char *file, *s; int fd = -1, n; /* Global system initialization*/ SSL_init(); /* Create our context*/ meth=SSLv23_method(); ctx=SSL_CTX_new(meth); *ctx_ret = ctx; if( ctx == 0 ){ Set_ERR_str( "SSL_Initialize: SSL_CTX_new failed", errmsg, errlen ); return -1; } mycert = 0; /* get the directory for the SSL certificates */ if( ISNULL(Ssl_ca_path_DYN) && !ISNULL(Ssl_ca_file_DYN) ){ Set_DYN(&Ssl_ca_path_DYN, Ssl_ca_file_DYN); if( (s = strrchr(Ssl_ca_path_DYN, '/')) ) *s = 0; } cp = certpath = Ssl_ca_path_DYN; cf = certfile = Ssl_ca_file_DYN; if( Is_server ){ mycert = Ssl_server_cert_DYN; file = Ssl_server_password_file_DYN; if( file ){ if( (fd = Checkread( file, &statb )) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "SSL_initialize: cannot open server_password_file '%s'", file ); } if( (n = ok_read(fd, password_value, sizeof(password_value)-1)) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "SSL_initialize: cannot read server_password_file '%s'", file ); } password_value[n] = 0; if( (s = safestrchr(password_value,'\n')) ) *s = 0; n = strlen(password_value); if( n == 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "SSL_initialize: zero length server_password_file '%s'", file ); } } } else { struct passwd *pw; char *homedir; if( (pw = getpwuid( getuid())) == 0 ){ logerr_die(LOG_INFO, "setup_envp: getpwuid(%d) failed", getuid()); } homedir = pw->pw_dir; mycert = getuservals("LPR_SSL_FILE",homedir, ".lpr/client.crt", certbuf,sizeof(certbuf)); fd = -1; file = getuservals("LPR_SSL_PASSWORD",homedir, ".lpr/client.pwd", pwbuf, sizeof(pwbuf)); if( file ) fd = Checkread( file, &statb ); if( fd > 0 ){ if( (n = ok_read(fd, password_value, sizeof(password_value)-1)) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "SSL_initialize: cannot read server_password_file '%s'", file ); } password_value[n] = 0; if( (s = safestrchr(password_value,'\n')) ) *s = 0; } } DEBUG1("SSL_Initialize_ctx: certpath '%s', certfile '%s', mycert '%s', password '%s'", certpath, certfile, mycert, password_value ); /* Certificate Authority Files * - the certfile can contain a list of certificates * - the certpath has a list of files, with an index */ if( certpath && stat(certpath,&statb) ) cp = 0; if( certfile && stat(certfile,&statb) ) cf = 0; if( cf == 0 && cp == 0 ){ plp_snprintf( errmsg,errlen, "SSL_initialize: Missing both CA file '%s' and CA path '%s'", certfile, certpath ); return -1; } if( !SSL_CTX_load_verify_locations(ctx, cf, cp) ){ DEBUG1("SSL_Initialize_ctx: verify locations failed"); plp_snprintf( header,sizeof(header), "SSL_initialize: Bad CA file '%s' or CA path '%s'", cf, cp ); Set_ERR_str( header, errmsg, errlen ); return(-1); } /* * Certificate Checking (server) * we request check - this is good practice */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); /* * we have a certificate or key or both * we can assume that if you have one or the other that * it is a combined key/cert file * Set the password callback BEFORE we load the Private Key file */ SSL_CTX_set_default_passwd_cb(ctx, Password_callback); if( (cp = mycert) && stat(mycert,&statb) ) cp = 0; if( Is_server && !cp ){ plp_snprintf( errmsg,errlen, "SSL_initialize: Missing cert file '%s'", mycert ); return -1; } if( cp ){ if( !SSL_CTX_use_certificate_chain_file(ctx, mycert) ){ plp_snprintf( header,sizeof(header), "SSL_initialize: can't read certificate file '%s'", mycert ); Set_ERR_str( header, errmsg, errlen ); return(-1); } if( !SSL_CTX_use_PrivateKey_file(ctx, mycert, SSL_FILETYPE_PEM) ){ plp_snprintf( header,sizeof(header), "SSL_initialize: can't read private key in '%s'", mycert ); Set_ERR_str( header, errmsg, errlen ); return(-1); } } /* we set the session id context for the server. * This has no effect on clients, but appears to be * harmless. */ pid = getpid(); if( !SSL_CTX_set_session_id_context(ctx, (void*)&pid, sizeof pid) ){ Set_ERR_str( "SSL_initialize: SSL_CTX_set_session_id_context failed", errmsg, errlen ); return(-1); } #if (OPENSSL_VERSION_NUMBER < 0x00905100L) SSL_CTX_set_verify_depth(ctx,1); #endif return 0; } static void Destroy_ctx(SSL_CTX *ctx) { SSL_CTX_free(ctx); } /* * get peer certificate information */ static void Get_cert_info( SSL *ssl, struct line_list *info ) { X509 *peer; STACK_OF(X509) *sk; int i, n; char *certs = 0; char buffer[SMALLBUFFER]; sk=SSL_get_peer_cert_chain(ssl); if( sk && (n = sk_X509_num(sk)) > 0 ){ for( i = n-1; i >= 0; --i ){ peer = sk_X509_value(sk,i); if( X509_NAME_oneline( X509_get_subject_name( peer ), buffer, sizeof(buffer) ) ){ DEBUG1("Get_cert_info: level [%d of %d] subject '%s'", i, n, buffer ); if( i == n-1 && info ){ Set_str_value(info,AUTHFROM,buffer); } certs = safeextend3( certs, buffer, "\n", __FILE__,__LINE__ ); } if( 0 && X509_NAME_oneline( X509_get_issuer_name( peer ), buffer, sizeof(buffer) ) ){ DEBUG1("Get_cert_info: level [%d of %d] issuer '%s'", i, n, buffer ); certs = safeextend3( certs, buffer, "\n", __FILE__,__LINE__ ); } } } peer = SSL_get_peer_certificate(ssl); if( peer ){ if( X509_NAME_oneline( X509_get_subject_name( peer ), buffer, sizeof(buffer) ) ){ DEBUG1("Get_cert_info: peer subject '%s'", buffer ); if( info ){ Set_str_value(info,AUTHFROM,buffer); } certs = safeextend3( certs, buffer, "\n", __FILE__,__LINE__ ); } if( X509_NAME_oneline( X509_get_issuer_name( peer ), buffer, sizeof(buffer) ) ){ DEBUG1("Get_cert_info: peer issuer '%s'", buffer ); certs = safeextend3( certs, buffer, "\n", __FILE__,__LINE__ ); } } if( info ){ Set_str_value(info,AUTHCA,certs); } if( certs ) free( certs ); certs = 0; } /* * Make the connection an SSL connnection * - we also set up a BIO so that we can do buffered line reads * and writes */ static int Open_SSL_connection( int sock, SSL_CTX *ctx, SSL **ssl_ret, struct line_list *info, char *errmsg, int errlen ) { SSL *ssl = 0; BIO *bio; int ret; long verify_result; char buffer[SMALLBUFFER]; int status = 0; /* we get the SSL context. No connection yet */ ssl = SSL_new(ctx); if( !ssl ){ Set_ERR_str( "Open_SSL_connection: SSL_new failed", errmsg, errlen ); status = -1; goto done; } /* we get the magic BIO wrapper, and put it around * our socket. Note that we want to make sure that * the socket is not closed by the BIO functions */ if( !(bio = BIO_new_socket(sock, BIO_NOCLOSE)) ){ Set_ERR_str( "Open_SSL_connection: BIO_new_socket failed", errmsg, errlen ); status = -1; goto done; } SSL_set_bio(ssl,bio,bio); /* if you get any sort of error, give up */ ret = SSL_connect( ssl ); DEBUG1("Open_SSL_connection: SSL_connect returned %d, SSL_get_error = %d", ret, SSL_get_error(ssl, ret) ); switch( SSL_get_error(ssl, ret) ){ case SSL_ERROR_NONE: break; default: plp_snprintf(buffer,sizeof(buffer), "SSL_connect failed, err %d, SSL_get_error %d", ret, SSL_get_error(ssl, ret) ); Set_ERR_str( buffer, errmsg, errlen ); status = -1; goto done; break; } /* now we check to see which server we talked to */ verify_result = SSL_get_verify_result(ssl); DEBUG1("Open_SSL_connection: SSL_get_verify_result '%s'", X509_verify_cert_error_string(verify_result) ); if( verify_result != X509_V_OK ){ plp_snprintf(errmsg,errlen, "SSL_connect failed, peer certificat not verified: '%s'", X509_verify_cert_error_string(verify_result) ); status = -1; goto done; } Get_cert_info( ssl, info ); done: if( status ){ if( ssl ) SSL_free(ssl); ssl = 0; } *ssl_ret = ssl; return( status ); } /* * accept an incoming SSL connection */ static int Accept_SSL_connection( int sock, int timeout, SSL_CTX *ctx, SSL **ssl_ret, struct line_list *info, char *errmsg, int errlen ) { SSL *ssl = 0; BIO *bio; int ret, n, finished; long verify_result; char buffer[SMALLBUFFER]; int wait_for_read, wait_for_write; /* for select */ int status = 0; /* we get the SSL context. No connection yet */ DEBUG1("Accept_SSL_connection: starting, ctx 0x%lx, sock %d", Cast_ptr_to_long(ctx), sock); ssl = SSL_new(ctx); DEBUG1("Accept_SSL_connection: SSL_new 0x%lx", Cast_ptr_to_long(ssl) ); if( !ssl ){ Set_ERR_str( "Accept_SSL_connection: SSL_new failed", errmsg, errlen ); DEBUG1("Accept_SSL_connection: '%s'", errmsg); status = -1; goto done; } /* we get the magic BIO wrapper, and put it around * our socket. Note that we want to make sure that * the socket is not closed by the BIO functions */ if( !(bio = BIO_new_socket(sock, BIO_NOCLOSE)) ){ Set_ERR_str( "Accept_SSL_connection: BIO_new_socket failed", errmsg, errlen ); DEBUG1("Accept_SSL_connection: '%s'", errmsg); status = -1; goto done; } SSL_set_bio(ssl,bio,bio); /* if you get any sort of error, give up */ finished = wait_for_read = wait_for_write = 0; DEBUG1("Accept_SSL_connection: loop"); while(!finished){ if( wait_for_read || wait_for_write ){ fd_set readfds, writefds, exceptfds; /* for select() */ struct timeval tv, *tm = 0; DEBUG1("Accept_SSL_connection: need to wait for IO"); memset(&tv,0,sizeof(tv)); tv.tv_sec = timeout; if( timeout ) tm = &tv; FD_ZERO( &readfds ); FD_ZERO( &writefds ); FD_ZERO( &exceptfds ); if( wait_for_read ) FD_SET( sock, &readfds ); if( wait_for_write ) FD_SET( sock, &writefds ); FD_SET( sock, &exceptfds ); wait_for_read = wait_for_write = 0; n = select( sock+1,&readfds, &writefds, &exceptfds, tm ); if( n == 0 ){ plp_snprintf(errmsg, errlen, "Accept_SSL_connection: timeout"); status = -1; goto done; } } ret = SSL_accept( ssl ); n = SSL_get_error(ssl, ret); DEBUG1("Accept_SSL_connection: SSL_accept returned %d, SSL_get_error = %d", ret, n ); switch( n ){ case SSL_ERROR_NONE: finished = 1; break; case SSL_ERROR_WANT_READ: wait_for_read = 1; break; case SSL_ERROR_WANT_WRITE: wait_for_write = 1; break; default: plp_snprintf(buffer,sizeof(buffer), "SSL_accept failed, err %d, SSL_get_error %d '%s'", ret, n, Error_SSL_name(n) ); Set_ERR_str( buffer, errmsg, errlen ); status = -1; DEBUG1("Accept_SSL_connection: '%s'", errmsg ); goto done; break; } } /* now we check to see which server we talked to */ verify_result = SSL_get_verify_result(ssl); DEBUG1("Accept_SSL_connection: SSL_get_verify_result '%s'", X509_verify_cert_error_string(verify_result) ); if( verify_result != X509_V_OK ){ plp_snprintf(errmsg,errlen, "SSL_connect failed, peer certificat not verified: '%s'", X509_verify_cert_error_string(verify_result) ); status = -1; goto done; } Get_cert_info( ssl, info ); done: if( status ){ if( ssl ) SSL_free(ssl); ssl = 0; } *ssl_ret = ssl; return( status ); } /* * write a buffer to the SSL connection * return: 0 if successful * != 0 if failure */ static int Write_SSL_connection( int timeout, SSL *ssl, char *buffer, int len, char *errmsg, int errlen ) { int done = 0, n = 0; int status = 0; while( !status && done < len ){ Set_timeout_break( timeout ); n = SSL_write( ssl, buffer+done, len - done ); Clear_timeout(); switch( SSL_get_error(ssl, n) ){ case SSL_ERROR_NONE: done += n; break; case SSL_ERROR_ZERO_RETURN: status = LINK_TRANSFER_FAIL; break; case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: break; default: plp_snprintf(buffer,sizeof(buffer), "SSL_write failed, err %d, SSL_get_error %d", n, SSL_get_error(ssl, n) ); Set_ERR_str( buffer, errmsg, errlen ); status = LINK_TRANSFER_FAIL; break; } } return( status ); } /* * get a line terminated with \n into the buffer of size len * - reads at most len-1 chars to make sure a terminating 0 * can be appended * returns: 0 - success * -1 - error * 1 - EOF */ static int Gets_SSL_connection( int timeout, SSL *ssl, char *inbuffer, int len, char *errmsg, int errlen ) { int n, ret, status = 0, done = 0; char buffer[SMALLBUFFER]; buffer[0] = 0; for( n = 0; !done && n < len-1; ){ Set_timeout_break( timeout ); ret = SSL_read( ssl, inbuffer+n, 1 ); Clear_timeout(); if( ret > 0 ){ n += ret; inbuffer[n] = 0; if( cval(inbuffer+n-1) == '\n' ) done = 1; } DEBUG1("Gets_SSL_connection: ret %d, n %d, '%s'\n", ret, n, inbuffer ); switch( SSL_get_error( ssl, ret ) ){ case SSL_ERROR_NONE: break; case SSL_ERROR_ZERO_RETURN: done = status = 1; break; default: done = status = -1; plp_snprintf(buffer,sizeof(buffer), "SSL_read failed, err %d, SSL_get_error %d", ret, SSL_get_error(ssl, ret) ); Set_ERR_str( buffer, errmsg, errlen ); break; } } return( status ); } /* * read a buffer of size len * returns: 0 - success * -1 - error * 1 - EOF * *len = number of bytes read */ static int Read_SSL_connection( int timeout, SSL *ssl, char *inbuffer, int *len, char *errmsg, int errlen ) { char buffer[SMALLBUFFER]; int n, ret, status = 0; n = *len; *len = 0; Set_timeout_break( timeout ); ret = SSL_read( ssl, inbuffer, n ); Clear_timeout(); switch( SSL_get_error( ssl, ret ) ){ case SSL_ERROR_NONE: *len = ret; break; case SSL_ERROR_ZERO_RETURN: status = 1; break; default: status = -1; plp_snprintf(buffer,sizeof(buffer), "SSL_read failed, err %d, SSL_get_error %d", ret, SSL_get_error(ssl, ret) ); Set_ERR_str( buffer, errmsg, errlen ); status = LINK_TRANSFER_FAIL; break; } return( status ); } /* * close and kill off the SSL connection with undue violence */ static int Close_SSL_connection( int sock, SSL *ssl ) { int ret; BIO *bio = 0; char buffer[SMALLBUFFER]; int status = 0; /* do the shutdown and brutally at that */ if( ssl ){ ret = SSL_shutdown(ssl); DEBUG1( "SSL_shutdown returned %d, SSL_get_error %d - '%s'", ret, SSL_get_error(ssl, ret), Error_SSL_name(SSL_get_error(ssl,ret)) ); if( ret == 0 ){ shutdown( sock,1 ); ret = SSL_shutdown(ssl); DEBUG1( "SSL_shutdown (second) returned %d, SSL_get_error %d", ret, SSL_get_error(ssl, ret) ); } if( ret != 1 ){ plp_snprintf(buffer,sizeof(buffer), "SSL_shutdown failed, err %d, SSL_get_error %d", ret, SSL_get_error(ssl, ret) ); } } return( status ); } static const char * Error_SSL_name( int i ) { char *s = "Unknown"; switch(i){ case SSL_ERROR_NONE: s = "SSL_ERROR_NONE"; break; case SSL_ERROR_SSL: s = "SSL_ERROR_SSL"; break; case SSL_ERROR_WANT_READ: s = "SSL_ERROR_WANT_READ"; break; case SSL_ERROR_WANT_WRITE: s = "SSL_ERROR_WANT_WRITE"; break; case SSL_ERROR_WANT_X509_LOOKUP: s = "SSL_ERROR_WANT_X509_LOOKUP"; break; case SSL_ERROR_SYSCALL: s = "SSL_ERROR_SYSCALL"; break; case SSL_ERROR_ZERO_RETURN: s = "SSL_ERROR_ZERO_RETURN"; break; case SSL_ERROR_WANT_CONNECT: s = "SSL_ERROR_WANT_CONNECT"; break; } return(s); } static int Ssl_send( int *sock, int transfer_timeout, char *tempfile, char *errmsg, int errlen, const struct security *security, struct line_list *info ) { char buffer[LARGEBUFFER]; struct stat statb; int tempfd = -1, len; int status = 0; double size; SSL_CTX *ctx = 0; SSL *ssl = 0; errmsg[0] = 0; if(DEBUGL1)Dump_line_list("Ssl_send: info", info ); DEBUG1("Ssl_send: sending on socket %d", *sock ); if( SSL_Initialize_ctx(&ctx, errmsg, errlen ) ){ status = JFAIL; goto t_error; } if( Open_SSL_connection( *sock, ctx, &ssl, info, errmsg, errlen ) ){ status = JFAIL; goto t_error; } if( (tempfd = Checkread(tempfile,&statb)) < 0){ plp_snprintf(errmsg, errlen, "Ssl_send: open '%s' for read failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto t_error; } size = statb.st_size; plp_snprintf(buffer,sizeof(buffer), "%0.0f\n", size ); DEBUG1("Ssl_send: writing '%s'", buffer ); if( Write_SSL_connection( transfer_timeout, ssl, buffer, strlen(buffer), errmsg, errlen) ){ status = JFAIL; goto t_error; } DEBUG1("Ssl_send: starting send"); while( (len = ok_read( tempfd, buffer, sizeof(buffer)-1 )) > 0 ){ buffer[len] = 0; DEBUG4("Ssl_send: file information '%s'", buffer ); if( Write_SSL_connection( transfer_timeout, ssl, buffer, len, errmsg, errlen) ){ status = JFAIL; goto t_error; } } if( len < 0 ){ plp_snprintf(errmsg, errlen, "Ssl_send: read from '%s' failed - %s", tempfile, Errormsg(errno) ); status = JFAIL; goto t_error; } close(tempfd); tempfd = -1; if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ Errorcode = JABORT; fatal(LOG_ERR, "Ssl_send: open '%s' for write failed - %s", tempfile, Errormsg(errno) ); } DEBUG1("Ssl_send: sent file" ); DEBUG1("Ssl_send: getting read size"); if( Gets_SSL_connection( transfer_timeout, ssl, buffer, sizeof(buffer), errmsg, errlen) ){ status = JFAIL; goto error; } size = strtod( buffer, 0 ); DEBUG1("Ssl_send: starting read of %0.0f bytes", size); while( size > 0 ){ len = sizeof(buffer)-1; if( len > size ) len = size; if( Read_SSL_connection( transfer_timeout, ssl, buffer, &len, errmsg, errlen) ){ status = JFAIL; goto error; } buffer[len] = 0; DEBUG1("Ssl_send: rcvd %d bytes '%s'", len, buffer); if( write(tempfd,buffer,len) != len ){ plp_snprintf(errmsg, errlen, "Ssl_send: write to '%s' failed - %s", tempfile, Errormsg(errno) ); status = JABORT; goto error; } size -= len; } DEBUG1("Ssl_send: finished read"); close( tempfd ); tempfd = -1; goto done; t_error: DEBUG1("Ssl_send: t_error - status %d, errmsg '%s'", status, errmsg); close(tempfd); tempfd = -1; if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ Errorcode = JFAIL; fatal(LOG_ERR, "Ssl_send: open '%s' for write failed - %s", tempfile, Errormsg(errno) ); } error: DEBUG1("Ssl_send: error - status %d, errmsg '%s'", status, errmsg); Write_fd_str(tempfd, errmsg ); Write_fd_str(tempfd, "\n" ); done: DEBUG1("Ssl_send: done - status %d, errmsg '%s'", status, errmsg); if( ssl ){ Close_SSL_connection( *sock, ssl ); } if( ssl ) SSL_free( ssl ); if( ctx ) Destroy_ctx( ctx ); return(status); } static int Ssl_receive( int *sock, int transfer_timeout, char *user, char *jobsize, int from_server, char *authtype, struct line_list *info, char *errmsg, int errlen, struct line_list *header_info, const struct security *security, char *tempfile, SECURE_WORKER_PROC do_secure_work) { int tempfd, status, n, len; char buffer[LARGEBUFFER]; struct stat statb; double size; SSL_CTX *ctx = 0; SSL *ssl = 0; DEBUGFC(DRECV1)Dump_line_list("Ssl_receive: info", info ); DEBUGFC(DRECV1)Dump_line_list("Ssl_receive: header_info", header_info ); /* do validation and then write 0 */ tempfd = -1; if( Write_fd_len( *sock, "", 1 ) < 0 ){ status = JABORT; plp_snprintf( errmsg, errlen, "Ssl_receive: ACK 0 write error - %s", Errormsg(errno) ); goto error; } if( SSL_Initialize_ctx(&ctx, errmsg, errlen ) ){ status = JFAIL; goto error; } if( Accept_SSL_connection( *sock, transfer_timeout, ctx, &ssl, header_info, errmsg, errlen ) ){ status = JFAIL; goto error; } DEBUGFC(DRECV1)Dump_line_list("Ssl_receive: after accept info", header_info ); /* open a file for the output */ if( (tempfd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Ssl_receive: open of '%s' for write failed", tempfile ); } DEBUGF(DRECV1)("Ssl_receive: getting read size"); if( Gets_SSL_connection( transfer_timeout, ssl, buffer, sizeof(buffer), errmsg, errlen) ){ status = JFAIL; goto error; } size = strtod( buffer, 0 ); DEBUGF(DRECV1)("Ssl_receive: read size '%s'", buffer ); while( size > 0 ){ len = sizeof(buffer); if( len > size ) len = size; if( Read_SSL_connection( transfer_timeout, ssl, buffer, &len, errmsg, errlen) ){ status = JFAIL; goto error; } DEBUGF(DRECV1)("Ssl_receive: rcvd '%d' '%s'", len, buffer ); if( write( tempfd,buffer,len ) != len ){ status = JFAIL; logerr_die(LOG_ERR, "Ssl_receive: bad write to '%s' - '%s'", tempfile, Errormsg(errno) ); } size -= len; } close(tempfd); tempfd = -1; DEBUGF(DRECV1)("Ssl_receive: end read" ); /*** at this point you can check the format of the received file, etc. *** if you have an error message at this point, you should write it *** to the socket, and arrange protocol can handle this. ***/ status = do_secure_work( jobsize, from_server, tempfile, header_info ); /*** if an error message is returned, you should write this *** message to the tempfile and the proceed to send the contents ***/ DEBUGF(DRECV1)("Ssl_receive: doing reply" ); if( (tempfd = Checkread(tempfile,&statb)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Ssl_receive: reopen of '%s' for write failed", tempfile ); } size = statb.st_size; plp_snprintf(buffer,sizeof(buffer), "%0.0f\n", size ); DEBUG1("Ssl_receive: writing '%s'", buffer ); if( Write_SSL_connection( transfer_timeout, ssl, buffer, strlen(buffer), errmsg, errlen) ){ status = JFAIL; goto error; } while( (n = ok_read(tempfd, buffer,sizeof(buffer)-1)) > 0 ){ buffer[n] = 0; DEBUGF(DRECV1)("Ssl_receive: sending '%d' '%s'", n, buffer ); if( Write_SSL_connection( transfer_timeout, ssl, buffer, n, errmsg, errlen) ){ status = JFAIL; goto error; } } if( n < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Ssl_receive: read of '%s'", tempfile ); } DEBUGF(DRECV1)("Ssl_receive: reply done" ); if( tempfd > 0 ) close( tempfd ); tempfd = -1; return( status ); error: fatal(LOG_ERR, "Ssl_receive: %s", errmsg ); return(status); } const struct security ssl_auth = { "ssl", "ssl", "ssl", 0, 0, Ssl_send, 0, Ssl_receive }; #ifdef WITHPLUGINS plugin_get_func getter_name(ssl); size_t getter_name(ssl)(const struct security **s, size_t max) { if( max > 0 ) s[0] = &ssl_auth; return 1; } #endif #endif lprng-3.8.B/src/common/0000777000131400013140000000000011531672401011742 500000000000000lprng-3.8.B/src/common/lpd_worker.c0000644000131400013140000001157511531672132014204 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errorcodes.h" #include "child.h" #include "getqueue.h" #include "linelist.h" #include "lpd_worker.h" /* this file contains code that was formerly in linelist.c but split * out as it is only needed in lpd and pulls much code with it */ static void Do_work( const char *name, struct line_list *args, WorkerProc *proc, int intern_logger, int intern_status, int intern_mail, int intern_lpd_rquest, int intern_fd ) NORETURN; /* * Make_lpd_call - does the actual forking operation * - sets up file descriptor for child, can close_on_exec() * - does fork() as appropriate * * returns: pid of child or -1 if fork failed. */ static pid_t Make_lpd_call( const char *name, WorkerProc *proc, int passfd_count, int *passfd, struct line_list *args, int intern_logger, int intern_status, int intern_mail, int intern_lpd_request, int param_fd ) { int pid, fd, i, n, newfd; struct line_list env; Init_line_list(&env); pid = dofork(1); if( pid ){ return(pid); } Name = "LPD_CALL"; if(DEBUGL2){ LOGDEBUG("Make_lpd_call: name '%s', lpd path '%s'", name, Lpd_path_DYN ); LOGDEBUG("Make_lpd_call: passfd count %d", passfd_count ); for( i = 0; i < passfd_count; ++i ){ LOGDEBUG(" [%d] %d", i, passfd[i]); } Dump_line_list("Make_lpd_call - args", args ); } for( i = 0; i < passfd_count; ++i ){ fd = passfd[i]; if( fd < i ){ /* we have fd 3 -> 4, but 3 gets wiped out */ do{ newfd = dup(fd); Max_open(newfd); if( newfd < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Make_lpd_call: dup failed"); } DEBUG4("Make_lpd_call: fd [%d] = %d, dup2 -> %d", i, fd, newfd ); passfd[i] = newfd; } while( newfd < i ); } } if(DEBUGL2){ LOGDEBUG("Make_lpd_call: after fixing fd count %d", passfd_count); for( i = 0 ; i < passfd_count; ++i ){ fd = passfd[i]; LOGDEBUG(" [%d]=%d",i,fd); } } for( i = 0; i < passfd_count; ++i ){ fd = passfd[i]; DEBUG2("Make_lpd_call: fd %d -> %d",fd, i ); if( dup2( fd, i ) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Make_lpd_call: dup2(%d,%d) failed", fd, i ); } } /* close other ones to simulate close_on_exec() */ n = Max_fd+10; for( i = passfd_count ; i < n; ++i ){ close(i); } Do_work( name, args, proc, intern_logger, intern_status, intern_mail, intern_lpd_request, param_fd ); /* not reached: */ return(0); } static void Do_work( const char *name, struct line_list *args, WorkerProc *proc, int intern_logger, int intern_status, int intern_mail, int intern_lpd_request, int param_fd ) { Logger_fd = intern_logger; Status_fd = intern_status; Mail_fd = intern_mail; Lpd_request = intern_lpd_request; /* undo the non-blocking IO */ if( Lpd_request > 0 ){ /* undo the non-blocking IO */ Set_block_io( Lpd_request ); } Debug= Find_flag_value( args, DEBUG ); DbgFlag= Find_flag_value( args, DEBUGFV ); #ifdef DMALLOC { extern int dmalloc_outfile_fd; dmalloc_outfile_fd = intern_dmalloc; } #endif DEBUG3("Do_work: '%s', proc 0x%lx ", name, Cast_ptr_to_long(proc) ); (proc)(args, param_fd); cleanup(0); } /* * Start_worker - general purpose dispatch function * - adds an input FD */ pid_t Start_worker( const char *name, WorkerProc *proc, struct line_list *parms, int fd ) { struct line_list args; int passfd[20]; pid_t pid; int intern_fd = 0, intern_logger = -1, intern_status = -1, intern_mail = -1, intern_lpd = -1; int passfd_count = 0; Init_line_list(&args); passfd[passfd_count++] = 0; passfd[passfd_count++] = 1; passfd[passfd_count++] = 2; if( Mail_fd > 0 ){ intern_mail = passfd_count; passfd[passfd_count++] = Mail_fd; } if( Status_fd > 0 ){ intern_status = passfd_count; passfd[passfd_count++] = Status_fd; } if( Logger_fd > 0 ){ intern_logger = passfd_count; passfd[passfd_count++] = Logger_fd; } if( Lpd_request > 0 ){ intern_lpd = passfd_count; passfd[passfd_count++] = Lpd_request; } Set_flag_value(&args,DEBUG,Debug); Set_flag_value(&args,DEBUGFV,DbgFlag); #ifdef DMALLOC { extern int dmalloc_outfile_fd; if( dmalloc_outfile_fd > 0 ){ intern_dmalloc = passfd_count; passfd[passfd_count++] = dmalloc_outfile_fd; } } #endif if(DEBUGL1){ DEBUG1("Start_worker: '%s' fd %d", name, fd ); Dump_line_list("Start_worker - parms", parms ); } Merge_line_list( &args, parms, Hash_value_sep,1,1); Free_line_list( parms ); if( fd ){ intern_fd = passfd_count; passfd[passfd_count++] = fd; } pid = Make_lpd_call( name, proc, passfd_count, passfd, &args, intern_logger, intern_status, intern_mail, intern_lpd, intern_fd ); Free_line_list( &args ); return(pid); } lprng-3.8.B/src/common/monitor.c0000755000131400013140000002505311531672132013522 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "linelist.h" #include "getopt.h" #include "linksupport.h" #include "getqueue.h" /**** ENDINCLUDE ****/ /* * Monitor for TCP/UDP data * Opens a UDP or TCP socket and waits for data to be sent to it. * * monitor [-t] [-u] [port] * port is an integer number or a service name in the services database * default is to use UDP. */ int udp_open( int port ); int tcp_open( int port ); void Decode( char *in ); char buffer[1024*64]; int use_tcp = 1; int use_udp = 1; int port_num = 2001; int udp_fd = -1; int tcp_fd = -1; fd_set readfds; fd_set testfds; int debug; const char *prog = "???"; /***************************************************************** * Command line options and Debugging information * Getopt is a modified version of the standard getopt(3) command * line parsing routine. See getopt.c for details *****************************************************************/ /* use this before any error printing, sets up program Name */ struct info { char *buffer; int len; int max_len; }; struct info *inbuffers; int max_in_buffers; static void Add_buffer( int n ) { int len = max_in_buffers, count; if(debug)FPRINTF(STDERR, "Add_buffer: start n %d, inbuffers 0x%lx, max_in_buffers %d\n", n, Cast_ptr_to_long(inbuffers), max_in_buffers ); if( max_in_buffers <= n ){ max_in_buffers = n+1; count = sizeof(inbuffers[0])*max_in_buffers; inbuffers = realloc( inbuffers, count ); if( inbuffers == 0 ){ FPRINTF(STDERR,"Add_buffer: realloc %d failed\n", n ); exit(1); } for( count = len; count < max_in_buffers; ++count ){ memset(inbuffers+count,0,sizeof(inbuffers[0])); } } if(debug)FPRINTF(STDERR,"Add_buffer: end n %d, inbuffers 0x%lx, max_in_buffers %d\n", n, Cast_ptr_to_long(inbuffers), max_in_buffers ); } static void Clear_buffer( int n ) { struct info *in; if(debug)FPRINTF(STDERR,"Clear_buffer: n %d\n", n ); Add_buffer( n ); in = inbuffers+n; in->len = 0; } static struct info *Save_outbuf_len( int n, char *str, int len ) { struct info *in; if(debug)FPRINTF(STDERR,"Save_outbuf_len: n %d, len %d\n", n, len ); Add_buffer(n); in = inbuffers+n; if(debug)FPRINTF(STDERR, "Save_outbuf_len: start inbuffers 0x%lx, in 0x%lx, buffer 0x%lx, len %d, max_len %d\n", Cast_ptr_to_long(inbuffers), Cast_ptr_to_long(in), Cast_ptr_to_long(in->buffer), in->len, in->max_len ); if( len + in->len >= in->max_len ){ in->max_len += len; in->buffer = realloc( in->buffer, in->max_len+1 ); if( in->buffer == 0 ){ FPRINTF(STDERR,"Put_oubuf_len: realloc %d failed\n", in->max_len ); exit(1); } } memcpy(in->buffer+in->len, str, len+1 ); in->len += len; if(debug)FPRINTF(STDERR, "Save_outbuf_len: start inbuffers 0x%lx, in 0x%lx, buffer 0x%lx, len %d, max_len %d\n", Cast_ptr_to_long(inbuffers), Cast_ptr_to_long(in), Cast_ptr_to_long(in->buffer), in->len, in->max_len ); return( in ); } static void usage(void) { char *s; if( (s = safestrrchr( prog, '/')) ){ prog = s+1; } FPRINTF( STDERR, "usage: %s [-u] [-t] [port]\n", prog ); FPRINTF( STDERR, " -u = use UDP\n" ); FPRINTF( STDERR, " -t = use TCP (default)\n" ); FPRINTF( STDERR, " -d = debug\n" ); FPRINTF( STDERR, " port = port to use (%d default)\n", port_num ); exit(1); } int main(int argc, char *argv[] ) { int n, i, c, err, max_port = 0; char *portname, *s; struct servent *servent; struct info *in; prog = argv[0]; Opterr = 1; while( (n = Getopt(argc, argv, "dut")) != EOF ){ switch(n){ default: usage(); break; case 'u': use_udp = !use_udp; break; case 't': use_tcp = !use_tcp; break; case 'd': debug = 1; break; } } i = argc - Optind; if( i > 1 ) usage(); if( i == 1 ){ portname = argv[Optind]; n = atoi( portname ); if( n <= 0 ){ servent = getservbyname( portname, "udp" ); if( servent ){ n = ntohs( servent->s_port ); } } if( n <= 0 ){ FPRINTF( STDERR, "udp_open: bad port number '%s'\n",portname ); usage(); } port_num = n; } if( !use_tcp && !use_udp ) use_udp = 1; if( debug ){ FPRINTF(STDERR,"monitor: udp %d, tcp %d, port %d\n", use_udp, use_tcp, port_num ); } max_port = 0; FD_ZERO( &readfds ); if( use_udp && (udp_fd = udp_open( port_num )) >= 0){ if( debug ) FPRINTF(STDERR,"monitor: udp port %d\n", udp_fd ); FD_SET(udp_fd, &readfds); if( udp_fd >= max_port ) max_port = udp_fd+1; } if( use_tcp && (tcp_fd = tcp_open( port_num )) >= 0){ if( debug ) FPRINTF(STDERR,"monitor: tcp port %d\n", tcp_fd ); FD_SET(tcp_fd, &readfds); if( tcp_fd >= max_port ) max_port = tcp_fd+1; } if( debug ){ FPRINTF(STDERR,"monitor: max_port %d\n", max_port ); for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &readfds) ){ FPRINTF(STDERR,"monitor: initial on %d\n", i ); } } } while(1){ FD_ZERO( &testfds ); for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &readfds) ){ if( debug ) FPRINTF(STDERR,"monitor: waiting on %d\n", i ); FD_SET(i, &testfds); } } if( debug ) FPRINTF(STDERR,"monitor: starting wait, max %d\n", i ); n = select( i, &testfds, NULL, NULL, (struct timeval *)0 ); err = errno; if( debug ) FPRINTF(STDERR,"monitor: select returned %d\n", n ); if( n < 0 ){ FPRINTF( STDERR, "select error - %s\n", Errormsg(err) ); if( err != EINTR ) break; } if( n > 0 ) for( i = 0; i < max_port; ++i ){ if( FD_ISSET(i, &testfds) ){ if( debug ) FPRINTF(STDERR,"monitor: input on %d\n", i ); if( i == tcp_fd ){ socklen_t len; struct sockaddr_in sinaddr; len = sizeof( sinaddr ); i = accept( tcp_fd, (struct sockaddr *)&sinaddr, &len ); if( i < 0 ){ FPRINTF( STDERR, "accept error - %s\n", Errormsg(errno) ); continue; } FPRINTF( STDOUT, "connection from %s\n", inet_ntoa( sinaddr.sin_addr ) ); if( i >= max_port ) max_port = i+1; FD_SET(i, &readfds); } else { c = ok_read( i, buffer, sizeof(buffer)-1 ); if( c == 0 ){ /* closed connection */ FPRINTF(STDOUT, "closed connection %d\n", i ); close( i ); FD_CLR(i, &readfds ); Clear_buffer(i); } else if( c > 0 ){ buffer[c] = 0; if(debug)FPRINTF( STDOUT, "recv port %d: %s\n", i, buffer ); Add_buffer(i); in = Save_outbuf_len( i, buffer, c ); while( (s = safestrchr(in->buffer,'\n')) ){ *s++ = 0; Decode(in->buffer); memmove(in->buffer,s, safestrlen(s)+1 ); in->len = safestrlen(in->buffer); } } else { FPRINTF( STDERR, "read error - %s\n", Errormsg(errno) ); close( i ); FD_CLR(i, &readfds ); } } } } } return(0); } void Decode( char *in ) { struct line_list l, cf, info; char *s, *t, *header, *value; int i; Init_line_list(&l); Init_line_list(&cf); Init_line_list(&info); FPRINTF(STDOUT,"****\n"); if( debug )FPRINTF(STDOUT, "Decode: %s\n", in ); if((s = safestrpbrk(in,Hash_value_sep)) ){ *s++ = 0; Unescape(s); Free_line_list(&l); Split(&l,s,Line_ends,1,Hash_value_sep,1,1,1,0); for( i = 0; i < l.count; ++i ){ t = l.list[i]; if( debug || safestrncasecmp(t,VALUE,5) ){ FPRINTF(STDOUT,"%s\n", t ); } } s = Find_str_value(&l,VALUE); if( s ) Unescape(s); if( !safestrcasecmp(in,TRACE) ){ FPRINTF(STDOUT,"TRACE: '%s'\n", s ); } else if( !safestrcasecmp(in,UPDATE) ){ FPRINTF(STDOUT,"UPDATE: '%s'\n", s ); Split(&info,s,Line_ends,0,0,0,0,0,0); for( i = 0; i < info.count; ++i ){ header = info.list[i]; if( (value = safestrchr(header,'=')) ) *value++ = 0; Unescape(value); FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value ); } } else if( !safestrcasecmp(in,PRSTATUS) ){ FPRINTF(STDOUT,"PRSTATUS: '%s'\n", s ); } else if( !safestrcasecmp(in,QUEUE) ){ FPRINTF(STDOUT,"QUEUE: '%s'\n", s ); Split(&info,s,Line_ends,0,0,0,0,0,0); for( i = 0; i < info.count; ++i ){ header = info.list[i]; if( (value = safestrchr(header,'=')) ) *value++ = 0; Unescape(value); FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value ); } Free_line_list(&info); } else if( !safestrcasecmp(in,DUMP) ){ FPRINTF(STDOUT,"DUMP:\n"); Split(&info,s,Line_ends,0,0,0,0,0,0); for( i = 0; i < info.count; ++i ){ header = info.list[i]; if( (value = safestrchr(header,'=')) ) *value++ = 0; Unescape(value); if(debug) FPRINTF(STDOUT," [%d] %s='%s'\n", i, header, value ); if( !safestrcasecmp(header,QUEUE) ){ FPRINTF(STDOUT," EXTRACT QUEUE '%s'\n",value); } else if( !safestrcasecmp(header,UPDATE) ){ FPRINTF(STDOUT," EXTRACT UPDATE '%s'\n",value); } else { FPRINTF(STDOUT," EXTRACT '%s' '%s'\n",header, value); } } Free_line_list(&info); } else { FPRINTF(STDOUT,"%s: '%s'\n", in, s ); } } Free_line_list(&l); Free_line_list(&cf); Free_line_list(&info); FPRINTF(STDOUT,"\n"); } int udp_open( int port ) { int i, fd; struct sockaddr_in sinaddr; sinaddr.sin_family = AF_INET; sinaddr.sin_addr.s_addr = INADDR_ANY; sinaddr.sin_port = htons( port ); fd = socket( AF_INET, SOCK_DGRAM, 0 ); Max_open(fd); if( fd < 0 ){ FPRINTF(STDERR,"udp_open: socket call failed - %s\n", Errormsg(errno) ); return( -1 ); } i = bind( fd, (struct sockaddr *) & sinaddr, sizeof (sinaddr) ); if( i < 0 ){ FPRINTF(STDERR,"udp_open: bind to '%s port %d' failed - %s\n", inet_ntoa( sinaddr.sin_addr ), ntohs( sinaddr.sin_port ), Errormsg(errno) ); close(fd); fd = -1; } if( fd == 0 ){ fd = dup(fd); if( fd < 0 ){ FPRINTF(STDERR,"udp_open: dup failed - %s\n", Errormsg(errno) ); close(fd); fd = -1; } } return( fd ); } int tcp_open( int port ) { int i, fd; struct sockaddr_in sinaddr; sinaddr.sin_family = AF_INET; sinaddr.sin_addr.s_addr = INADDR_ANY; sinaddr.sin_port = htons( port ); fd = socket( AF_INET, SOCK_STREAM, 0 ); Max_open(fd); if( fd < 0 ){ FPRINTF(STDERR,"tcp_open: socket call failed - %s\n", Errormsg(errno) ); return( -1 ); } i = Link_setreuse( fd ); if( i >= 0 ) i = bind( fd, (struct sockaddr *) & sinaddr, sizeof (sinaddr) ); if( i >= 0 ) i = listen( fd, 10 ); if( i < 0 ){ FPRINTF(STDERR,"tcp_open: connect to '%s port %d' failed - %s\n", inet_ntoa( sinaddr.sin_addr ), ntohs( sinaddr.sin_port ), Errormsg(errno) ); close(fd); fd = -1; } if( fd == 0 ){ fd = dup(fd); if( fd < 0 ){ FPRINTF(STDERR,"tcp_open: dup failed - %s\n", Errormsg(errno) ); close(fd); fd = -1; } } return( fd ); } lprng-3.8.B/src/common/user_auth.c0000644000131400013140000001665211531672132014034 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-1999, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. ***************************************************************************/ /* * This code is, sadly, a whimpy excuse for the dynamically loadable * modules. The idea is that you can put your user code in here and it * will get included in various files. * * Supported Sections: * User Authentication * * DEFINES FILE WHERE INCLUDED PURPOSE * USER_RECEIVE lpd_secure.c define the user authentication * This is an entry in a table * USER_SEND sendauth.c define the user authentication * This is an entry in a table * RECEIVE lpd_secure.c define the user authentication * This is the code referenced in USER_RECEIVE * SENDING sendauth.c define the user authentication * This is the code referenced in USER_SEND * */ #include "lp.h" #ifdef WITHPLUGINS #include #endif #include "user_auth.h" #include "krb5_auth.h" #include "errorcodes.h" #include "fileopen.h" #include "linksupport.h" #include "child.h" #include "getqueue.h" #include "lpd_secure.h" #include "lpd_dispatch.h" #include "permission.h" #include "globmatch.h" #ifdef SSL_ENABLE /* The Kerberos 5 support is MIT-specific. */ #define OPENSSL_NO_KRB5 # include "ssl_auth.h" #endif /************************************************************** * Secure Protocol * * the following is sent on *sock: * \REQ_SECUREprintername C/F user authtype \n - receive a command * 0 1 2 3 * \REQ_SECUREprintername C/F user authtype jobsize\n - receive a job * 0 1 2 3 4 * Printer_DYN | | | + jobsize * | | authtype * | user * from_server=1 if F, 0 if C * * The authtype is used to look up the security information. This * controls the dispatch and the lookup of information from the * configuration and printcap entry for the specified printer * * The info line_list has the information, stripped of the leading * xxxx_ of the authtype name. * For example: * * forward_id=test <- forward_id from configuration/printcap * id=test <- id from configuration/printcap * * If there are no problems with this information, a single 0 byte * should be written back at this point, or a nonzero byte with an * error message. The 0 will cause the corresponding transfer * to be started. * * The handshake and with the remote end should be done now. * * The client will send a string with the following format: * destination=test\n <- destination ID (URL encoded) * (destination ID from above) * server=test\n <- if originating from server, the server key (URL encoded) * (originator ID from above) * client=papowell\n <- client id * (client ID from above) * input=%04t1\n <- input or command * This information will be extracted by the server. * The 'Do_secure_work' routine can now be called, and it will do the work. * * ERROR MESSAGES: * If you generate an error, then you should log it. If you want * return status to be returned to the remote end, then you have * to take suitable precautions. * 1. If the error is detected BEFORE you send the 0 ACK, then you * can send an error back directly. * 2. If the error is discovered as the result of a problem with * the encryption method, it is strongly recommended that you * simply send a string error message back. This should be * detected by the remote end, which will then decide that this * is an error message and not status. * **************************************************************/ #ifndef WITHPLUGINS static const struct security *SecuritySupported[] = { /* name, server_name, config_name, flags, client connect, send, send_done server accept, receive, receive_done */ #if defined(KERBEROS) &kerberos5_auth, &k5conn_auth, #endif &test_auth, &md5_auth, #ifdef SSL_ENABLE &ssl_auth, #endif NULL }; #else static const struct security **SecuritySupported = NULL; static int loadplugin(const char *filename, const char *realname) { void *plugin; char symbol[1024]; int count; const struct security **n; plugin_get_func *getter; size_t got; plugin = dlopen(filename, RTLD_NOW | RTLD_LOCAL); if( plugin == NULL ) { DEBUG1("%s cannot be loaded: %s", filename, dlerror()); return 0; } plp_snprintf(symbol, sizeof(symbol), "get_lprng_auth_%d_%s", AUTHPLUGINVERSION, realname); getter = dlsym(plugin, symbol); if( getter == NULL ) { DEBUG1("%s has no symbol named %s", filename, symbol); dlclose(plugin); return 0; } count = 0; if( SecuritySupported != NULL ) while( SecuritySupported[count] != NULL ) count++; n = realloc(SecuritySupported, sizeof(struct security*)*(count+10)); if( n == NULL ) { dlclose(plugin); return 0; } n[count] = NULL; SecuritySupported = n; got = getter(n + count, 9); if( got < 0 || got > 9 ) { n[count] = NULL; dlclose(plugin); return 0; } n[count + got] = NULL; return 1; } static void LoadSecurityPlugin(const char *name) { const char *d; size_t l; if( name == NULL ) return; l = strlen(name); d = Plugin_path_DYN; if( d == NULL ) return; while( *d != '\0' ) { char *filename; const char *e; struct stat s; int i; e = strchr(d, ':'); if( e == NULL ) e = strchr(d, '\0'); filename = malloc_or_die((e-d)+l+5, __FILE__, __LINE__); memcpy(filename, d, e-d); filename[e-d] = '/'; memcpy(filename + (e-d) + 1, name, l); memcpy(filename + (e-d) + 1 + l, ".so", 4); i = lstat(filename, &s); if( i == 0 && S_ISLNK(s.st_mode) ) { ssize_t linklen; char linkname[MAXPATHLEN]; linklen = readlink(filename, linkname, sizeof(linkname)); if( linklen > 0 || linklen name; plp_snprintf( str+len,maxlen-len, "%s%s",len?",":"",name ); len += strlen(str+len); } return( str ); } const struct security *FindSecurity( const char *name ) { const struct security *s, **p; for( p = SecuritySupported ; p != NULL && (s = *p) != NULL ; p++ ) { if( !Globmatch(s->name, name ) ) return s; } #ifdef WITHPLUGINS LoadSecurityPlugin(name); for( p = SecuritySupported ; p != NULL && (s = *p) != NULL ; p++ ) { if( !Globmatch(s->name, name ) ) return s; } #endif return NULL; } lprng-3.8.B/src/common/controlword.c0000644000131400013140000000455111531672131014403 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "control.h" /**** ENDINCLUDE ****/ static struct keywords controlwords[] = { { "ABORT", N_("ABORT"), OP_ABORT, 0, 0, 0, 0}, { "ACTIVE", N_("ACTIVE"), OP_ACTIVE, 0, 0, 0, 0}, { "CLASS", N_("CLASS"), OP_CLASS, 0, 0, 0, 0}, { "CLIENT", N_("CLIENT"), OP_CLIENT, 0, 0, 0, 0}, { "DEBUG", N_("DEBUG"), OP_DEBUG, 0, 0, 0, 0}, { "DEFAULTQ", N_("DEFAULTQ"), OP_DEFAULTQ, 0, 0, 0, 0}, { "DISABLE", N_("DISABLE"), OP_DISABLE, 0, 0, 0, 0}, { "DOWN", N_("DOWN"), OP_DOWN, 0, 0, 0, 0}, { "ENABLE", N_("ENABLE"), OP_ENABLE, 0, 0, 0, 0}, { "HOLD", N_("HOLD"), OP_HOLD, 0, 0, 0, 0}, { "HOLDALL", N_("HOLDALL"), OP_HOLDALL, 0, 0, 0, 0}, { "KILL", N_("KILL"), OP_KILL, 0, 0, 0, 0}, { "LPD", N_("LPD"), OP_LPD, 0, 0, 0, 0}, { "LPQ", N_("LPQ"), OP_LPQ, 0, 0, 0, 0}, { "LPRM", N_("LPRM"), OP_LPRM, 0, 0, 0, 0}, { "MOVE", N_("MOVE"), OP_MOVE, 0, 0, 0, 0}, { "MSG", N_("MSG"), OP_MSG, 0, 0, 0, 0}, { "NOHOLDALL", N_("NOHOLDALL"), OP_NOHOLDALL, 0, 0, 0, 0}, { "PRINTCAP", N_("PRINTCAP"), OP_PRINTCAP, 0, 0, 0, 0}, { "REDIRECT", N_("REDIRECT"), OP_REDIRECT, 0, 0, 0, 0}, { "REDO", N_("REDO"), OP_REDO, 0, 0, 0, 0}, { "RELEASE", N_("RELEASE"), OP_RELEASE, 0, 0, 0, 0}, { "REREAD", N_("REREAD"), OP_REREAD, 0, 0, 0, 0}, { "START", N_("START"), OP_START, 0, 0, 0, 0}, { "STATUS", N_("STATUS"), OP_STATUS, 0, 0, 0, 0}, { "STOP", N_("STOP"), OP_STOP, 0, 0, 0, 0}, { "TOPQ", N_("TOPQ"), OP_TOPQ, 0, 0, 0, 0}, { "UP", N_("UP"), OP_UP, 0, 0, 0, 0}, { "SERVER", N_("SERVER"), OP_SERVER, 0, 0, 0, 0}, { "DEFAULTS", N_("DEFAULTS"), OP_DEFAULTS, 0, 0, 0, 0}, { "FLUSH", N_("FLUSH"), OP_FLUSH, 0, 0, 0, 0}, { "LANG", N_("LANG"), OP_LANG, 0, 0, 0, 0}, { "PPD", N_("PPD"), OP_PPD, 0, 0, 0, 0}, {0,0,0,0,0,0,0} }; /*************************************************************************** * Get_controlword() * - decode the control word and return a key ***************************************************************************/ int Get_controlword( char *s ) { return( Get_keyval( s, controlwords ) ); } const char *Get_controlstr( int c ) { return( Get_keystr( c, controlwords ) ); } lprng-3.8.B/src/common/lpq.c0000644000131400013140000004077111531672132012630 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * *************************************************************************** * MODULE: lpq.c * PURPOSE: **************************************************************************/ /*************************************************************************** * SYNOPSIS * lpq [ -PPrinter_DYN ] * lpq [-Pprinter ]*[-a][-U username][-s][-l][+[n]][-Ddebugopt][job#][user] * DESCRIPTION * lpq sends a status request to lpd(8) * and reports the status of the * specified jobs or all jobs associated with a user. lpq * invoked without any arguments reports on the printer given * by the default printer (see -P option). For each job sub- * mitted (i.e. invocation of lpr(1)) lpq reports the user's * name, current rank in the queue, the names of files compris- * ing the job, the job identifier (a number which may be sup- * plied to lprm(1) for removing a specific job), and the total * size in bytes. Job ordering is dependent on the algorithm * used to scan the spooling directory and is FIFO (First in * First Out), in order of priority level. File names compris- * ing a job may be unavailable (when lpr(1) is used as a sink * in a pipeline) in which case the file is indicated as * ``(STDIN)''. * -P printer * Specifies a particular printer, otherwise the default * line printer is used (or the value of the PRINTER vari- * able in the environment). If PRINTER is not defined, * then the first entry in the /etc/printcap(5) file is * reported. Multiple printers can be displayed by speci- * fying more than one -P option. * * -a All printers listed in the /etc/printcap(5) file are * reported. * * -l An alternate display format is used, which simply * reports the user, jobnumber, and originating host. * * [+[n]] * Forces lpq to periodically display the spool queues. * Supplying a number immediately after the + sign indi- * cates that lpq should sleep n seconds in between scans * of the queue. * Note: the screen will be cleared at the start of each * display using the 'curses.h' package. **************************************************************************** * * Implementation Notes * Patrick Powell Tue May 2 09:58:29 PDT 1995 * * The LPD server will be returning the formatted status; * The format can be the following: * * SHORT: * Warning: lp is down: lp is ready and printing * Warning: no daemon present * Rank Owner Job Files Total Size * active root 30 standard input 5 bytes * 2nd root 31 standard input 5 bytes * * LONG: * * Warning: lp is down: lp is ready and printing * Warning: no daemon present * * root: 1st [job 030taco] * standard input 5 bytes * * root: 2nd [job 031taco] * standard input 5 bytes * */ #include "lp.h" #include "child.h" #include "getopt.h" #include "getprinter.h" #include "getqueue.h" #include "initialize.h" #include "linksupport.h" #include "sendreq.h" #include "user_auth.h" /**** ENDINCLUDE ****/ #undef EXTERN #undef DEFINE #define EXTERN #define DEFINE(X) X #include "lpq.h" /**** ENDINCLUDE ****/ static const char *Printer_to_show; /* TODO: why is that not used?: */ static char *Username_JOB; static void usage(void) { char buffer[128]; FPRINTF( STDERR, _("usage: %s [-aAclV] [-Ddebuglevel] [-Pprinter] [-tsleeptime]\n" " -A - use authentication specified by AUTH environment variable\n" " -a - all printers\n" " -c - clear screen before update\n" " -l - increase (lengthen) detailed status information\n" " additional l flags add more detail.\n" " -L - maximum detailed status information\n" " -n linecount - linecount lines of detailed status information\n" " -Ddebuglevel - debug level\n" " -Pprinter - specify printer\n" " -s - short (summary) format\n" " -tsleeptime - sleeptime between updates\n" " -V - print version information\n" " -v - print in key: value format\n"), Name ); FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); Parse_debug("=",-1); FPRINTF( STDOUT, "%s\n", Version ); exit(1); } /*************************************************************************** * main() * - top level of LPQ * ****************************************************************************/ int main(int argc, char *argv[], char *envp[]) { int i; struct line_list l, options; Init_line_list(&l); Init_line_list(&options); /* set signal handlers */ (void) plp_signal (SIGHUP, cleanup_HUP); (void) plp_signal (SIGINT, cleanup_INT); (void) plp_signal (SIGQUIT, cleanup_QUIT); (void) plp_signal (SIGTERM, cleanup_TERM); (void) signal (SIGPIPE, SIG_IGN); (void) signal (SIGCHLD, SIG_DFL); /* * set up the user state */ #ifndef NODEBUG Debug = 0; #endif Longformat = 1; Status_line_count = 0; Printer_to_show = NULL; Displayformat = REQ_DLONG; Initialize(argc, argv, envp, 'D' ); Setup_configuration(); Get_parms(argc, argv ); /* scan input args */ if( Auth && !getenv("AUTH") ){ FPRINTF(STDERR,_("authentication requested (-A option) and AUTH environment variable not set")); usage(); } if(DEBUGL1)Dump_line_list("lpq- Config", &Config_line_list ); /* we do the individual printers */ if( Displayformat == REQ_DLONG && Longformat && Status_line_count <= 0 ){ Status_line_count = (1 << (Longformat-1)); } do { Free_line_list(&Printer_list); if( Clear_scr ){ Term_clear(); Write_fd_str(1,Time_str(0,0)); Write_fd_str(1,"\n"); } if( All_printers ){ DEBUG1("lpq: all printers"); Get_all_printcap_entries(); if(DEBUGL1)Dump_line_list("lpq- All_line_list", &All_line_list ); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,All_line_list.list[i] ); Show_status(argv); } } else { /* set up configuration */ Set_DYN(&Printer_DYN, Printer_to_show); Get_printer(); Show_status(argv); } DEBUG1("lpq: done"); Remove_tempfiles(); DEBUG1("lpq: tempfiles removed"); if( Interval > 0 ){ plp_sleep( Interval ); } /* we check to make sure that nobody killed the output */ } while( Interval > 0 ); DEBUG1("lpq: after loop"); /* if( Clear_scr ){ Term_finish(); } */ Errorcode = 0; DEBUG1("lpq: cleaning up"); cleanup(0); } static void Show_status(char **argv) { int fd; char msg[LINEBUFFER]; DEBUG1("Show_status: start"); Fix_Rm_Rp_info(0,0); if( ISNULL(RemotePrinter_DYN) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - cannot get status from device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Displayformat != REQ_DSHORT && safestrcasecmp(Printer_DYN, RemotePrinter_DYN) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s is %s@%s\n"), Printer_DYN, RemotePrinter_DYN, RemoteHost_DYN ); DEBUG1("Show_status: '%s'",msg); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); } if( Check_for_rg_group( Logname_DYN ) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - cannot use printer, not in privileged group\n"), Printer_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Direct_DYN && Lp_device_DYN ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - direct connection to device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Auth ){ Set_DYN(&Auth_DYN, getenv("AUTH") ); } fd = Send_request( 'Q', Displayformat, &argv[Optind], Connect_timeout_DYN, Send_query_rw_timeout_DYN, 1 ); if( fd >= 0 ){ /* shutdown( fd, 1 ); */ if( Read_status_info( RemoteHost_DYN, fd, 1, Send_query_rw_timeout_DYN, Displayformat, Status_line_count ) ){ cleanup(0); } close(fd); fd = -1; } DEBUG1("Show_status: end"); } /*************************************************************************** *int Read_status_info( int ack, int fd, int timeout ); * ack = ack character from remote site * sock = fd to read status from * char *host = host we are reading from * int output = output fd * We read the input in blocks, split up into lines, * and then pass the lines to a lower level routine for processing. * We run the status through the SNPRINTF() routine, which will * rip out any unprintable characters. This will prevent magic escape * string attacks by users putting codes in job names, etc. ***************************************************************************/ int Read_status_info( char *host UNUSED, int sock, int output, int timeout, int displayformat, int status_line_count ) { int n, status, count, line, last_line, same; char header[SMALLBUFFER], buffer[SMALLBUFFER]; char *s, *t; struct line_list l; int look_for_pr = 0; Init_line_list(&l); header[0] = 0; status = count = 0; /* long status - trim lines */ DEBUG1("Read_status_info: output %d, timeout %d, dspfmt %d", output, timeout, displayformat ); DEBUG1("Read_status_info: status_line_count %d", status_line_count ); DEBUG1("Read_status_info: displayformat %d, Show_all %d",displayformat, Show_all ); /* * Do not try to be fancy - the overhead is not high unless lots * of data and then something is wrong. */ if( displayformat == REQ_VERBOSE || displayformat == REQ_LPSTAT || Show_all ){ do{ n = Read_fd_len_timeout( Send_query_rw_timeout_DYN, sock, buffer, sizeof(buffer)-1); if( n ){ buffer[n] = 0; if( Write_fd_str( output, buffer ) < 0 ) return(1); } } while( n > 0 ); return 0; } Read_fd_and_split( &l, sock, Line_ends, 0, 0, 0, 0, 0 ); if(DEBUGL1)Dump_line_list("lpq- status", &l ); last_line = -1; /* now deal with the short status format */ if( displayformat == REQ_DSHORT ){ for( line = 0; line < l.count; ++line ){ s = l.list[line]; if( s && !Find_exists_value(&Printer_list,s,0) ){ if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); Add_line_list(&Printer_list,s,0,1,0); } } return(0); } same = 0; header[0] = 0; last_line = -1; look_for_pr = 1; for( line = 0; line < l.count; ){ /* we start by looking at the first line and seeing if it is * for a printer that we have already found * if look_for_pr is 1 then we have just started the search * - we assume that any non-blank line not containing a Printer: * line is a 'proper' entry. * if look_for_pr is 2 then we assume that we are looking for * the end of a printer entry and we look for a line with * Printer: in it that we have not seen */ while( look_for_pr && line < l.count ){ s = l.list[line]; /* we do not want a line starting with a space or a blank line */ if( ISNULL(s) ){ look_for_pr = 1; } else if( look_for_pr == 1 && !(strstr(s,"Printer:") || strstr(s,_("Printer:")) ) ){ look_for_pr = 0; } else if( isspace(cval(s)) /* if line starts with a space */ /* line does not contain Printer: */ || !(strstr(s,"Printer:") || strstr(s,_("Printer:")) ) /* or that already is in the list */ || Find_exists_value(&Printer_list,s,0) ){ look_for_pr = 2; } else { look_for_pr = 0; } if( look_for_pr == 0 ){ if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); if( strstr(s,"Printer:") || strstr(s,_("Printer:")) ){ Add_line_list(&Printer_list,s,0,1,0); } DEBUG1("Read_status_info: pr [%d] '%s'", line, s ); } ++line; } header[0] = 0; last_line = -1; while( !look_for_pr && line < l.count ){ s = l.list[line]; DEBUG1("Read_status_info: last_line %d, header '%s', checking [%d] '%s'", last_line, header, line, s ); /* find up to the first colon */ if( s == 0 ){ ++line; continue; } if( !Rawformat ){ if( (t = safestrchr(s,':')) ){ *t = 0; } same = 1; if( last_line == -1 ){ last_line = line; safestrncpy( header, s ); if( t ) *t = ':'; ++line; continue; } if( (same = isspace(cval(s))) ){ same = !safestrcmp( header, s ); } if( t ) *t = ':'; if( same ){ ++line; continue; } DEBUG1("Read_status_info: header '%s', same %d", header, same ); n = line - status_line_count; if( n < last_line ) n = last_line; for( ; n < line; ++n ){ t = l.list[n]; if( Write_fd_str( output, t ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); } if( !isspace(cval(s)) && (strstr(s,"Printer:") || strstr(s,_("Printer:")) ) ){ look_for_pr = 1; } header[0] = 0; last_line = -1; } else { if( !isspace(cval(s)) && (strstr(s,"Printer:") || strstr(s,_("Printer:")) ) ){ look_for_pr = 1; } else { if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); ++line; } } } } DEBUG1("Read_status_info: after checks look_for_pr %d, line %d, last_line %d", look_for_pr, line, last_line); if( !look_for_pr && last_line >= 0 ){ n = l.count - status_line_count; if( n < last_line ) n = last_line; for( ; n < l.count; ++n ){ s = l.list[n]; if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); } } Free_line_list(&l); Free_line_list(&l); DEBUG1("Read_status_info: done" ); return(0); } static void Term_clear(void) { #if defined(CLEAR) int pid, n; plp_status_t procstatus; if( (pid = dofork(0)) == 0 ){ setuid( OriginalRUID ); close_on_exec(3); execl(CLEAR,CLEAR,(char*)NULL); exit(1); } else if( pid < 0 ){ logerr_die(LOG_ERR, _("fork() failed") ); } while( (n = plp_waitpid(pid,&procstatus,0)) != pid ){ int err = errno; DEBUG1("Filterprintcap: waitpid(%d) returned %d, err '%s'", pid, n, Errormsg(err) ); if( err == EINTR ) continue; logerr(LOG_ERR, _("Term_clear: waitpid(%d) failed"), pid); exit(1); } #else Write_fd_str(1,"\014"); #endif } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ static void Get_parms(int argc, char *argv[] ) { int option; char *name, *s, *t; if( argv[0] && (name = safestrrchr( argv[0], '/' )) ) { ++name; } else { name = argv[0]; } /* check to see if we simulate (poorly) the LP options */ if( name && safestrcmp( name, "lpstat" ) == 0 ){ FPRINTF( STDERR,_("lpq: please use the LPRng lpstat program\n")); exit(1); } else { /* scan the input arguments, setting up values */ while ((option = Getopt (argc, argv, "AD:P:VacLn:lst:vU:" )) != EOF) { switch (option) { case 'A': Auth = 1; break; case 'D': Parse_debug(Optarg,1); break; case 'P': if( Optarg == 0 ) usage(); Printer_to_show = Optarg; break; case 'V': ++Verbose; break; case 'a': Set_DYN(&Printer_DYN,ALL); All_printers = 1; break; case 'c': Clear_scr = 1; break; case 'l': ++Longformat; break; case 'n': Status_line_count = atoi( Optarg ); break; case 'L': Longformat = 0; Rawformat = 1; break; case 's': Longformat = 0; Displayformat = REQ_DSHORT; break; case 't': if( Optarg == 0 ) usage(); Interval = atoi( Optarg ); break; case 'v': Longformat = 0; Displayformat = REQ_VERBOSE; break; case 'U': Username_JOB = Optarg; break; default: usage(); } } } if( Verbose ) { FPRINTF( STDOUT, "%s\n", Version ); if( Verbose > 1 ){ if( (s = getenv("LANG")) ){ FPRINTF( STDOUT, _("LANG environment variable '%s'\n"), s ); t = _(""); if( t && *t ){ FPRINTF( STDOUT, _("gettext translation information '%s'\n"), t ); } else { FPRINTF( STDOUT, "%s", _("No translation available\n")); } } else { FPRINTF( STDOUT, "LANG environment variable not set\n" ); } Printlist( Copyright, 2 ); } } } lprng-3.8.B/src/common/lpr.c0000644000131400013140000011443711531672132012632 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "child.h" #include "errorcodes.h" #include "fileopen.h" #include "getopt.h" #include "getprinter.h" #include "getqueue.h" #include "gethostinfo.h" #include "initialize.h" #include "linksupport.h" #include "printjob.h" #include "sendjob.h" #include "user_auth.h" #include "openprinter.h" /**** ENDINCLUDE ****/ #undef EXTERN #undef DEFINE #define EXTERN #define DEFINE(X) X #include "lpr.h" /**** ENDINCLUDE ****/ /*************************************************************************** * main() * - top level of LPR Lite. This is a cannonical method of handling * input. Note that we assume that the LPD daemon will handle all * of the dirty work associated with formatting, printing, etc. * * 1. get the debug level from command line arguments * 2. set signal handlers for cleanup * 3. get the Host computer Name and user Name * 4. scan command line arguments * 5. check command line arguments for consistency * 6. if we are spooling from STDIN, copy stdin to a file. * 7. if we have a list of files, check each for access * 8. create a control file * 9. send control file to server * ****************************************************************************/ int main(int argc, char *argv[], char *envp[]) { off_t job_size; char *s, *t, buffer[SMALLBUFFER], *send_to_pr = 0; struct job prjob; struct line_list opts, newargs; int attempt = 0; int n; #ifndef NODEBUG Debug = 0; #endif /* set signal handlers */ Is_lpr = 1; Init_line_list( &newargs ); Init_line_list( &opts ); memset(&prjob, 0, sizeof(prjob) ); (void) plp_signal (SIGHUP, cleanup_HUP); (void) plp_signal (SIGINT, cleanup_INT); (void) plp_signal (SIGQUIT, cleanup_QUIT); (void) plp_signal (SIGTERM, cleanup_TERM); (void) signal(SIGCHLD, SIG_DFL); (void) signal(SIGPIPE, SIG_IGN); /* * set up the defaults */ Errorcode = 1; Initialize(argc, argv, envp, 'D' ); Setup_configuration(); Job_number = DbgTest; /* scan the input arguments, setting up values */ Get_parms(argc, argv); /* scan input args */ if( Auth_JOB && !getenv( "AUTH" ) ){ FPRINTF(STDERR, _("authentication requested (-A option) and AUTH environment variable not set") ); usage(); } /* Note: we may need the open connection to the remote printer to get our IP address if it is not available */ if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("lpr: after init open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } again: Free_job(&prjob); Get_printer(); Fix_Rm_Rp_info(0,0); DEBUG1("lpr: Lpr_opts_DYN '%s', argc %d", Lpr_opts_DYN, argc ); if( Lpr_opts_DYN ){ int i, j; Split_cmd_line( &opts, Lpr_opts_DYN ); Check_max( &newargs, argc+2+opts.count+2 ); i = j = 0; newargs.list[newargs.count++] = argv[0]; for( j = 0; j < opts.count; ++j ){ newargs.list[newargs.count++] = opts.list[j]; } for( j = 1; j < argc; ++j ){ newargs.list[newargs.count++] = argv[j]; } newargs.list[newargs.count] = 0; if(DEBUGL1)Dump_line_list("lpr - new options",&newargs ); Optind = 0; Files.count = 0; Getopt(0,0,0); Get_parms(newargs.count, newargs.list); /* scan input args */ newargs.count = 0; } job_size = Make_job(&prjob); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("lpr: after Make_job open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } /* * Fix the rest of the control file */ if( job_size == 0 ){ Free_job(&prjob); Errorcode = 1; fatal(LOG_INFO, _("nothing to print")); } if( Check_for_rg_group( Logname_DYN ) ){ Errorcode = 1; fatal(LOG_INFO, _("cannot use printer - not in privileged group\n") ); } if( Remote_support_DYN ) uppercase( Remote_support_DYN ); if( safestrchr( Remote_support_DYN, 'R' ) == 0 ){ Errorcode = 1; fatal(LOG_INFO, _("no remote support for %s@%s"), RemotePrinter_DYN,RemoteHost_DYN ); } /* we check to see if we need to do control file filtering */ /* we do not do any translation of formats */ s = 0; n = Find_flag_value( &prjob.info,DATAFILE_COUNT); if( Max_datafiles_DYN > 0 && n > Max_datafiles_DYN ){ Errorcode = 1; fatal(LOG_INFO, _("%d data files and maximum allowed %d"), n, Max_datafiles_DYN ); } send_to_pr = 0; if( Direct_JOB ){ /* check to see if we have a socket connection specified */ send_to_pr = Printer_JOB; } else if( Direct_DYN ){ send_to_pr = Lp_device_DYN; } Force_localhost_DYN = 0; if( send_to_pr ){ Force_localhost_DYN = 0; Lpr_bounce_DYN = Lpr_bounce_JOB = 0; send_to_pr = safestrdup(send_to_pr,__FILE__,__LINE__); Expand_percent(&send_to_pr); } DEBUG1("lpr: send_to_pr '%s'", send_to_pr ); if( Lpr_bounce_DYN || Lpr_bounce_JOB ){ int tempfd; struct stat statb; char *tempfile, *old_lp_value; struct line_list *lp; if(DEBUGL2) Dump_job( "lpr - before filtering", &prjob ); tempfd = Make_temp_fd(&tempfile); old_lp_value = safestrdup(Find_str_value( &PC_entry_line_list, "lp"), __FILE__,__LINE__); Set_str_value( &PC_entry_line_list, LP, tempfile ); /* Print_job( output_device, status_device, job, timeout, poll_for_status ) */ Print_job( tempfd, -1, &prjob, 0, 0, User_filter_JOB ); Set_str_value( &PC_entry_line_list, LP, old_lp_value ); if( old_lp_value ) free( old_lp_value ); old_lp_value = 0; close(tempfd); tempfd = Checkread( tempfile, &statb ); if( tempfd < 0 ){ Errorcode = JABORT; fatal(LOG_INFO, _("Cannot open file '%s', %s"), tempfile, Errormsg( errno ) ); } close(tempfd); DEBUG2("lpr: jobs size now %0.0f", (double)(statb.st_size)); job_size = statb.st_size; Free_listof_line_list(&prjob.datafiles); lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&prjob.datafiles,1); prjob.datafiles.list[prjob.datafiles.count++] = (void *)lp; Set_str_value(lp,OPENNAME,tempfile); Set_str_value(lp,"N",_("(lpr_filter)")); Set_flag_value(lp,COPIES,1); Set_double_value(lp,SIZE,job_size); Fix_bq_format( 'f', lp ); User_filter_JOB = 0; } if(DEBUGL1)Dump_job("lpr - before Fix_control",&prjob); Fix_control( &prjob, Control_filter_DYN, 0, 1 ); if(DEBUGL1)Dump_job("lpr - after Fix_control",&prjob); if( send_to_pr && ((!strchr(send_to_pr,'@') && strchr(send_to_pr,'%')) || (send_to_pr[0] == '/') || strchr(send_to_pr,'|')) ){ int fd, pid, status_fd, poll_for_status; char *id; setstatus(&prjob, "destination '%s'", send_to_pr ); Errorcode = 0; fd = pid = status_fd = poll_for_status = 0; fd = Printer_open(send_to_pr, &status_fd, &prjob, Lpr_send_try_DYN, Connect_interval_DYN, Max_connect_interval_DYN, Connect_grace_DYN, Connect_timeout_DYN, &pid, &poll_for_status ); /* note: we NEVER return fd == 0 or horrible things have happened */ DEBUG1("lpr: fd %d", fd ); if( fd <= 0 ){ Errorcode = JFAIL; goto exit; } id = Find_str_value(&prjob.info,IDENTIFIER); setstatus(&prjob, "transferring job '%s'", id ); /* Print_job( output_device, status_device, job, timeout, poll_for_status, filter ) */ Set_str_value( &PC_entry_line_list, LP, s ); Errorcode = Print_job( fd, status_fd, &prjob, Send_job_rw_timeout_DYN, poll_for_status, User_filter_JOB ); /* we close close device */ DEBUG1("lpr: shutting down fd %d", fd ); fd = Shutdown_or_close( fd ); DEBUG1("lpr: after shutdown fd %d, status_fd %d", fd, status_fd ); if( status_fd > 0 ){ /* we shut down this connection as well */ shutdown(status_fd,1); /* we wait for eof on status_fd */ buffer[0] = 0; Get_status_from_OF(&prjob,"LP",pid, status_fd, buffer, sizeof(buffer)-1, Send_job_rw_timeout_DYN, 0, 0, 0 ); } if( fd > 0 ) close( fd ); fd = -1; if( status_fd > 0 ) close( status_fd ); status_fd = -1; if( pid > 0 ){ setstatus(&prjob, "waiting for printer filter to exit"); Errorcode = Wait_for_pid( pid, "LP", 0, Send_job_rw_timeout_DYN ); } DEBUG1("lpr: status %s", Server_status(Errorcode) ); } else { Errorcode = 0; attempt = 1; do { if( Errorcode ){ if(DEBUGL1)Dump_job("lpr - after error",&prjob); buffer[0] = 0; plp_snprintf(buffer,sizeof(buffer), _("Status Information, attempt %d:\n"), attempt); if( Lpr_send_try_DYN ){ n = strlen(buffer)-2; plp_snprintf(buffer+n,sizeof(buffer)-n, _(" of %d:\n"), Lpr_send_try_DYN); } Write_fd_str(2,buffer); s = Join_line_list(&Status_lines,"\n "); if( (t = safestrrchr(s,' ')) ) *t = 0; Write_fd_str(2,s); if(s) free(s); s = 0; Init_line_list( &Status_lines ); ++attempt; n = Connect_interval_DYN + Connect_grace_DYN; if( n > 0 ){ buffer[0] = 0; plp_snprintf(buffer,sizeof(buffer), _("Waiting %d seconds before retry\n"), n); Write_fd_str(2,buffer); plp_sleep( n ); } Errorcode = 0; } Errorcode = Send_job( &prjob, &prjob, Connect_timeout_DYN, Connect_interval_DYN, Max_connect_interval_DYN, Send_job_rw_timeout_DYN, User_filter_JOB ); } while( Errorcode && (Lpr_send_try_DYN == 0 || attempt < Lpr_send_try_DYN) ); } exit: if( send_to_pr ) free(send_to_pr); send_to_pr = 0; if( Errorcode ){ Errorcode = 1; if(DEBUGL1)Dump_job("lpr - after error",&prjob); buffer[0] = 0; plp_snprintf(buffer,sizeof(buffer), _("Status Information, attempt %d:\n"), attempt); if( Lpr_send_try_DYN ){ n = strlen(buffer)-2; plp_snprintf(buffer+n,sizeof(buffer)-n, _(" of %d:\n"), Lpr_send_try_DYN); } s = Join_line_list(&Status_lines,"\n "); if( (t = safestrrchr(s,' ')) ) *t = 0; Write_fd_str(2,s); if(s) free(s); s = 0; cleanup(0); } if( LP_mode_JOB && !Silent_JOB ){ char *id; int n; char msg[SMALLBUFFER]; id = Find_str_value(&prjob.info,IDENTIFIER); if( id ){ plp_snprintf(msg,sizeof(msg)-1, _("request id is %s\n"), id ); } else { n = Find_decimal_value(&prjob.info,NUMBER); plp_snprintf(msg,sizeof(msg)-1, _("request id is %d\n"), n ); } Write_fd_str(1, msg ); } /* the dreaded -r (remove files) option */ if( Removefiles_JOB && !Errorcode ){ int i; /* eliminate any possible game playing */ To_user(); for( i = 0; i < Files.count; ++i ){ if( unlink( Files.list[i] ) == -1 ){ WARNMSG(_("Error unlinking '%s' - %s"), Files.list[i], Errormsg( errno ) ); } } } if( Job_number ){ plp_snprintf(buffer,sizeof(buffer), _("Done %d\n"), Job_number); Write_fd_str(1,buffer); ++Job_number; goto again; } Free_line_list( &newargs ); Free_line_list( &opts ); Free_job(&prjob); Free_line_list(&Files); cleanup(0); } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ static void usage(void); char LPR_optstr[] /* LPR options */ = "1:2:3:4:#:ABC:D:F:GJ:K:NP:QR:T:U:VX:YZ:bcdfghi:klm:nprstvw:" ; char LPR_bsd_optstr[] /* LPR options */ = "1:2:3:4:#:ABC:D:F:GJ:K:NP:QR:T:U:VX:YZ:bcdfghi:klmnprstvw:" ; char LP_optstr[] /* LP options */ = "ckmprswd:BD:f:GH:n:o:P:q:S:t:T:X:Yy:"; void Get_parms(int argc, char *argv[] ) { int option, i; char *name, *s; Verbose = 0; if( argv[0] && (name = safestrrchr( argv[0], '/' )) ) { ++name; } else { name = argv[0]; } /* check to see if we simulate (poorly) the LP options */ if( name && safestrcmp( name, "lp" ) == 0 ){ LP_mode_JOB = 1; } DEBUG1("Get_parms: LP_mode %d", LP_mode_JOB ); if( LP_mode_JOB ){ while( (option = Getopt( argc, argv, LP_optstr)) != EOF ){ DEBUG1("Get_parms: option %c", option ); switch( option ){ case 'A': Auth_JOB = 1; break; case 'B': Lpr_bounce_JOB = 1; break; case 'c': break; /* use symbolic link */ case 'k': Lpr_zero_file_JOB = 1; break; /* send input with 0 length */ case 'm': /* send mail */ Mailname_JOB = getenv( "USER" ); if( Mailname_JOB == 0 ){ DIEMSG( _("USER environment variable undefined") ); } break; case 'p': break; /* ignore notification */ case 'r': break; /* ignore this option */ case 's': Verbose = 0; Silent_JOB = 1; break; /* suppress messages flag */ case 'w': break; /* no writing of message */ case 'd': Set_DYN(&Printer_DYN, Optarg); /* destination */ Printer_JOB = Optarg; break; case 'D': Parse_debug(Optarg,1); break; case 'f': Classname_JOB = Optarg; break; case 'H': /* special handling - ignore */ break; case 'n': Copies_JOB = atoi( Optarg ); /* copies */ if( Copies_JOB <= 0 ){ DIEMSG( _("-ncopies -number of copies must be greater than 0\n")); } break; case 'o': if( safestrcasecmp( Optarg, "nobanner" ) == 0 || safestrcasecmp( Optarg,_("nobanner") ) == 0 ){ No_header_JOB = 1; } else if( safestrncasecmp( Optarg, "width", 5 ) == 0 || safestrncasecmp( Optarg,_("width"), 5 ) == 0 ){ s = safestrchr( Optarg, '=' ); if( s ){ Pwidth_JOB = atoi( s+1 ); } } else { /* pass as Zopts */ if( Zopts_JOB ){ s = Zopts_JOB; Zopts_JOB = safestrdup3(s,",",Optarg, __FILE__,__LINE__); free(s); } else { Zopts_JOB = safestrdup(Optarg, __FILE__,__LINE__); } } break; case 'P': break; /* ignore page lis */ case 'q': Priority_JOB = 'Z' - atoi(Optarg); /* get priority */ if(Priority_JOB < 'A' ) Priority_JOB = 'A'; if(Priority_JOB > 'Z' ) Priority_JOB = 'Z'; break; /* pass these as Zopts */ case 'S': case 'T': case 'y': /* pass as Zopts */ if( Zopts_JOB ){ s = Zopts_JOB; Zopts_JOB = safestrdup3(s,",",Optarg, __FILE__,__LINE__); free(s); } else { Zopts_JOB = safestrdup(Optarg, __FILE__,__LINE__); } break; case 't': Check_str_dup( option, &Jobname_JOB, Optarg); break; case 'X': Check_str_dup( option, &User_filter_JOB, Optarg); break; case 'Y': Direct_JOB = 1; break; default: usage(); break; } } } else { while( (option = Getopt (argc, argv, LPR_bsd_DYN?LPR_bsd_optstr:LPR_optstr )) != EOF ) { DEBUG1("Get_parms: option %c", option ); switch( option ){ case 'A': Auth_JOB = 1; break; case 'B': Lpr_bounce_JOB = 1; break; case '1': Check_str_dup( option, &Font1_JOB, Optarg); break; case '2': Check_str_dup( option, &Font2_JOB, Optarg); break; case '3': Check_str_dup( option, &Font3_JOB, Optarg); break; case '4': Check_str_dup( option, &Font4_JOB, Optarg); break; case 'C': Check_str_dup( option, &Classname_JOB, Optarg); break; case 'D': Parse_debug(Optarg,1); break; case 'F': if( safestrlen (Optarg) != 1 ){ DIEMSG( _("bad -F format string '%s'\n"), Optarg); } if( Format_JOB ){ DIEMSG( _("duplicate format specification -F%s\n"), Optarg); } else { Format_JOB = *Optarg; } break; case 'J': Check_str_dup( option, &Jobname_JOB, Optarg); break; case 'K': case '#': Check_int_dup( option, &Copies_JOB, Optarg, 0); if( Copies_JOB <= 0 ){ DIEMSG( _("-Kcopies -number of copies must be greater than 0\n")); } break; case 'N': Check_for_nonprintable_DYN = 0; break; case 'P': Printer_JOB = Optarg; Set_DYN(&Printer_DYN,Optarg); break; case 'Q': Use_queuename_flag_DYN = 1; break; case 'R': Check_str_dup( option, &Accntname_JOB, Optarg ); break; case 'T': Check_str_dup( option, &Prtitle_JOB, Optarg); break; case 'U': Check_str_dup( option, &Username_JOB, Optarg); break; case 'V': ++Verbose; break; case 'X': Check_str_dup( option, &User_filter_JOB, Optarg); break; case 'Y': Direct_JOB = 1; break; case 'o': /* same as Z */ case 'Z': if( Zopts_JOB ){ s = Zopts_JOB; Zopts_JOB = safestrdup3(s,",",Optarg, __FILE__,__LINE__); free(s); } else { Zopts_JOB = safestrdup(Optarg, __FILE__,__LINE__); } break; case 'k': Lpr_zero_file_JOB = 1; break; /* send input with 0 length */ case 'l': case 'b': Binary_JOB = 1; break; case 'h': No_header_JOB = 1; break; case 'i': Check_int_dup( option, &Indent_JOB, Optarg, 0); break; case 'm': /* * -m Mailname */ if( LPR_bsd_DYN ){ Mailname_JOB = getenv( "USER" ); if( Mailname_JOB == 0 ){ DIEMSG( _("USER environment variable undefined") ); } break; } if( Optarg[0] == '-' ){ DIEMSG( _("Missing mail name") ); } else { Mailname_JOB = Optarg; } break; case 'c': case 'd': case 'f': case 'g': case 'n': case 'p': case 't': case 'v': if( Format_JOB ){ DIEMSG( _("duplicate format specification -%c\n"), option); } else { Format_JOB = option; } break; case 'w': Check_int_dup( option, &Pwidth_JOB, Optarg, 0); break; /* Throw a sop to the whiners - let them wipe themselves out... */ /* remove files */ case 'r': Removefiles_JOB = 1; break; case 's': /* symbolic link - quietly ignored */ break; default: usage(); break; } } } /* * set up the Parms[] array */ for( i = Optind; i < argc; ++i ){ Add_line_list(&Files,argv[i],0,0,0); } if( Verbose ){ if( Verbose > 1 ){ Printlist( Copyright, 1 ); } else { Write_fd_str( 2, Version ); Write_fd_str( 2, "\n" ); } } } static void usage(void) { if(LP_mode_JOB ){ FPRINTF( STDERR, _("Usage: %s [-A] [-B] [-c] [-G] [-m] [-p] [-s] [-w] [-d printer@[host]]\n" " [-f form-name] [-H special-handling]\n" " [-n number] [-o options] [-P page-list]\n" " [-q priority-level] [-S character-set]\n" " [-S print-wheel] [-t title]\n" " [-T content-type [-r]] [-y mode-list]\n" " [-Ddebugopt ] [ filenames ... ]\n" " lp simulator using LPRng, functionality may differ slightly\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -c - (make copy before printing - ignored)\n" " -d printer[@host] - printer on host\n" " -D debugflags - debugging flags\n" " -f formname - first letter used as job format\n" " -G - filter individual job files before sending\n" " -H handling - (passed as -Z handling)\n" " -m - mail sent to $USER on completion\n" " -n copies - number of copies\n" " -o option nobanner, width recognized\n" " (others passed as -Z option)\n" " -P pagelist - (print page list - ignored)\n" " -p - (notification on completion - ignored)\n" " -q - priority - 0 -> Z (highest), 25 -> A (lowest)\n" " -s - (suppress messages - ignored)\n" " -S charset - (passed as -Z charset)\n" " -t title - job title\n" " -T content - (passed as -Z content)\n" " -w - (write message on completion - ignored)\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -y mode - (passed as -Z mode)\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NGPRINTER, NPRINTER environment variables set default printer.\n"), Name ); } else { FPRINTF( STDERR, _("Usage: %s [-Pprinter[@host]] [-A] [-B] [-Cclass] [-Fformat] [-G] [-Jinfo]\n" " [-(K|#)copies] [-Q] [-Raccountname] [-Ttitle] [-Uuser[@host]] [-V]\n" " [-Zoptions] [-b] [-m mailaddr] [-h] [-i indent] [-l] [-w width ] [-r]\n" " [-Ddebugopt ] [--] [ filenames ... ]\n" " -A - use authentication specified by AUTH environment variable\n" " -B - filter files and reduce job to single file before sending\n" " -C class - job class\n" " -D debugopt - debugging flags\n" " -F format - job format\n" " -b,-l - binary or literal format\n" " c,d,f,g,l,m,p,t,v are also format options\n" " -G - filter individual job files before sending\n" " -J info - banner and job information\n" " -K copies, -# copies - number of copies\n" " -P printer[@host] - printer on host\n" " -Q - put 'queuename' in control file\n" " -Raccntname - accounting information\n" " -T title - title for 'pr' (-p) formatting\n" " -U username - override user name (restricted)\n" " -V - Verbose information during spooling\n" " -X path - user specified filter for job files\n" " -Y - connect and send to TCP/IP port (direct mode)\n" " -Z options - options to pass to filter\n" " -h - no header or banner page\n" " -i indent - indentation\n" " -k - do not use tempfile when sending to server\n" " -m mailaddr - mail final status to mailaddr\n" " -r - remove files after spooling\n" " -w width - width to use\n" " -- - end of options, files follow\n" " filename '-' reads from STDIN\n" " PRINTER, LPDEST, NPRINTER, NGPRINTER environment variables set default printer.\n"), Name ); } Parse_debug("=",-1); FPRINTF( STDERR, "%s\n", Version ); { char buffer[128]; FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); } exit(1); } /*************************************************************************** * Make_job Parms() * 1. we determine the name of the printer - Printer_DYN variable * 2. we determine the host name to be used - RemoteHost_DYN variable * 3. check the user name for consistency: * We have the user name from the environment * We have the user name from the -U option * Allow override if we are root or some silly system (like DOS) * that does not support multiple users ***************************************************************************/ static void get_job_number( struct job *job ); static double Copy_STDIN( struct job *job ); static double Check_files( struct job *job ); /*************************************************************************** * Commentary: * The struct control_file{} data structure contains fields that point to * complete lines in the control file, i.e.- 'Jjobname', 'Hhostname' * We set up this information in a data structure. * Note that this is specific to the LPR program * * Make_job() * 1. Get the control file number and name information * 2. scan the set of variables, and determine how much space is needed. * 3. scan the data files, and determine how much space is needed * 4. allocate the space. * 5. Copy variables to the allocated space, setting up pointers in the * control_file data structure. **************************************************************************/ static int Make_job( struct job *job ) { char nstr[SMALLBUFFER]; /* information */ struct jobwords *keys; /* keyword entry in the parameter list */ char *s, *name; /* buffer where we allocate stuff */ void *p; char *originate_hostname = 0; int i, n; double job_size = 0; if( Auth_JOB ){ Set_DYN(&Auth_DYN, getenv("AUTH") ); } if(DEBUGL4)Dump_line_list("Make_job - PC_entry",&PC_entry_line_list ); if(DEBUGL4)Dump_parms("Make_job",Pc_var_list); if(DEBUGL4)Dump_line_list("Make_job - job at start",&job->info ); /* check for priority in range */ if( Priority_JOB == 0 && Classname_JOB && !Break_classname_priority_link_DYN ) Priority_JOB = cval(Classname_JOB); if( Priority_JOB == 0 && Default_priority_DYN ) Priority_JOB = cval(Default_priority_DYN); if( Priority_JOB == 0 ) Priority_JOB = 'A'; if( islower(Priority_JOB) ) Priority_JOB = toupper( Priority_JOB ); if( !isupper( Priority_JOB ) ){ DIEMSG( _("Priority (first letter of Class) not 'A' (lowest) to 'Z' (highest)") ); } plp_snprintf(nstr,sizeof(nstr), "%c",Priority_JOB); Set_str_value(&job->info,PRIORITY,nstr); /* fix up the Classname_JOB 'C' option */ if( Classname_JOB == 0 ){ if( Backwards_compatible_DYN ){ Classname_JOB = ShortHost_FQDN; } else { plp_snprintf(nstr,sizeof(nstr), "%c",Priority_JOB); Classname_JOB = nstr; } } Set_str_value(&job->info,CLASS,Classname_JOB); if( Files.count == 1 && !safestrcmp("-", Files.list[0]) ){ Files.count = 0; } /* fix up the jobname */ if( Jobname_JOB == 0 ){ if( Files.count == 0 ){ Set_str_value(&job->info,JOBNAME,_("(STDIN)") ); } else { name = 0; for( i = 0; i < Files.count; ++i ){ s = Files.list[i]; if( safestrcmp(s, "-" ) == 0 ) s = _("(STDIN)"); name = safeextend3(name,name?",":"",s,__FILE__,__LINE__); } Set_str_value(&job->info,JOBNAME, name ); if( name ) free(name); name = 0; } } else { Set_str_value(&job->info,JOBNAME,Jobname_JOB ); } if(DEBUGL4)Dump_line_list("Make_job - after jobname",&job->info); /* fix up the banner name. * if you used the -U option, * check to see if you have root permissions * set to -U value * else set to log name of user * if No_header suppress banner */ if( Username_JOB ){ /* check to see if you were root */ if( 0 != OriginalRUID ){ struct line_list user_list; char *str, *t; struct passwd *pw; int found; uid_t uid; DEBUG2("Make_job: checking '%s' for -U perms", Allow_user_setting_DYN ); Init_line_list(&user_list); Split( &user_list, Allow_user_setting_DYN,File_sep,0,0,0,0,0,0); found = 0; for( i = 0; !found && i < user_list.count; ++i ){ str = user_list.list[i]; DEBUG2("Make_job: checking '%s'", str ); uid = strtol( str, &t, 10 ); if( str == t || *t ){ /* try getpasswd */ pw = getpwnam( str ); if( pw ){ uid = pw->pw_uid; } } DEBUG2( "Make_job: uid '%ld'", (long)uid ); found = ( uid == OriginalRUID ); DEBUG2( "Make_job: found '%d'", found ); } if( !found ){ DEBUG1( _("-U (username) can only be used by ROOT") ); Username_JOB = 0; } } } if( Username_JOB ){ Clean_meta(Username_JOB); if( (originate_hostname = strchr(Username_JOB,'@')) ){ *originate_hostname++ = 0; for( s = originate_hostname; cval(s); ++s ){ if( isspace(cval(s)) ){ *s = '_'; } } if( (s = Find_fqdn( &LookupHost_IP, originate_hostname )) == 0 ){ Errorcode = JABORT; fatal(LOG_ERR, _("Get_local_host: '%s' FQDN name not found!"), originate_hostname ); } else { originate_hostname = s; } } Set_DYN(&Logname_DYN, Username_JOB ); } if( !originate_hostname ) originate_hostname = FQDNHost_FQDN; Bnrname_JOB = Logname_DYN; if( No_header_JOB || Suppress_header_DYN ){ Bnrname_JOB = 0; } Set_str_value(&job->info,BNRNAME, Bnrname_JOB ); /* check the format */ DEBUG1("Make_job: before checking format '%c'", Format_JOB ); if( Binary_JOB ){ Format_JOB = 'l'; } if( Format_JOB == 0 && Default_format_DYN ) Format_JOB = *Default_format_DYN; if( Format_JOB == 0 ) Format_JOB = 'f'; if( isupper(Format_JOB) ) Format_JOB = tolower(Format_JOB); DEBUG1("Make_job: after checking format '%c'", Format_JOB ); if( safestrchr( "aios", Format_JOB ) || (Formats_allowed_DYN && !safestrchr( Formats_allowed_DYN, Format_JOB ) )){ DIEMSG( _("Bad format specification '%c'"), Format_JOB ); } plp_snprintf(nstr,sizeof(nstr), "%c",Format_JOB); Set_str_value(&job->info,FORMAT,nstr); /* check to see how many files you want to print- limit of 52 */ if( Max_datafiles_DYN > 0 && Files.count > Max_datafiles_DYN ){ DIEMSG( _("Sorry, can only print %d files at a time, split job up"), Max_datafiles_DYN); } if( Copies_JOB == 0 ){ Copies_JOB = 1; } if( Max_copies_DYN && Copies_JOB > Max_copies_DYN ){ DIEMSG( _("Maximum of %d copies allowed"), Max_copies_DYN ); } Set_flag_value(&job->info,COPIES,Copies_JOB); /* check the for the -Q flag */ DEBUG1("Make_job: 'qq' flag %d, queue '%s', force_queuename '%s'", Use_queuename_flag_DYN, Queue_name_DYN, Force_queuename_DYN ); if( Use_queuename_flag_DYN ){ Set_str_value(&job->info,QUEUENAME,Queue_name_DYN); } if( Force_queuename_DYN ){ Set_str_value(&job->info,QUEUENAME,Force_queuename_DYN); } get_job_number(job); Set_str_value(&job->info,FROMHOST,originate_hostname); if( isdigit(cval(originate_hostname)) ){ s = safestrdup2("ADDR",originate_hostname,__FILE__,__LINE__); Set_str_value(&job->info,FILE_HOSTNAME,s); if( s ) free(s); s = 0; } else { Set_str_value(&job->info,FILE_HOSTNAME,originate_hostname); } /* we put the option strings in the buffer */ for( keys = Lpr_parms; keys->key; ++keys ){ DEBUG2("Make_job: key '%s', maxlen %d, use '%s'", keys->keyword?*keys->keyword:0,keys->maxlen,keys->key); s = 0; /* see if we already have a value for this parameter. If not, then we set it */ if( keys->keyword ){ s = Find_str_value(&job->info,*keys->keyword); } p = keys->variable; nstr[0] = 0; n = 0; switch( keys->type ){ case INTEGER_K: if( s ){ n = strtol(s,0,0); } else if( p ){ n = *(int *)p; } if( n ) Set_decimal_value(&job->info,keys->key,n); break; case STRING_K: if( s == 0 && p ) s = *(char **)p; if( s ) Set_str_value(&job->info,keys->key,s); break; default: break; } } if(DEBUGL2)Dump_job("Make_job - job after", job ); /* * copy from standard in? */ /* now we check to see if we have zero length flag */ if( Lpr_zero_file_JOB ){ if( Auth_JOB || Auth_DYN ){ DIEMSG( _("authentication conficts with -k option")); } if( Send_block_format_DYN ){ DIEMSG( _("send_block_format configuration option conficts with -k option")); } if( Send_data_first_DYN ){ DIEMSG( _("send_data_first configuration option conficts with -k option")); } if(Copies_JOB > 1 ){ DIEMSG( _("multiple copies conficts with -k option")); } if(Files.count ){ DIEMSG( _("files on command line conflicts with -k option")); } } if( Files.count == 0 ){ if( Lpr_zero_file_JOB || Direct_JOB ){ struct line_list *lp; lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *) lp; Set_str_value(lp,"N","(STDIN)"); Set_flag_value(lp,COPIES,1); plp_snprintf(nstr,sizeof(nstr), "%c",Format_JOB); Set_str_value(lp,FORMAT,nstr); Set_double_value(lp,SIZE,0 ); Set_str_value(lp,OPENNAME,"-"); job_size = 1; /* make checker happy */ } else { job_size = Copy_STDIN( job ); job_size *= Copies_JOB; } } else { /* * check to see that the input files are printable */ job_size = Check_files( job ); job_size *= Copies_JOB; } if(DEBUGL2) Dump_job( "Make_job - final value", job ); return( job_size ); } /************************************************************************** * int get_job_number(); * - get an integer value for the job number **************************************************************************/ static void get_job_number( struct job *job ) { int number = Job_number; if( number == 0 ) number = getpid(); Fix_job_number( job, number ); } struct jobwords Lpr_parms[] = { { 0, STRING_K , &Accntname_JOB, M_ACCNTNAME, "R" }, { &BNRNAME, STRING_K , &Bnrname_JOB, M_BNRNAME, "L" }, { &CLASS, STRING_K , &Classname_JOB, M_CLASSNAME, "C" }, { 0, STRING_K , &Font1_JOB, M_FONT, "1" }, { 0, STRING_K , &Font2_JOB, M_FONT, "2" }, { 0, STRING_K , &Font3_JOB, M_FONT, "3" }, { 0, STRING_K , &Font4_JOB, M_FONT, "4" }, { &FROMHOST, STRING_K , &FQDNHost_FQDN, M_FROMHOST, "H" }, { 0, INTEGER_K , &Indent_JOB, M_INDENT, "I" }, { &JOBNAME, STRING_K , &Jobname_JOB, M_JOBNAME, "J" }, { &LOGNAME, STRING_K , &Logname_DYN, M_BNRNAME, "P" }, { 0, STRING_K , &Mailname_JOB, M_MAILNAME, "M" }, { 0, STRING_K , &Prtitle_JOB, M_PRTITLE, "T" }, { 0, INTEGER_K , &Pwidth_JOB, M_PWIDTH, "W" }, { 0, STRING_K , &Zopts_JOB, M_ZOPTS, "Z" }, { 0,0,0,0,0 } } ; /*************************************************************************** * off_t Copy_STDIN() * 1. we get the name of a temporary file * 2. we open the temporary file and read from STDIN until we get * no more. * 3. stat the temporary file to prevent games ***************************************************************************/ static double Copy_STDIN( struct job *job ) { int fd, count, printable = 1; double size = 0; char *tempfile; struct line_list *lp; struct stat statb; char buffer[LARGEBUFFER]; /* get a tempfile */ if( Copies_JOB == 0 ) Copies_JOB = 1; fd = Make_temp_fd( &tempfile ); if( fd < 0 ){ logerr_die(LOG_INFO, _("Make_temp_fd failed") ); } else if( fd == 0 ){ DIEMSG( _("You have closed STDIN! cannot pipe from a closed connection")); } DEBUG1("Temporary file '%s', fd %d", tempfile, fd ); size = 0; while( (count = ok_read( 0, buffer, sizeof(buffer))) > 0 ){ if( write( fd, buffer, count ) < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, _("Copy_STDIN: write to temp file failed")); } } if( fstat( fd, &statb ) != 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, _("Copy_STDIN: stat of temp fd '%d' failed"), fd); } printable = Check_lpr_printable( tempfile, fd, &statb, Format_JOB ); if( printable ){ size = statb.st_size; lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *) lp; Set_str_value(lp,"N","(STDIN)"); Set_str_value(lp,OPENNAME,tempfile); Set_str_value(lp,DFTRANSFERNAME,tempfile); Set_flag_value(lp,COPIES,1); plp_snprintf(buffer,sizeof(buffer), "%c",Format_JOB); Set_str_value(lp,FORMAT,buffer); Set_double_value(lp,SIZE,size); } else { size = 0; } close(fd); return( size ); } /*************************************************************************** * off_t Check_files( char **files, int filecount ) * 2. check each of the input files for access * 3. stat the files and get the size * 4. Check for printability * 5. Put information in the data_file{} entry ***************************************************************************/ static double Check_files( struct job *job ) { double size = 0; int i, fd, printable = 1; struct stat statb; char *s, *cs, *tempfile; char buffer[SMALLBUFFER]; struct line_list *lp; for( i = 0; i < Files.count; ++i){ tempfile = s = Files.list[i]; DEBUG2( "Check_files: doing '%s'", s ); if( safestrcmp( s, "-" ) == 0 ){ size += Copy_STDIN( job ); continue; } fd = Checkread( s, &statb ); if( fd < 0 ){ WARNMSG( _("Cannot open file '%s', %s"), s, Errormsg( errno ) ); continue; } printable = 1; if( User_filter_JOB == 0 ){ if( fstat( fd, &statb ) != 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, _("Check_files: stat of temp fd '%d' failed"), fd); } printable = Check_lpr_printable( s, fd, &statb, Format_JOB ); } close( fd ); if( printable > 0 ){ lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *) lp; Set_str_value(lp,OPENNAME,tempfile); Set_str_value(lp,DFTRANSFERNAME,s); cs = safestrdup(s,__FILE__,__LINE__); Clean_meta(cs); /* this will destroy the name fix by sharkey3 */ Set_str_value(lp,"N",cs); free(cs); Set_flag_value(lp,COPIES,1); plp_snprintf(buffer,sizeof(buffer), "%c",Format_JOB); Set_str_value(lp,FORMAT,buffer); size = size + statb.st_size; Set_double_value(lp,SIZE,(double)(statb.st_size) ); DEBUG2( "Check_files: printing '%s'", s ); } else { DEBUG2( "Check_files: not printing '%s'", s ); } } if( Copies_JOB ) size *= Copies_JOB; DEBUG2( "Check_files: %d files, size %0.0f", job->datafiles.count, size ); return( size ); } /*************************************************************************** * int Check_lpr_printable(char *file, int fd, struct stat *statb, int format ) * 1. Check to make sure it is a regular file. * 2. Check to make sure that it is not 'binary data' file * 3. If a text file, check to see if it has some control characters * ***************************************************************************/ static int Check_lpr_printable(char *file, int fd, struct stat *statb, int format ) { char buf[LINEBUFFER]; int n, i, c; /* Acme Integers, Inc. */ int printable = 0; char *err = _("cannot print '%s': %s"); if( Check_for_nonprintable_DYN == 0 ) return(1); /* * Do an LSEEK on the file, i.e.- see to the start * Ignore any error return */ lseek( fd, 0, SEEK_SET ); if(!S_ISREG( statb->st_mode )) { DIEMSG(err, file,_("not a regular file")); } else if(statb->st_size == 0) { /* empty file */ printable = -1; } else if ((n = ok_read (fd, buf, sizeof(buf))) <= 0) { DIEMSG (err, file,_("cannot read it")); } else if (format != 'p' && format != 'f' ){ printable = 1; } else { printable = 1; if( Min_printable_count_DYN && n > Min_printable_count_DYN ){ n = Min_printable_count_DYN; } for (i = 0; printable && i < n; ++i) { c = cval(buf+i); /* we allow backspace, escape, ^D */ if( !isprint( c ) && !isspace( c ) && c != 0x08 && c != 0x1B && c!= 0x04 ) printable = 0; } if( !printable ) DIEMSG (err, file, _("unprintable characters at start of file, check your LANG environment variable as well as the input file")); } return(printable); } static void Dienoarg(int option) { DIEMSG (_("option '%c' missing argument"), option); } /*************************************************************************** * Check_int_dup (int option, int *value, char *arg) * 1. check to see if value has been set * 2. if not, then get integer value from arg ***************************************************************************/ static void Check_int_dup (int option, int *value, char *arg, int maxvalue) { char *convert; if (arg == 0) { Dienoarg (option); } convert = arg; *value = strtol( arg, &convert, 10 ); if( *value < 0 || convert == arg || *convert ){ DIEMSG (_("option %c parameter `%s` is not positive integer value"), option, arg ); } if( maxvalue > 0 && *value > maxvalue ){ DIEMSG (_("option %c parameter `%s` is not integer value from 0 - %d"), option, arg, maxvalue ); } } /*************************************************************************** * Check_str_dup(int option, char *value, char *arg) * 1. check to see if value has been set * 2. if not, then set it ***************************************************************************/ static void Check_str_dup(int option, char **value, char *arg ) { if (arg == 0) { Dienoarg (option); } *value = arg; } lprng-3.8.B/src/common/fileopen.c0000644000131400013140000001245711531672131013634 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "fileopen.h" #include "errorcodes.h" #include "child.h" /**** ENDINCLUDE ****/ /*************************************************************************** Commentary: Patrick Powell Mon May 1 05:37:02 PDT 1995 These routines were created in order to centralize all file open and checking. Hopefully, if there are portability problems, these routines will be the only ones to change. ***************************************************************************/ /*************************************************************************** * int Checkread( char *file, struct stat *statb ) * open a file for reading, and check its permissions * Returns: fd of open file, -1 if error. ***************************************************************************/ int Checkread( const char *file, struct stat *statb ) { int fd = -1; int status = 0; int err = 0; /* open the file */ DEBUG3("Checkread: file '%s'", file ); if( (fd = open( file, O_RDONLY|O_NOCTTY, 0 ) )< 0 ){ Max_open(fd); status = -1; err = errno; DEBUG3( "Checkread: cannot open '%s', %s", file, Errormsg(err) ); memset( statb, 0, sizeof(struct stat) ); } if( status >= 0 && fstat( fd, statb ) < 0 ) { err = errno; logerr(LOG_ERR, "Checkread: fstat of '%s' failed, possible security problem", file); status = -1; } /* check for a security loophole: not a file */ if( status >= 0 && !(S_ISREG(statb->st_mode))){ /* AHA! not a regular file! */ DEBUG3( "Checkread: '%s' not regular file, mode = 0%o", file, (unsigned int)statb->st_mode ); status = -1; } if( status < 0 && fd >= 0 ){ close( fd ); fd = -1; } DEBUG3("Checkread: '%s' fd %d, size %0.0f", file, fd, (double)(statb->st_size) ); errno = err; return( fd ); } /*************************************************************************** * int Checkwrite( char *file, struct stat *statb, int rw, int create, * int nodelay ) * - if rw != 0, open for both read and write * - if create != 0, create if it does not exist * - if nodelay != 0, use nonblocking open * open a file or device for writing, and check its permissions * Returns: fd of open file, -1 if error. * status in *statb ***************************************************************************/ int Checkwrite( const char *file, struct stat *statb, int rw, int create, int nodelay ) { int fd = -1; int status = 0; int options = O_NOCTTY|O_APPEND; int mask, oldumask; int err = errno; /* open the file */ DEBUG3("Checkwrite: file '%s', rw %d, create %d, nodelay %d", file, rw, create, nodelay ); memset( statb, 0, sizeof( statb[0] ) ); if( nodelay ){ options |= NONBLOCK; } if( rw ){ options |= rw; } else { options |= O_WRONLY; } if( create ){ options |= O_CREAT; } /* turn off umask */ oldumask = umask( 0 ); fd = open( file, options, Is_server?Spool_file_perms_DYN:0600 ); Max_open(fd); err = errno; umask( oldumask ); if( fd < 0 ){ status = -1; DEBUG3( "Checkwrite: cannot open '%s', %s", file, Errormsg(err) ); } else if( nodelay ){ /* turn off nonblocking */ mask = fcntl( fd, F_GETFL, 0 ); if( mask == -1 ){ logerr(LOG_ERR, "Checkwrite: fcntl F_GETFL of '%s' failed", file); status = -1; } else if( mask & NONBLOCK ){ DEBUG3( "Checkwrite: F_GETFL value '0x%x', BLOCK 0x%x", mask, NONBLOCK ); mask &= ~NONBLOCK; mask = fcntl( fd, F_SETFL, mask ); err = errno; DEBUG3( "Checkwrite: after F_SETFL value now '0x%x'", fcntl( fd, F_GETFL, 0 ) ); if( mask == -1 && err != ENODEV && err != ENOTTY ){ errno = err; logerr(LOG_ERR, "Checkwrite: fcntl F_SETFL of '%s' failed", file ); status = -1; } } } if( status >= 0 && fstat( fd, statb ) < 0 ) { err = errno; logerr_die(LOG_ERR, "Checkwrite: fstat of '%s' failed, possible security problem", file); status = -1; } /* check for a security loophole: not a file */ if( status >= 0 && (S_ISDIR(statb->st_mode))){ /* AHA! Directory! */ DEBUG3( "Checkwrite: '%s' directory, mode 0%o", file, (unsigned int)statb->st_mode ); status = -1; } if( fd == 0 ){ int tfd; tfd = dup(fd); Max_open(tfd); err = errno; if( tfd < 0 ){ logerr(LOG_ERR, "Checkwrite: dup of '%s' failed", file); status = -1; } else { close(fd); fd = tfd; } } if( status < 0 ){ close( fd ); fd = -1; } DEBUG2("Checkwrite: file '%s' fd %d, inode 0x%x, perms 0%o", file, fd, (int)(statb->st_ino), (int)(statb->st_mode) ); errno = err; return( fd ); } /*************************************************************************** * int Checkwrite_timeout(int timeout, ... ) * Tries to do Checkwrite() with a timeout ***************************************************************************/ int Checkwrite_timeout(int timeout, const char *file, struct stat *statb, int rw, int create, int nodelay ) { int fd; if( Set_timeout() ){ Set_timeout_alarm( timeout ); fd = Checkwrite( file, statb, rw, create, nodelay ); } else { fd = -1; } Clear_timeout(); return(fd); } lprng-3.8.B/src/common/lpd_rcvjob.c0000644000131400013140000015374611531672132014167 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "child.h" #include "errorcodes.h" #include "fileopen.h" #include "gethostinfo.h" #include "getopt.h" #include "getqueue.h" #include "linksupport.h" #include "lockfile.h" #include "permission.h" #include "proctitle.h" #include "lpd_remove.h" #include "lpd_rcvjob.h" #include "lpd_jobs.h" /**** ENDINCLUDE ****/ static int Read_one_line( int timeout, int fd, char *buffer, int maxlen ); static int Get_route( struct job *job, char *error, int errlen ); static int Do_incoming_control_filter( struct job *job, char *error, int errlen ); static void Generate_control_file( struct job *job ); static int Find_non_colliding_job_number( struct job *job ); /*************************************************************************** * Commentary: * Patrick Powell Mon Apr 17 05:43:48 PDT 1995 * * The protocol used to send a job to a remote host consists of the * following: * * Client Server * \2printername\n - receive a job * \0 (ack) * \2count controlfilename\n * * \0 * \0 * \3count datafilename\n * * \0 * \0 * \3count datafilename\n * * \0 * \0 * * * 1. Read the control file from the other end. * 2. Check to see if the printer exists, and if has a printcap entry * 3. If it does, check the permissions for the user. * 4. Read the job to the queue. * * Control file processing * 1. The control file at this end might exist already, and be in use. * If this is the case, we will try and allocate another control * file name if the option is allowed. * 2. After we lock the control file, we will then try and read the * data files. Again, there might be a collision. If this is * the case, then we will again try to generate a new number. * * The control file is first read into a file and then read into memory, * where it is parsed. * * Duplicate Control/Data files: * When copying jobs over, you might get to a point where you * discover that a control and/or data file already exists. * * if file already exists: * 1. if the existing file length is 0, then you can clobber the file. * This is reasonable given file locking is working * and games are not being played with NFS file systems. * Most likely you have found an abandonded file. * 2. If you have the control file and it is locked, * then you might as well clobber the data files * as they are probably left over from another job. * If you do not have the control file, then you give up * 3. If the first file file is the control file, * and you cannot lock it or it is locked and has a non-zero length, * then you should rename the file and try again. * rename the data files/control files * This can be done if the first file is a control file * and you cannot lock it, or you lock it and it is * non-zero in length. * * Job Size: * when the total received job size exceeds limits, then abort job * when the available file space falls below limit, then abort job * ***************************************************************************/ int Receive_job( int *sock, char *input ) { char line[SMALLBUFFER]; /* line buffer for input */ char error[SMALLBUFFER]; /* line buffer for input */ char buffer[SMALLBUFFER]; /* line buffer for input */ int errlen = sizeof(error); char *tempfile; /* name of temp file */ double file_len; /* length of file */ double read_len; /* amount to read from sock */ double jobsize = 0; /* size of job */ int ack = 0; /* ack to send */ int status = 0; /* status of the last command */ double len; /* length of last read */ char *s, *filename; /* name of control or data file */ int temp_fd = -1; /* used for file opening and locking */ int filetype; /* type of file - control or data */ int fd; /* for log file */ int job_in_progress = 0; /* job in progress */ int db, dbf, rlen; int fifo_fd = -1; /* fifo lock file */ struct line_list files, info, l; struct job job; struct stat statb; int discarding_large_job = 0; Init_line_list(&l); Init_line_list(&files); Init_line_list(&info); Init_job(&job); Name = "RECV"; if( input && *input ) ++input; Clean_meta(input); Split(&info,input,Whitespace,0,0,0,0,0,0); DEBUGFC(DRECV1)Dump_line_list("Receive_job: input", &info ); if( info.count != 1 ){ plp_snprintf( error, errlen, _("bad command line") ); goto error; } if( Is_clean_name( info.list[0] ) ){ plp_snprintf( error, errlen, _("bad printer name") ); goto error; } setproctitle( "lpd RECV '%s'", info.list[0] ); if( Setup_printer( info.list[0], error, errlen, 0 ) ){ if( error[0] == 0 ){ plp_snprintf( error, errlen, _("%s: cannot set up print queue"), Printer_DYN ); } goto error; } db = Debug; dbf = DbgFlag; s = Find_str_value(&Spool_control,DEBUG); if(!s) s = New_debug_DYN; Parse_debug( s, 0 ); if( !(DRECVMASK & DbgFlag) ){ Debug = db; DbgFlag = dbf; } else { int i, j; i = Debug; j = DbgFlag; Debug = db; DbgFlag = dbf; if( Log_file_DYN ){ fd = Checkwrite( Log_file_DYN, &statb,0,0,0); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); } } Debug = i; DbgFlag = j; } DEBUGF(DRECV1)("Receive_job: spooling_disabled %d", Sp_disabled(&Spool_control) ); if( Sp_disabled(&Spool_control) ){ plp_snprintf( error, errlen, _("%s: spooling disabled"), Printer_DYN ); ack = ACK_RETRY; /* retry */ goto error; } /* send an ACK */ DEBUGF(DRECV1)("Receive_job: sending 0 ACK for job transfer request" ); status = Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, "", 1, 0 ); if( status ){ plp_snprintf( error, errlen, _("%s: Receive_job: sending ACK 0 failed"), Printer_DYN ); goto error; } /* fifo order enforcement */ if( Fifo_DYN ){ char * path = Make_pathname( Spool_dir_DYN, Fifo_lock_file_DYN ); path = safestrdup3( path,"." , RemoteHost_IP.fqdn, __FILE__,__LINE__ ); DEBUGF(DRECV1)( "Receive_job: checking fifo_lock file '%s'", path ); fifo_fd = Checkwrite( path, &statb, O_RDWR, 1, 0 ); if( fifo_fd < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, _("Receive_job: cannot open lockfile '%s'"), path ); } if( Do_lock( fifo_fd, 1 ) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, _("Receive_job: cannot lock lockfile '%s'"), path ); } if(path) free(path); path = 0; } while( status == 0 ){ DEBUGF(DRECV1)("Receive_job: from %s- getting file transfer line", FQDNRemote_FQDN ); rlen = sizeof(line)-1; line[0] = 0; status = Link_line_read( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, line, &rlen ); DEBUGF(DRECV1)( "Receive_job: read from %s- status %d read %d bytes '%s'", FQDNRemote_FQDN, status, rlen, line ); if( rlen == 0 || status ){ DEBUGF(DRECV1)( "Receive_job: ending reading from remote" ); /* treat like normal closing of connection */ line[0] = 0; status = 0; break; } filetype = line[0]; Clean_meta(line+1); /* make sure we have a data file transfer */ if( filetype != DATA_FILE && filetype != CONTROL_FILE ){ /* we may have another type of command */ status = 0; break; } /* make sure we have length and filename */ filename = 0; file_len = strtod(line+1,&filename); if ((line+1) == filename){ /* Recover from Apple Desktop Printing stupidity. It occasionally resends the queue selection cmd. Darian Davis DD 03JUL2000 */ status = 0; logmsg(LOG_ERR, _("Recovering from incorrect job submission")); continue; } if( filename ){ while( isspace(cval(filename)) ) ++filename; Clean_meta(filename); s = filename; while( (s = strpbrk(s," \t")) ) *s++ = '_'; } if( file_len < 0 || filename == 0 || *filename == 0 || (file_len == 0 && filetype != DATA_FILE) ){ ack = ACK_STOP_Q; plp_snprintf( error, errlen, _("%s: Receive_job - bad control line '%s', len %0.0f, name '%s'"), Printer_DYN, line, file_len, filename ); goto error; } /************************************************ * check for job size and available space * This is done here so that we can neatly clean up * if we need to. Note we do this after we truncate... ************************************************/ jobsize += file_len; read_len = file_len; DEBUGF(DRECV4)("Receive_job: receiving '%s' jobsize %0.0f, file_len %0.0f, read_len %0.0f", filename, jobsize, file_len, read_len ); if( read_len == 0 ) read_len = Max_job_size_DYN*1024; if( Max_job_size_DYN > 0 && (jobsize/1024) > (0.0+Max_job_size_DYN) ){ if( Discard_large_jobs_DYN ){ discarding_large_job = 1; } else { plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); ack = ACK_RETRY; goto error; } } else if( !Check_space( read_len, Minfree_DYN, Spool_dir_DYN ) ){ plp_snprintf( error, errlen, _("%s: insufficient file space"), Printer_DYN ); ack = ACK_RETRY; goto error; } /* * we are ready to read the file; send 0 ack saying so */ DEBUGF(DRECV4)("Receive_job: next, receiving '%s' jobsize %0.0f, file_len %0.0f, read_len %0.0f", filename, jobsize, file_len, read_len ); DEBUGF(DRECV2)("Receive_job: sending 0 ACK to transfer '%s', length %0.0f", filename, file_len ); status = Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, "", 1, 0 ); if( status ){ plp_snprintf( error, errlen, _("%s: sending ACK 0 for '%s' failed"), Printer_DYN, filename ); ack = ACK_RETRY; goto error; } if( discarding_large_job ){ temp_fd = Checkwrite( "/dev/null", &statb,0,0,0); tempfile = 0; } else { temp_fd = Make_temp_fd(&tempfile); } /* * If the file length is 0, then we transfer only as much as we have * space available. Note that this will be the last file in a job */ DEBUGF(DRECV4)("Receive_job: receiving '%s' read_len %0.0f bytes, file_len %0.0f", filename, read_len, file_len ); len = read_len; status = Link_file_read( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, 0, temp_fd, &read_len, &ack ); DEBUGF(DRECV4)("Receive_job: status %d, read_len %0.0f, file_len %0.0f", status, read_len, file_len ); /* close the file */ close(temp_fd); temp_fd = -1; if( status || (file_len == 0 && read_len == 0) || (file_len != 0 && file_len != read_len) ){ plp_snprintf( error, errlen, _("%s: transfer of '%s' from '%s' failed"), Printer_DYN, filename, ShortRemote_FQDN ); ack = ACK_RETRY; goto error; } /* * we process the control file and make sure we can print it */ if( filetype == CONTROL_FILE ){ DEBUGF(DRECV2)("Receive_job: receiving new control file, old job.info.count %d, old files.count %d", job.info.count, files.count ); if( job_in_progress ){ /* we received another control file, finish this job up */ if( !discarding_large_job ){ if( Check_for_missing_files(&job, &files, error, errlen, 0, -1) ){ goto error; } } else { plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, -1 )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } } Free_line_list(&files); discarding_large_job = 0; jobsize = 0; job_in_progress = 0; } Free_job(&job); Set_str_value(&job.info,OPENNAME,tempfile); { int job_ticket_fd = Setup_temporary_job_ticket_file( &job, filename, 1, 0, error, errlen ); if( job_ticket_fd < 0 ){ goto error; } if( files.count ){ /* we have datafiles, FOLLOWED by a control file */ if( !discarding_large_job ){ if( Check_for_missing_files(&job, &files, error, errlen, 0, job_ticket_fd) ){ goto error; } } else { plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, job_ticket_fd )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } } Free_line_list(&files); discarding_large_job = 0; job_in_progress = 0; jobsize = 0; Free_job(&job); } else { job_in_progress = 1; } /* * we do not want to lock the hold file while there is an incoming job */ close( job_ticket_fd ); job_ticket_fd = -1; } } else { Set_casekey_str_value(&files,filename,tempfile); } DEBUGF(DRECV2)("Receive_job: sending 0 ACK transfer done" ); status = Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, "",1, 0 ); } DEBUGF(DRECV2)("Receive_job: eof on transfer, job.info.count %d, files.count %d", job.info.count, files.count ); if( !discarding_large_job ){ /* * if we get just a control file and no data file, then we have a sender * problem. We will NOT log this */ if( job.info.count && !files.count ){ /* we will not log this */ ; } else if( files.count && Check_for_missing_files(&job, &files, error, errlen, 0, -1) ){ goto error; } } else { char *f = Find_str_value( &job.info,HF_NAME ); if( !ISNULL(f) ){ plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, -1 )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } discarding_large_job = 0; } } error: if( temp_fd > 0 ) close(temp_fd); temp_fd = -1; if( fifo_fd > 0 ) close(fifo_fd); fifo_fd = -1; Remove_tempfiles(); if( error[0] ){ DEBUGF(DRECV1)("Receive_job: error, removing job" ); DEBUGFC(DRECV4)Dump_job("Receive_job - error", &job ); s = Find_str_value(&job.info,HF_NAME); if( !ISNULL(s) ) unlink(s); if( ack == 0 ) ack = ACK_FAIL; buffer[0] = ack; plp_snprintf(buffer+1,sizeof(buffer)-1, "%s\n",error); DEBUGF(DRECV1)("Receive_job: sending ACK %d, msg '%s'", ack, error ); (void)Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, buffer, safestrlen(buffer), 0 ); Link_close( Send_query_rw_timeout_DYN, sock ); } else { Link_close( Send_query_rw_timeout_DYN, sock ); /* update the spool queue */ Get_spool_control( Queue_control_file_DYN, &Spool_control ); Set_flag_value(&Spool_control,CHANGE,1); Set_spool_control( 0, Queue_control_file_DYN, &Spool_control ); if( Lpq_status_file_DYN ){ unlink( Lpq_status_file_DYN ); } s = Server_queue_name_DYN; if( !s ) s = Printer_DYN; plp_snprintf( line, sizeof(line), "%s\n", s ); DEBUGF(DRECV1)("Receive_jobs: Lpd_request fd %d, starting '%s'", Lpd_request, line ); if( Write_fd_str( Lpd_request, line ) < 0 ){ logerr_die(LOG_ERR, _("Receive_jobs: write to fd '%d' failed"), Lpd_request ); } } Free_line_list(&info); Free_line_list(&files); Free_job(&job); Free_line_list(&l); cleanup( 0 ); } /*************************************************************************** * Block Job Transfer * \RCV_BLOCKprinter size * The actual file transferred has the format: * \CONTROL_FILElen name * [control file contents] * \DATA_FILElen name * [data file contents] * * We receive the entire file, placing it into the control file. * We then split the job up as usual ***************************************************************************/ #define MAX_INPUT_TOKENS 10 int Receive_block_job( int *sock, char *input ) { int temp_fd = -1, fd; /* fd for received file */ double read_len; /* file read length */ char error[SMALLBUFFER]; int errlen = sizeof(error); char buffer[SMALLBUFFER]; int ack = 0, status = 0; double file_len; char *tempfile, *s; struct stat statb; struct line_list l; int db, dbf; int discarding_large_job = 0; error[0] = 0; Init_line_list(&l); Name = "RECVB"; if( *input ) ++input; Clean_meta(input); Split(&l,input,Whitespace,0,0,0,0,0,0); DEBUGFC(DRECV1)Dump_line_list("Receive_block_job: input", &l ); if( l.count != 2 ){ plp_snprintf( error, errlen-4, _("bad command line") ); goto error; } if( Is_clean_name( l.list[0] ) ){ plp_snprintf( error, errlen-4, _("bad printer name") ); goto error; } setproctitle( "lpd RECVB '%s'", l.list[0] ); if( Setup_printer( l.list[0], error, errlen-4, 0 ) ){ if( error[0] == 0 ){ plp_snprintf( error, errlen-4, _("%s: cannot set up printer"), Printer_DYN ); } goto error; } db = Debug; dbf =DbgFlag; s = Find_str_value(&Spool_control,DEBUG); if(!s) s = New_debug_DYN; Parse_debug( s, 0 ); if( !(DRECVMASK & DbgFlag) ){ Debug = db; DbgFlag = dbf; } else { dbf = Debug; Debug = db; if( Log_file_DYN ){ fd = Checkwrite( Log_file_DYN, &statb,0,0,0); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); } } Debug = dbf; } DEBUGF(DRECV1)("Receive_block_job: debug '%s', Debug %d, DbgFlag 0x%x", s, Debug, DbgFlag ); DEBUGF(DRECV1)("Receive_block_job: spooling_disabled %d", Sp_disabled(&Spool_control) ); if( Sp_disabled(&Spool_control) ){ plp_snprintf( error, errlen-4, _("%s: spooling disabled"), Printer_DYN ); ack = ACK_RETRY; /* retry */ goto error; } /* check for space */ file_len = strtod( l.list[1], 0 ); read_len = file_len; if( Max_job_size_DYN > 0 && (read_len+1023)/1024 > Max_job_size_DYN ){ if( Discard_large_jobs_DYN ){ discarding_large_job = 1; } else { plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), read_len/1024, Max_job_size_DYN ); ack = ACK_RETRY; goto error; } } else if( !Check_space( read_len, Minfree_DYN, Spool_dir_DYN ) ){ plp_snprintf( error, errlen-4, _("%s: insufficient file space"), Printer_DYN ); ack = ACK_RETRY; goto error; } /* * we are ready to read the file; send 0 ack saying so */ DEBUGF(DRECV1)("Receive_block_job: sending 0 ACK for job transfer request" ); status = Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, "",1, 0 ); if( status ){ plp_snprintf( error, errlen-4, _("%s: Receive_block_job: sending ACK 0 failed"), Printer_DYN ); goto error; } temp_fd = Make_temp_fd( &tempfile ); DEBUGF(DRECV4)("Receive_block_job: receiving '%s' %0.0f bytes ", tempfile, file_len ); status = Link_file_read( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, 0, temp_fd, &read_len, &ack ); DEBUGF(DRECV4)("Receive_block_job: received %0.0f bytes ", read_len ); if( status ){ plp_snprintf( error, errlen-4, _("%s: transfer of '%s' from '%s' failed"), Printer_DYN, tempfile, ShortRemote_FQDN ); ack = ACK_FAIL; goto error; } /* extract jobs */ if( lseek( temp_fd, 0, SEEK_SET ) == -1 ){ plp_snprintf( error, errlen-4, _("Receive_block_job: lseek failed '%s'"), Errormsg(errno) ); ack = ACK_FAIL; goto error; } if( Scan_block_file( temp_fd, error, errlen-4, 0 ) ){ ack = ACK_FAIL; goto error; } close( temp_fd ); temp_fd = -1; DEBUGF(DRECV2)("Receive_block_job: sending 0 ACK" ); status = Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, "",1, 0 ); if( status ){ plp_snprintf( error, errlen-4, _("%s: sending ACK 0 for '%s' failed"), Printer_DYN, tempfile ); ack = ACK_RETRY; goto error; } error[0] = 0; error: Free_line_list(&l); if( temp_fd > 0 ){ close(temp_fd ); } if( error[0] ){ if( ack != 0 ) ack = ACK_FAIL; buffer[0] = ack; plp_snprintf(buffer+1,sizeof(buffer)-1, "%s\n",error); /* LOG( LOG_INFO) "Receive_block_job: error '%s'", error ); */ DEBUGF(DRECV1)("Receive_block_job: sending ACK %d, msg '%s'", ack, error ); (void)Link_send( ShortRemote_FQDN, sock, Send_job_rw_timeout_DYN, buffer, safestrlen(buffer), 0 ); Link_close( Send_query_rw_timeout_DYN, sock ); } else { Link_close( Send_query_rw_timeout_DYN, sock ); Remove_tempfiles(); s = Server_queue_name_DYN; if( !s ) s = Printer_DYN; plp_snprintf( buffer, sizeof(buffer), "%s\n", s ); DEBUGF(DRECV1)("Receive_block_jobs: Lpd_request fd %d, starting '%s'", Lpd_request, buffer ); if( Write_fd_str( Lpd_request, buffer ) < 0 ){ logerr_die(LOG_ERR, _("Receive_block_jobs: write to fd '%d' failed"), Lpd_request ); } } return( error[0] != 0 ); } /*************************************************************************** * int Scan_block_file( int fd, char *error, int errlen, struct line_list *header_info ) * we scan the block file, getting the various portions * * Generate the compressed data files - this has the format * \3count cfname\n * [count control file bytes] * \4count dfname\n * [count data file bytes] * The header_info contains authentication information * * We extract the various sections and find the offsets. * Note that the various name fields will be the original * values; the ones we actually use will be the transfer values * RETURNS: nonzero on error, error set * 0 on success ***************************************************************************/ int Scan_block_file( int fd, char *error, int errlen, struct line_list *header_info ) { char line[LINEBUFFER]; char buffer[LARGEBUFFER]; int startpos; int read_len, filetype, tempfd = -1; /* type and length fields */ char *filename; /* name field */ char *tempfile; /* name field */ int status; int len, count, n; int job_ticket_fd = -1; struct line_list l, info, files; struct job job; struct stat statb; int discarding_large_job = 0; double jobsize = 0; if( fstat( fd, &statb) < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Scan_block_file: fstat failed"); } DEBUGF(DRECV2)("Scan_block_file: starting, file size '%0.0f'", (double)(statb.st_size) ); Init_line_list(&l); Init_line_list(&info); Init_line_list(&files); Init_job(&job); /* first we find the file position */ startpos = lseek( fd, 0, SEEK_CUR ); DEBUGF(DRECV2)("Scan_block_file: starting at %d", startpos ); error[0] = 0; while( (status = Read_one_line( Send_job_rw_timeout_DYN, fd, line, sizeof(line) )) > 0 ){ /* the next position is the start of data */ Free_line_list(&l); Free_line_list(&info); startpos = lseek( fd, 0, SEEK_CUR ); if( startpos == -1 ){ plp_snprintf( error, errlen, _("Scan_block_file: lseek failed '%s'"), Errormsg(errno) ); status = 1; goto error; } DEBUGF(DRECV2)("Scan_block_file: '%s', end position %d", line, startpos ); filetype = line[0]; if( filetype != CONTROL_FILE && filetype != DATA_FILE ){ /* get the next line */ continue; } Clean_meta(line+1); Split(&info,line+1,Whitespace,0,0,0,0,0,0); if( info.count != 2 ){ plp_snprintf( error, errlen, _("bad length information '%s'"), line+1 ); status = 1; goto error; } DEBUGFC(DRECV2)Dump_line_list("Scan_block_file- input", &info ); read_len = atoi( info.list[0] ); filename = info.list[1]; jobsize += read_len; if( Max_job_size_DYN > 0 && (jobsize/1024) > (0.0+Max_job_size_DYN) ){ if( Discard_large_jobs_DYN ){ plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); discarding_large_job = 1; } } if( discarding_large_job ){ tempfd = Checkwrite( "/dev/null", &statb,0,0,0); tempfile = 0; } else { tempfd = Make_temp_fd( &tempfile ); } DEBUGF(DRECV2)("Scan_block_file: tempfd %d, read_len %d", read_len, tempfd ); for( len = read_len; len > 0; len -= count ){ n = sizeof(buffer); if( n > len ) n = len; count = Read_fd_len_timeout(Send_job_rw_timeout_DYN,fd,buffer,n); DEBUGF(DRECV2)("Scan_block_file: len %d, reading %d, got count %d", len, n, count ); if( count < 0 ){ plp_snprintf( error, errlen, _("Scan_block_file: read failed '%s'"), Errormsg(errno) ); status = 1; goto error; } else if( count == 0 ){ plp_snprintf( error, errlen, _("Scan_block_file: read unexecpted EOF") ); status = 1; goto error; } n = write(tempfd,buffer,count); if( n != count ){ plp_snprintf( error, errlen, _("Scan_block_file: lseek failed '%s'"), Errormsg(errno) ); status = 1; goto error; } } close( tempfd); tempfd = -1; if( filetype == CONTROL_FILE ){ DEBUGF(DRECV2)("Scan_block_file: receiving new control file, old job.info.count %d, old files.count %d", job.info.count, files.count ); if( job.info.count ){ /* we received another control file, finish this job up */ if( discarding_large_job ){ plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, job_ticket_fd )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } } else { if( Check_for_missing_files(&job, &files, error, errlen, header_info, job_ticket_fd) ){ goto error; } } close( job_ticket_fd ); job_ticket_fd = -1; Free_line_list(&files); jobsize = 0; } Free_job(&job); Set_str_value(&job.info,OPENNAME,tempfile); job_ticket_fd = Setup_temporary_job_ticket_file( &job, filename, 1, 0, error, errlen ); if( job_ticket_fd < 0 ){ goto error; } if( files.count ){ /* we have datafiles, FOLLOWED by a control file, followed (possibly) by another control file */ /* we receive another control file */ if( discarding_large_job ){ plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, job_ticket_fd )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } } else { if( Check_for_missing_files(&job, &files, error, errlen, header_info, job_ticket_fd) ){ goto error; } } Free_line_list(&files); jobsize = 0; Free_job(&job); } /* * we close the job_ticket_fd file so that we do not lock the hold file while * the incoming job is arriving. */ close( job_ticket_fd ); job_ticket_fd = -1; } else { Set_str_value(&files,filename,tempfile); } } if( files.count ){ if( discarding_large_job ){ plp_snprintf( error, errlen, _("size %0.3fK exceeds %dK"), jobsize/1024, Max_job_size_DYN ); Set_str_value(&job.info,ERROR,error); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_str_value(&job.info,INCOMING_TIME,0); Set_str_value(&job.info,INCOMING_PID,0); error[0] = 0; if( (status = Set_job_ticket_file( &job, 0, job_ticket_fd )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } } else { if( Check_for_missing_files(&job, &files, error, errlen, header_info, job_ticket_fd) ){ goto error; } } } error: if( error[0] ){ Remove_tempfiles(); Remove_job( &job ); } if( job_ticket_fd > 0 ) close(job_ticket_fd); job_ticket_fd = -1; if( tempfd > 0 ) close(tempfd); tempfd = -1; Free_line_list(&l); Free_line_list(&info); Free_line_list(&files); Free_job(&job); return( status ); } /*************************************************************************** * static int read_one_line(int fd, char *buffer, int maxlen ); * reads one line (terminated by \n) into the buffer *RETURNS: 0 if EOF characters read * n = # chars read * Note: buffer terminated by 0 ***************************************************************************/ static int Read_one_line( int timeout, int fd, char *buffer, int maxlen ) { int len, status; len = status = 0; while( len < maxlen-1 && (status = Read_fd_len_timeout( timeout, fd, &buffer[len], 1)) > 0 ){ if( buffer[len] == '\n' ){ break; } ++len; } buffer[len] = 0; return( status ); } int Check_space( double jobsize, int min_space, char *pathname ) { double space = Space_avail(pathname); int ok; jobsize = ((jobsize+1023)/1024); ok = ((jobsize + min_space) < space); DEBUGF(DRECV1)("Check_space: path '%s', space %0.0f Bytes, jobsize %0.0fK, ok %d", pathname, space, jobsize, ok ); return( ok ); } static int Do_perm_check( struct job *job, char *error, int errlen ) { int permission = 0; /* permission */ char *s; DEBUGFC(DRECV1)Dump_job("Do_perm_check", job ); Perm_check.service = 'R'; Perm_check.printer = Printer_DYN; s = Find_str_value(&job->info,LOGNAME); Perm_check.user = s; Perm_check.remoteuser = s; Perm_check.host = 0; s = Find_str_value(&job->info,FROMHOST); if( s && Find_fqdn( &PermHost_IP, s ) ){ Perm_check.host = &PermHost_IP; } Perm_check.remotehost = &RemoteHost_IP; /* check for permission */ if( Perm_filters_line_list.count ){ Free_line_list(&Perm_line_list); Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); Filterprintcap( &Perm_line_list, &Perm_filters_line_list, ""); } if( (permission = Perms_check( &Perm_line_list, &Perm_check, job, 1 )) == P_REJECT ){ plp_snprintf( error, errlen, _("%s: no permission to print"), Printer_DYN ); } Perm_check.user = 0; Perm_check.remoteuser = 0; DEBUGF(DRECV1)("Do_perm_check: permission '%s'", perm_str(permission) ); return( permission ); } /* * Process the list of control and data files, and make a job from them * job - the job structure * files - list of files that we received and need to check. * if this is a copy of a job from another queue, files == 0 * spool_control - the spool control values for this queue * spool_dir - the spool directory for this queue * xlate_incoming_format - only valid for received files * error, errlen - the error message information * header_info - authentication ID to put in the job * - if 0, do not update, this preserves copy * returns: 0 - successful * != 0 - error */ int Check_for_missing_files( struct job *job, struct line_list *files, char *error, int errlen, struct line_list *header_info, int holdfile_fd ) { int count, i, status = 0, copies; struct line_list *lp = 0, datafiles; char *openname, *transfername; double jobsize; struct stat statb; struct timeval start_time; char *fromhost, *file_hostname, *number; Init_line_list(&datafiles); if( gettimeofday( &start_time, 0 ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Check_for_missing_files: gettimeofday failed"); } DEBUGF(DRECV1)("Check_for_missing_files: start time 0x%x usec 0x%x", (int)start_time.tv_sec, (int)start_time.tv_usec ); if(DEBUGL1)Dump_job("Check_for_missing_files - start", job ); if(DEBUGL1)Dump_line_list("Check_for_missing_files- files", files ); if(DEBUGL1)Dump_line_list("Check_for_missing_files- header_info", header_info ); Set_flag_value(&job->info,JOB_TIME,(int)start_time.tv_sec); Set_flag_value(&job->info,JOB_TIME_USEC,(int)start_time.tv_usec); /* we can get this as a new job or as a copy. * if we get a copy, we do not need to check this stuff */ if( !Find_str_value(&job->info,REMOTEHOST) ){ Set_str_value(&job->info,REMOTEHOST,RemoteHost_IP.fqdn); Set_flag_value(&job->info,UNIXSOCKET,Perm_check.unix_socket); Set_flag_value(&job->info,REMOTEPORT,Perm_check.port); } if( header_info ){ char *s; s = Find_str_value(header_info,AUTH); if( !ISNULL(s) ) Set_str_value( &job->info,AUTH,s); s = Find_str_value(header_info,AUTHCA); if( !ISNULL(s) ) Set_str_value( &job->info,AUTHCA,s); s = Find_str_value(header_info,AUTHFROM); if( !ISNULL(s) ) Set_str_value( &job->info,AUTHFROM,s); s = Find_str_value(header_info,AUTHTYPE); if( !ISNULL(s) ) Set_str_value( &job->info,AUTHTYPE,s); if( User_is_authuser_DYN ){ s = Find_str_value(header_info,AUTHUSER); if( !ISNULL(s) ){ Set_str_value( &job->info,LOGNAME,s); DEBUGF(DRECV1)("Check_for_missing_files: setting user to authuser '%s'", s ); } } } if(DEBUGL3) Dump_job( "Check_for_missing_files: before fixing", job ); /* deal with authentication */ Make_identifier( job ); if( !(fromhost = Find_str_value(&job->info,FROMHOST)) || Is_clean_name(fromhost) ){ Set_str_value(&job->info,FROMHOST,FQDNRemote_FQDN); fromhost = Find_str_value(&job->info,FROMHOST); } if( header_info ){ char *authfrom, *authuser, *authtype, *authca; authfrom = Find_str_value(header_info,AUTHFROM); authuser = Find_str_value(header_info,AUTHUSER); authtype = Find_str_value(header_info,AUTHTYPE); authca = Find_str_value(header_info,AUTHCA); if( ISNULL(authuser) ) authuser = authfrom; Set_str_value(&job->info,AUTHUSER,authuser); Set_str_value(&job->info,AUTHFROM,authfrom); Set_str_value(&job->info,AUTHTYPE,authtype); Set_str_value(&job->info,AUTHCA,authca); } /* * check permissions now that you have set up all the information */ if( Do_perm_check( job, error, errlen ) == P_REJECT ){ status = 1; goto error; } /* * accounting name fixup * change the accounting name ('R' field in control file) * based on hostname * hostname(,hostname)*=($K|value)*(;hostname(,hostname)*=($K|value)*)* * we have a semicolon separated list of entrires * the RemoteHost_IP is compared to these. If a match is found then the * user name (if any) is used for the accounting name. * The user name list has the format: * ${K} - value from control file or printcap entry - you must use the * ${K} format. * username - user name value to substitute. */ if( Accounting_namefixup_DYN ){ struct line_list l, listv; char *accounting_name = 0; Init_line_list(&l); Init_line_list(&listv); DEBUGF(DRECV1)("Check_for_missing_files: Accounting_namefixup '%s'", Accounting_namefixup_DYN ); Split(&listv,Accounting_namefixup_DYN,";",0,0,0,0,0,0); for( i = 0; i < listv.count; ++i ){ char *s, *t; int j; s = listv.list[i]; if( (t = safestrpbrk(s,"=")) ) *t++ = 0; Free_line_list(&l); DEBUGF(DRECV1)("Check_for_missing_files: hostlist '%s'", s ); Split(&l,s,",",0,0,0,0,0,0); if( Match_ipaddr_value(&l,&RemoteHost_IP) == 0 ){ Free_line_list(&l); DEBUGF(DRECV1)("Check_for_missing_files: match, using users '%s'", t ); Split(&l,t,",",0,0,0,0,0,0); if(DEBUGL1)Dump_line_list("Check_for_missing_files: before Fix_dollars", &l ); Fix_dollars(&l,job,0,0); if(DEBUGL1)Dump_line_list("Check_for_missing_files: after Fix_dollars", &l ); for( j = 0; j < l.count; ++j ){ if( !ISNULL(l.list[j]) ){ accounting_name = l.list[j]; break; } } break; } } DEBUGF(DRECV1)("Check_for_missing_files: accounting_name '%s'", accounting_name ); if( !ISNULL(accounting_name) ){ Set_str_value(&job->info,ACCNTNAME,accounting_name ); } Free_line_list(&l); Free_line_list(&listv); } if( Force_IPADDR_hostname_DYN ){ char buffer[SMALLBUFFER]; const char *const_s; int family; /* We will need to create a dummy record. - no host */ family = RemoteHost_IP.h_addrtype; const_s = (char *)inet_ntop( family, RemoteHost_IP.h_addr_list.list[0], buffer, sizeof(buffer) ); DEBUGF(DRECV1)("Check_for_missing_files: remotehost '%s'", const_s ); Set_str_value(&job->info,FROMHOST,const_s); fromhost = Find_str_value(&job->info,FROMHOST); } { char *s, *t; if( Force_FQDN_hostname_DYN && !safestrchr(fromhost,'.') && (t = safestrchr(FQDNRemote_FQDN,'.')) ){ s = safestrdup2(fromhost, t, __FILE__,__LINE__ ); Set_str_value(&job->info,FROMHOST,s); if( s ) free(s); s = 0; fromhost = Find_str_value(&job->info,FROMHOST); } } if( !Find_str_value(&job->info,DATE) ){ char *s = Time_str(0,0); Set_str_value(&job->info,DATE,s); } if( (Use_queuename_DYN || Force_queuename_DYN) && !Find_str_value(&job->info,QUEUENAME) ){ char *s = Force_queuename_DYN; if( s == 0 ) s = Queue_name_DYN; if( s == 0 ) s = Printer_DYN; Set_str_value(&job->info,QUEUENAME,s); Set_DYN(&Queue_name_DYN,s); } if( Hld_all(&Spool_control) || Auto_hold_DYN ){ Set_flag_value( &job->info,HOLD_TIME,time((void *)0) ); } else { Set_flag_value( &job->info,HOLD_TIME,0); } number = Find_str_value( &job->info,NUMBER); file_hostname = Find_str_value(&job->info,FROMHOST); if( ISNULL(file_hostname) ) file_hostname = FQDNRemote_FQDN; if( ISNULL(file_hostname) ) file_hostname = FQDNHost_FQDN; if( isdigit(cval(file_hostname)) ){ char * s = safestrdup2("ADDR",file_hostname,__FILE__,__LINE__); Set_str_value(&job->info,FILE_HOSTNAME,s); if( s ) free(s); s = 0; } else { Set_str_value(&job->info,FILE_HOSTNAME,file_hostname); } file_hostname = Find_str_value(&job->info,FILE_HOSTNAME); /* fix Z options */ Fix_Z_opts( job ); /* fix control file name */ { jobsize = 0; /* RedHat Linux 6.1 - sends a control file with NO data files */ if( job->datafiles.count == 0 && files->count > 0 ){ Check_max(&job->datafiles,files->count+1); for( count = 0; count < files->count; ++count ){ lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); job->datafiles.list[job->datafiles.count++] = (void *)lp; /* * now we add the information needed * the files list has 'transfername=openname' */ transfername = files->list[count]; if( (openname = strchr(transfername,'=')) ) *openname++ = 0; Set_str_value(lp,OTRANSFERNAME,transfername); Set_str_value(lp,FORMAT,"f"); Set_flag_value(lp,COPIES,1); if( openname ) openname[-1] = '='; } if(DEBUGL1)Dump_job("RedHat Linux fix", job ); } for( count = 0; count < job->datafiles.count; ++count ){ double size; lp = (void *)job->datafiles.list[count]; transfername = Find_str_value(lp,OTRANSFERNAME); /* find the open name and replace it in the information */ if( (openname = Find_casekey_str_value(files,transfername,Hash_value_sep)) ){ Set_str_value(lp,OPENNAME,openname); Set_casekey_str_value(&datafiles,transfername,openname); } else { plp_snprintf(error,errlen, "missing data file '%s'",transfername); status = 1; goto error; } if( (status = stat( openname, &statb )) ){ plp_snprintf( error, errlen, "stat() '%s' error - %s", openname, Errormsg(errno) ); goto error; } copies = Find_flag_value(lp,COPIES); if( copies == 0 ) copies = 1; size = statb.st_size; Set_double_value(lp,SIZE,size); jobsize += copies * size; } Set_double_value(&job->info,SIZE,jobsize); if(DEBUGL1)Dump_line_list("Check_for_missing_files- found", &datafiles ); if( files->count != datafiles.count ){ plp_snprintf(error,errlen, "too many data files"); status = 1; goto error; } Free_line_list(&datafiles); Fix_datafile_infox( job, number, file_hostname, Xlate_incoming_format_DYN, 1 ); } Set_str_value(&job->info,HPFORMAT,0); Set_str_value(&job->info,INCOMING_TIME,0); Set_str_value(&job->info,INCOMING_PID,0); if( !ISNULL(Incoming_control_filter_DYN) ){ Generate_control_file( job ); if( (status = Do_incoming_control_filter( job, error, errlen )) ){ DEBUGF(DRECV1)("Check_for_missing_files: error '%s'", error ); goto error; } } if( !ISNULL(Routing_filter_DYN) ){ Generate_control_file( job ); if( (status = Get_route( job, error, errlen )) ){ DEBUGF(DRECV1)("Check_for_missing_files: Routing_filter error '%s'", error ); goto error; } } /* now rename the data files */ status = 0; for( count = 0; status == 0 && count < job->datafiles.count; ++count ){ lp = (void *)job->datafiles.list[count]; openname = Find_str_value(lp,OPENNAME); if( stat(openname,&statb) ) continue; transfername = Find_str_value(lp,DFTRANSFERNAME); DEBUGF(DRECV1)("Check_for_missing_files: renaming '%s' to '%s'", openname, transfername ); if( (status = rename(openname,transfername)) ){ plp_snprintf( error,errlen, "error renaming '%s' to '%s' - %s", openname, transfername, Errormsg( errno ) ); } } if( status ) goto error; if( (status = Set_job_ticket_file( job, 0, holdfile_fd )) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); goto error; } if(DEBUGL1)Dump_job("Check_for_missing_files - ending", job ); error: transfername = Find_str_value(&job->info,HF_NAME); if( !transfername ) transfername = Find_str_value(&job->info,XXCFTRANSFERNAME); if( status ){ logmsg(LOG_INFO, "Check_for_missing_files: FAILED '%s' %s", transfername?transfername:"???", error); /* we need to unlink the data files */ openname = Find_str_value(&job->info,OPENNAME); if( openname ) unlink( openname ); for( count = 0; count < job->datafiles.count; ++count ){ lp = (void *)job->datafiles.list[count]; transfername = Find_str_value(lp,DFTRANSFERNAME); openname = Find_str_value(lp,OPENNAME); if( transfername ) unlink(transfername); if( openname ) unlink(openname); } openname = Find_str_value(&job->info,HF_NAME); if( openname ) unlink(openname); } else { /* logmsg(LOG_INFO, "Check_for_missing_files: SUCCESS '%s'", transfername); */ setmessage( job, "STATE", "CREATE" ); } Free_line_list(&datafiles); return( status ); } /*************************************************************************** * int Setup_temporary_job_ticket_file( struct job *job, * char *error, int errlen ) * sets up a job ticket file and control file ***************************************************************************/ int Setup_temporary_job_ticket_file( struct job *job, char *filename, int read_control_file, char *cf_file_image, char *error, int errlen ) { int fd = -1; /* now we need to assign a control file number */ DEBUGF(DRECV1)("Setup_temporary_job_ticket_file: starting, filename %s, read_control_file %d, cf_file_image %s", filename, read_control_file, cf_file_image ); /* job id collision resolution */ if( filename ){ Check_format( CONTROL_FILE, filename, job ); } if( (fd = Find_non_colliding_job_number( job )) < 0 ){ plp_snprintf(error,errlen, "Maximum number of jobs in queue. Delete some and retry"); goto error; } /* set up the control file information */ Set_job_ticket_from_cf_info( job, cf_file_image, read_control_file ); Make_identifier( job ); Check_for_hold( job, &Spool_control ); DEBUGF(DRECV1)("Setup_temporary_job_ticket_file: job ticket file fd '%d'", fd ); /* mark as incoming */ Set_flag_value(&job->info,INCOMING_TIME,time((void *)0) ); Set_flag_value(&job->info,INCOMING_PID,getpid() ); /* write status */ if( Set_job_ticket_file( job, 0, fd ) ){ plp_snprintf( error,errlen, _("Error setting up job ticket file - %s"), Errormsg( errno ) ); close(fd); fd = -1; goto error; } error: return( fd ); } /*************************************************************************** * int Find_non_colliding_job_number( struct job *job ) * Find a non-colliding job number for the new job * RETURNS: 0 if successful * ack value if unsuccessful * Side effects: sets up control file fields; ***************************************************************************/ static int Find_non_colliding_job_number( struct job *job ) { int job_ticket_fd = -1; /* job job ticket file fd */ struct stat statb; /* for status */ char hold_file[SMALLBUFFER], *number; int max, n, start; /* we set the job number to a reasonable range */ job_ticket_fd = -1; number = Fix_job_number(job,0); start = n = strtol(number,0,10); max = 1000; if( Long_number_DYN ) max = 1000000; while( job_ticket_fd < 0 ){ number = Fix_job_number(job,n); plp_snprintf(hold_file,sizeof(hold_file), "hfA%s",number); DEBUGF(DRECV1)("Find_non_colliding_job_number: trying %s", hold_file ); job_ticket_fd = Checkwrite(hold_file, &statb, O_RDWR|O_CREAT, 0, 0 ); /* if the job ticket file locked skip to a new one */ if( job_ticket_fd < 0 || Do_lock( job_ticket_fd, 0 ) < 0 || statb.st_size ){ close( job_ticket_fd ); job_ticket_fd = -1; hold_file[0] = 0; ++n; if( n > max ) n = 0; if( n == start ){ break; } } else { Set_str_value(&job->info,HF_NAME,hold_file); } } DEBUGF(DRECV1)("Find_non_colliding_job_number: job_ticket_fd %d", job_ticket_fd ); return( job_ticket_fd ); } /* * Do_incoming_control_filter: * perform incoming control filter actions. * - if the control file filter wants to remove a line starting with X, * it puts in X (no data) * - it changes values by putting in Xnewvalue */ static int Do_incoming_control_filter( struct job *job, char *error, int errlen ) { int intempfd, tempfd, i; char *cf; int errorcode = 0; struct line_list env, cf_line_list; Init_line_list(&env); Init_line_list(&cf_line_list); DEBUGF(DRECV1)("Do_incoming_control_filter: control filter '%s'", Incoming_control_filter_DYN ); /* we pass the control file through the incoming control filter */ intempfd = Make_temp_fd(0); Max_open(intempfd); tempfd = Make_temp_fd(0); Max_open(tempfd); cf = Find_str_value(&job->info,CF_OUT_IMAGE); Write_fd_str(intempfd,cf); if( lseek( intempfd, 0, SEEK_SET ) == -1 ){ plp_snprintf( error, errlen-4, _("Do_incoming_control_filter: lseek failed '%s'"), Errormsg(errno) ); errorcode = JFAIL; goto error; } errorcode = Filter_file( Send_job_rw_timeout_DYN, intempfd, tempfd, "INCOMING_CONTROL_FILTER", Incoming_control_filter_DYN, Filter_options_DYN, job, &env, 0); switch(errorcode){ case 0: break; case JHOLD: Set_flag_value(&job->info,HOLD_TIME,time((void *)0) ); errorcode = 0; break; case JREMOVE: goto error; break; default: plp_snprintf(error,errlen, "Do_incoming_control_filter: incoming control filter '%s' failed '%s'", Incoming_control_filter_DYN, Server_status(errorcode) ); errorcode = JFAIL; goto error; } if( lseek( tempfd, 0, SEEK_SET ) == -1 ){ plp_snprintf( error, errlen-4, _("Do_incoming_control_filter: lseek failed '%s'"), Errormsg(errno) ); errorcode = JFAIL; goto error; } if( Get_fd_image_and_split(tempfd,0,0, &cf_line_list, Line_ends,0,0,0,0,0,0) ){ plp_snprintf(error,errlen, "Do_incoming_control_filter: split failed - %s", Errormsg(errno) ); errorcode = JFAIL; goto error; } for( i = 0; i < cf_line_list.count; ++i ){ char *key = cf_line_list.list[i]; int c = cval(key); char *value = strchr(key,'='); DEBUGF(DRECV2)("Do_incoming_control_filter: doing CF line '%s'", key ); if( isupper(c) || isdigit(c) ){ char buffer[2]; if( cval(key+1) != '=' ){ buffer[0] = c; buffer[1] = 0; value = key+1; key = buffer; } if( value ) *value++ = 0; if( ISNULL(value) ) value = 0; if( c != 'U' && c != 'N' ){ DEBUGF(DRECV2)("Do_incoming_control_filter: setting '%s'='%s'", key, value ); Set_str_value(&job->info,key,value); } } else { if( value ) *value++ = 0; if( ISNULL(value) ) value = 0; DEBUGF(DRECV2)("Do_incoming_control_filter: setting '%s'='%s'", key, value ); Set_str_value(&job->info,key,value); } } error: close(intempfd); intempfd = -1; close(tempfd); tempfd = -1; Free_line_list(&env); Free_line_list(&cf_line_list); return( errorcode ); } /* * routing filter * routing filter just generates 'routing' information * The control file contents are not changed, but additional * routing information can be added to change the values later. * * A routing entry has the format: * dest t5 < new destination t5 * Btesting < change/add B line * Ktesting < change/add K line * * end < end of entry * dest t4 < new destination t1 * * end * EOF */ static int Get_route( struct job *job, char *error, int errlen ) { int intempfd, tempfd, i, count; char *cf, *id, *s; int errorcode = 0; struct line_list env, cf_line_list; Init_line_list(&env); Init_line_list(&cf_line_list); DEBUGF(DRECV1)("Get_route: control filter '%s'", Incoming_control_filter_DYN ); /* we pass the control file through the incoming control filter */ intempfd = Make_temp_fd(0); Max_open(intempfd); tempfd = Make_temp_fd(0); Max_open(tempfd); cf = Find_str_value(&job->info,CF_OUT_IMAGE); Write_fd_str(intempfd,cf); if( lseek( intempfd, 0, SEEK_SET ) == -1 ){ plp_snprintf( error, errlen-4, _("Get_route: lseek failed '%s'"), Errormsg(errno) ); errorcode = JFAIL; goto error; } errorcode = Filter_file( Send_query_rw_timeout_DYN, intempfd, tempfd, "ROUTING_FILTER", Routing_filter_DYN, Filter_options_DYN, job, &env, 0); if(errorcode)switch(errorcode){ case 0: break; case JHOLD: Set_flag_value(&job->info,HOLD_TIME,time((void *)0) ); errorcode = 0; break; case JREMOVE: goto error; break; default: plp_snprintf(error,errlen, "Get_route: incoming control filter '%s' failed '%s'", Incoming_control_filter_DYN, Server_status(errorcode) ); errorcode = JFAIL; goto error; } if( Get_fd_image_and_split(tempfd,0,0, &cf_line_list, Line_ends,0,0,0,0,0,0) ){ plp_snprintf(error,errlen, "Get_route: split failed - %s", Errormsg(errno) ); errorcode = JFAIL; goto error; } DEBUGFC(DRECV1)Dump_line_list("Get_route: information", &cf_line_list ); Free_line_list(&job->destination); count = 0; id = Find_str_value(&job->info,IDENTIFIER); if( ISNULL(id) ){ plp_snprintf(error,errlen, "Get_route: split failed - %s", Errormsg(errno) ); errorcode = JFAIL; goto error; } for(i = 0; i < cf_line_list.count; ++i ){ char *s = cf_line_list.list[i]; char *t; char buffer[2]; DEBUGF(DRECV1)("Get_route: line '%s'", s ); if( safestrcasecmp(END,s) ){ if( isupper(cval(s)) ){ buffer[0] = cval(s); buffer[1] = 0; Set_str_value(&job->destination,buffer,s+1); } else if( (t = safestrpbrk(s,Hash_value_sep)) || (t = safestrpbrk(s,Whitespace)) ){ *t++ = 0; while( isspace(cval(t)) ) ++t; Set_str_value(&job->destination,s,t); } else { Set_str_value(&job->destination,s,""); } } else { DEBUGFC(DRECV1)Dump_line_list("Get_route: dest", &job->destination ); if( (s = Find_str_value(&job->destination, DEST)) ){ int n; DEBUGF(DRECV1)("Get_route: destination '%s'", s ); Set_flag_value(&job->destination,DESTINATION,count); n = Find_flag_value(&job->destination,COPIES); if( n < 0 ){ Set_flag_value(&job->destination,COPIES,0); } plp_snprintf(buffer,sizeof(buffer), ".%d",count+1); s = safestrdup2(id,buffer,__FILE__,__LINE__); Set_str_value(&job->destination,IDENTIFIER,s); if(s) free(s); Update_destination(job); ++count; } Free_line_list(&job->destination); } } DEBUGFC(DRECV1)Dump_line_list("Get_route: dest", &job->destination ); if( (s = Find_str_value(&job->destination, DEST)) ){ int n; char buffer[32]; DEBUGF(DRECV1)("Get_route: destination '%s'", s ); Set_flag_value(&job->destination,DESTINATION,count); n = Find_flag_value(&job->destination,COPIES); if( n < 0 ){ Set_flag_value(&job->destination,COPIES,0); } plp_snprintf(buffer,sizeof(buffer), ".%d",count+1); s = safestrdup2(id,buffer,__FILE__,__LINE__); Set_str_value(&job->destination,IDENTIFIER,s); if(s) free(s); Update_destination(job); ++count; } Free_line_list(&job->destination); Set_flag_value(&job->info,DESTINATIONS,count); if(DEBUGL1)Dump_job("Get_route: final", job ); error: close(intempfd); intempfd = -1; close(tempfd); tempfd = -1; Free_line_list(&env); Free_line_list(&cf_line_list); return( errorcode ); } /* * Generate_control_file: * Generate a control file from job ticket file contents * Use the X= lines and the DATAFILES entry */ static void Generate_control_file( struct job *job ) { /* generate the control file */ int i; char *cf = 0; char *openname, *transfername, *datafiles; struct line_list dups, *lp; Init_line_list( &dups ); for( i = 0; i < job->info.count; ++i ){ char *t = job->info.list[i]; int c; if( t && (c = t[0]) && isupper(c) && c != 'N' && c != 'U' && t[1] == '=' ){ t[1] = 0; cf = safeextend4(cf,t,t+2,"\n",__FILE__,__LINE__); t[1] = '='; } } datafiles = 0; for( i = 0; i < job->datafiles.count; ++i ){ char *format, *Nv; int count, j; lp = (void *)job->datafiles.list[i]; openname = Find_str_value(lp,OPENNAME); transfername = Find_str_value(lp,DFTRANSFERNAME); if( ! transfername ) transfername = openname; format = Find_str_value(lp,FORMAT); Nv = Find_str_value(lp,"N"); count = Find_flag_value(lp,COPIES); if( Nv ){ cf = safeextend4( cf, "N", Nv,"\n",__FILE__,__LINE__); } for( j = 0; j < count; ++j ){ cf = safeextend4( cf, format, transfername,"\n",__FILE__,__LINE__); } } for( i = 0; i < job->datafiles.count; ++i ){ lp = (void *)job->datafiles.list[i]; openname = Find_str_value(lp,OPENNAME); transfername = Find_str_value(lp,DFTRANSFERNAME); if( !Find_flag_value(&dups,transfername) ){ if( openname ){ datafiles = safeextend5(datafiles, transfername, "=",openname, " ",__FILE__,__LINE__); }else{ datafiles = safeextend3(datafiles, transfername, " ",__FILE__,__LINE__); } cf = safeextend4( cf, "U", transfername,"\n",__FILE__,__LINE__); } } DEBUGF(DRECV1)("Generate_control_file: datafiles '%s'", datafiles ); Set_str_value(&job->info,DATAFILES,datafiles); if( datafiles ) free(datafiles); datafiles = 0; DEBUGF(DRECV1)("Generate_control_file: cf start '%s'", cf ); Set_str_value(&job->info,CF_OUT_IMAGE,cf); Free_line_list( &dups ); if( cf ) free(cf); cf = 0; } lprng-3.8.B/src/common/linksupport.c0000644000131400013140000013721011531672131014420 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * MODULE: Link_support.c *************************************************************************** * Support for the inter-machine communications * * int Link_port_num(char *) * gets destination port number for connection * * int Link_open(char *host, int port, int int timeout ) * opens a link to the remote host * if timeout == 0, wait indefinitely * returns socket fd (>= 0); LINK errorcode (negative) if error * * int Link_listen() * 1. opens a socket on the current host * 2. set the REUSE option on socket * 3. does a bind to port determined by Link_dest_port_num(); * * void Link_close( int timeout, int socket ) * closes the link to the remote host * * int Link_send( char *host, int *socket,int timeout, * int ch, char *line,int lf,int *ack ) * sends 'ch'line'lf' to the remote host * if write/read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * if timeout > 0, i.e.- local, set signal handler * if ch != 0, send ch at start of line * if lf != 0, send LF at end of line * if ack != 0, wait for ack * returns 0 if successful, LINK errorcode if failure * * int Link_copy( char *host, int *socket, int timeout, * char *src, int fd, double count) * copies count bytes from fd to the socket * do a timeout on both reading from fd and writing to socket; * if timeout == 0, wait indefinitely * returns 0 if successful, LINK errorcode if failure * * int Link_line_read(char *host, int *socket, int timeout, * char *str, int *count ) * reads and copies characters from socket to str until '\n' read, * '\n' NOT copied * *count points to maximum number of bytes to read; * updated with actual value read (less 1 for '\n' ) * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * if *count read and not '\n', then error set; last character * will be discarded. * returns 0 if '\n' read and read <= *count characters * 0 if EOF and no characters read (*count == 0) * LINK errorcode otherwise * NOTE: socket is NOT closed on error. * * int Link_read( char *host, int *socket, int timeout, * char *str, int *count ) * reads and copies '*count' characters from socket to str * *count points to maximum number of bytes to read; * updated with actual value read * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * returns 0 *count not read * LINK errorcode otherwise * * int Link_file_read( char *host, int *socket, int readtimeout, * int writetimeout, int fd, int *count, int *ack ) * reads and copies '*count' characters from socket to fd * *count points to maximum number of bytes to read; * updated with actual value read * if ack then will read an additional ACK character * returns value in *ack * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * returns 0 *count not read * ***************************************************************************/ /*************************************************************************** * Commentary: * Patrick Powell Fri Apr 14 16:43:10 PDT 1995 * * These routines have evolved with experience from other systems. * The connection to the remote system involves 4 components: * < local_ip, local_port, remote_ip, remote_port > * * Local_ip: There appears to be little reason done to restrict * a system to originate a connection from a specific IP address. * * Local_port: The BSD UNIX networking software had a concept of reserved * ports for binding, i.e.- only root could bind (accept on or originate * connections from) ports 1-1023. However, this is now bogus given PCs * that can use any port. The requirement is specified in RFC1179, which * requires origination of connections from 721-731. Ummm... there is a * problem with doing this, as there is also a TCP/IP requirement that * a port not be reused withing 2*maxLt (10 minutes). If you spool a * lot of jobs from a host, you will have problems. You have to use * setsockopt( s, SOL_SOCKET, SO_REUSEADDR, 0, 0 ) to allow reuse of the * port, otherwise you may run out of ports to use. * * When using a Unix system, you can run non-privileged or privileged. * The remote system will determine if it is going to accept connections * or not. Thus, there is the following possibilities * 1. remote system wants PRIV port, and cannot open them (not root) * - hard failure, need root privs * 2. remote system wants PRIV port, and non available * - soft failure, can retry after timeout * 3. remote system doesnt care, cannot get priv port * - try getting unpriv port * 4. remote system doesnt care, cannot get unpriv port * - hard failure. Something is very wrong here! * * Configuration options: * The following options in the configuration file can be used to * specify control over the local port: * * originate_port (default: blank same as lowportnumber = 0) * originate_port lowportnumber [highportnumber] * If lowportnumber is missing or 0, then non-restricted * ports will be used. * If lowportnumber is non-zero (true), and no high port number is * present, then a port in the range lowportnumber-1023 will be used. * If both the lowport and highport and highport numbers * are present, a port in the range lowportnumber-highportnumber * will be used. * ***************************************************************************/ #include "lp.h" #include "linksupport.h" #include "gethostinfo.h" #include "errorcodes.h" /**** ENDINCLUDE ****/ /*************************************************************************** * int Link_open(char *host, int port, int timeout ); * 1. Set up an inet socket; a socket has a local host/local port and * remote host/remote port address part. The routine * will attempt to open a privileged port (number less than * PRIV); if this fails, it will open a non-privileged port * 2. Connect to the remote host on the port specified as follows: * 1. Lpd_port_DYN - (string) look up with getservbyname("printer","tcp") * 2. Lpd_port_DYN - (string) convert to integer if possible * 3. look up getservbyname("printer","tcp") * Give up with error message * * In RFC1192, it specifies that the originating ports will be in * a specified range, 721-731; Since a reserved port can only * be accessed by UID 0 (root) processes, this would appear to prevent * ordinary users from directly contacting the remote daemon. * However, enter the PC. We can generate a connection from ANY port. * Thus, all of these restrictions are somewhat bogus. We use the * configuration file 'PORT' restrictions instead ***************************************************************************/ int Link_setreuse( int sock ) { int status = 0; #ifdef SO_REUSEADDR int option = 1; status = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, (char *)&option, sizeof(option) ); #endif return( status ); } static int Link_setkeepalive( int sock ) { int status = 0; #ifdef SO_KEEPALIVE int option = 1; status = setsockopt( sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&option, sizeof(option) ); #endif return( status ); } /* * int getconnection ( char *hostname, int timeout, int connection_type ) * opens a connection to the remote host */ static int connect_timeout( int timeout, int sock, struct sockaddr *name, int namelen) { int status = -1; int err = 0; if( Set_timeout() ){ Set_timeout_alarm( timeout ); status = connect(sock, name, namelen ); err = errno; } else { status = -1; err = errno; } Clear_timeout(); errno = err; return( status ); } static int getconnection ( char *xhostname, int timeout, int connection_type, struct sockaddr *bindto, char *unix_socket_path, char *errmsg, int errlen ) { int sock; /* socket */ int i, err; /* ACME Generic Integers */ struct sockaddr_in dest_sin; /* inet socket address */ struct sockaddr_in src_sin; /* inet socket address */ int maxportno, minportno; int euid; int status = -1; /* status of operation */ plp_block_mask oblock; int port_count = 0; /* numbers of ports tried */ int connect_count = 0; /* number of connections tried */ int port_number; int range; /* range of ports */ char *use_host; int address_count = 0; int incoming_port; char *dest_port = 0; static int last_port_used; char hostname[256]; /* * find the address */ safestrncpy(hostname,xhostname); if( (dest_port = strchr(hostname,'%')) ){ *dest_port++ = 0; } DEBUGF(DNW1)("getconnection: START host %s, port %s, timeout %d, connection_type %d", hostname, dest_port, timeout, connection_type ); euid = geteuid(); sock = -1; memset(&dest_sin, 0, sizeof (dest_sin)); memset(&src_sin, 0, sizeof (src_sin)); dest_sin.sin_family = AF_Protocol(); if( Find_fqdn( &LookupHost_IP, hostname ) ){ /* * Get the destination host address and remote port number to connect to. */ DEBUGF(DNW1)("getconnection: fqdn found %s, h_addr_list count %d", LookupHost_IP.fqdn, LookupHost_IP.h_addr_list.count ); dest_sin.sin_family = LookupHost_IP.h_addrtype; if( LookupHost_IP.h_length > (int)sizeof( dest_sin.sin_addr ) ){ Errorcode = JABORT; fatal(LOG_ALERT, "getconnection: addresslength outsize value"); } memcpy( &dest_sin.sin_addr, LookupHost_IP.h_addr_list.list[address_count], LookupHost_IP.h_length ); } else if( inet_pton( AF_Protocol(), hostname, &dest_sin.sin_addr ) != 1 ){ (void) plp_snprintf(errmsg, errlen, "getconnection: cannot get address for '%s'", hostname ); DEBUGF(DNW2)("getconnection: cannot get address for '%s'", hostname ); return( LINK_OPEN_FAIL ); } /* UNIX socket connection for localhost support */ DEBUGF(DNW1)("getconnection: unix_socket_path %s", unix_socket_path ); /* check to see if the flag is set and the destination is one of the localhost addresses */ if( !ISNULL(unix_socket_path) && safestrcasecmp( "off", unix_socket_path ) && ( !Same_host(&LookupHost_IP,&Host_IP) || !Same_host(&LookupHost_IP,&Localhost_IP) ) ){ /* taken from Unix Network Programming, Volume 1, 2nd Edition * by W. Richard Stevens. With great thanks to his memory * and his amazingly detailed reference monographs. */ struct sockaddr_un dest_un; /* unix socket address */ memset( &dest_un, 0, sizeof(dest_un) ); DEBUGF(DNW1)("getconnection: using unix socket"); plp_block_all_signals( &oblock ); if( UID_root ) (void)To_euid_root(); safestrncpy( dest_un.sun_path, unix_socket_path ); #ifdef AF_LOCAL dest_un.sun_family = AF_LOCAL; #else dest_un.sun_family = AF_UNIX; #endif sock = socket(dest_un.sun_family, SOCK_STREAM, 0); err = errno; if( UID_root ) (void)To_euid( euid ); plp_set_signal_mask( &oblock, 0 ); Max_open(sock); if( sock < 0 ){ errno = err; logerr_die(LOG_DEBUG, "getconnection: UNIX domain socket call failed"); } DEBUGF(DNW2) ("getconnection: unix domain socket %d", sock); /* * set up timeout and then make connect call */ errno = 0; status = -1; Alarm_timed_out = 0; use_host = Unix_socket_path_DYN; DEBUGF(DNW2)("getconnection: trying connect to UNIX domain socket '%s', timeout %d", use_host, timeout ); status = connect_timeout(timeout,sock, (struct sockaddr *) &dest_un, sizeof(dest_un)); err = errno; DEBUGF(DNW2)( "getconnection: connect sock %d, status %d, err '%s', timedout %d", sock, status, Errormsg(err), Alarm_timed_out ); if( status < 0 || Alarm_timed_out ){ (void) close (sock); sock = LINK_OPEN_FAIL; if( Alarm_timed_out ) { DEBUGF(DNW1)("getconnection: connection to '%s' timed out", use_host); err = errno = ETIMEDOUT; } else { DEBUGF(DNW1)("getconnection: connection to '%s' failed '%s'", use_host, Errormsg(err) ); } } errno = err; return (sock); } if( ISNULL(dest_port) ) dest_port = Lpd_port_DYN; dest_sin.sin_port = Link_dest_port_num(dest_port); if( dest_sin.sin_port == 0 ){ (void) plp_snprintf(errmsg, errlen, "getconnection: using illegal port '%s' for connection to '%s'!\n", dest_port, hostname ); logmsg(LOG_INFO, "getconnection: using illegal port '%s' for connection to '%s'!\n", dest_port, hostname ); return( JABORT ); } /* handle multi-homed hosts with bad ideas about network connections, i.e. - firewalls */ next_addr: DEBUGF(DNW2)("getconnection: destination IP '%s' port %d", inet_ntoa( dest_sin.sin_addr ), ntohs( dest_sin.sin_port ) ); /* check on the low and high port values */ /* we decode the minimum and maximum range */ maxportno = minportno = 0; if( Originate_port_DYN ){ char *s, *end; int c; s = end = Originate_port_DYN; maxportno = strtol( s, &end, 0 ); if( s != end ){ s = end; while( (c = cval(s)) && !isdigit(c) ) ++s; minportno = strtol( s, 0, 0 ); } } DEBUGF(DNW2)( "getconnection: Originate_port_DYN '%s' minportno %d, maxportno %d", Originate_port_DYN, minportno, maxportno ); /* check for reversed order ... */ if( maxportno < minportno ){ i = maxportno; maxportno = minportno; minportno = i; } /* check for only one */ if( minportno == 0 ){ minportno = maxportno; } /* * if not running SUID root or not root user * check to see if we have less than reserved port */ if( !UID_root && minportno < IPPORT_RESERVED ){ minportno = IPPORT_RESERVED; if( minportno > maxportno ){ minportno = maxportno = 0; } } range = maxportno - minportno; port_count = 0; /* numbers of ports tried */ port_number = 0; connect_count = 0; /* number of connections tried */ port_number = 0; if( minportno ){ port_number = minportno; if( range ){ if( last_port_used && last_port_used >= minportno ){ port_number = ++last_port_used; } else { srand(getpid()); port_number = minportno + (abs(rand()>>8) % range); } } if( port_number > maxportno){ port_number = minportno; } } /* we now have a range of ports and a starting position * Note 1: if minportno == 0, then we use assignment by connect * and do not set SOCKREUSE. We only try once. * * Note 2: if minportno != 0, then we get port in range. * we DO set SOCKREUSE if Reuse_addr_DYN set. This is necessary * as some printers will not accept a new connection from the same * port as before. * * Note 3. we try all ports in range; if none work, * we get an error. * * * do the sock et, bind and the set reuse flag operation as * ROOT; this appears to be the side effect of some * very odd system implementations. Note that you can * read and write to the socket as a user. */ DEBUGF(DNW2)("getconnection: minportno %d, maxportno %d, range %d, port_number %d", minportno, maxportno, range, port_number ); again: DEBUGF(DNW1)("getconnection: AGAIN port %d, min %d, max %d, count %d, connects %d", port_number, minportno, maxportno, port_count, connect_count ); DEBUGF(DNW2)("getconnection: protocol %d, connection_type %d", AF_Protocol(), connection_type ); plp_block_all_signals( &oblock ); if( UID_root ) (void)To_euid_root(); sock = socket(AF_Protocol(), connection_type, 0); err = errno; if( UID_root ) (void)To_euid( euid ); plp_set_signal_mask( &oblock, 0 ); Max_open(sock); if( sock < 0 ){ errno = err; logerr_die(LOG_DEBUG, "getconnection: socket call failed"); } DEBUGF(DNW2) ("getconnection: socket %d", sock); /* bind to an outgoing port if you need to */ if( minportno || bindto ){ incoming_port = ntohs(Link_dest_port_num(0)); do{ last_port_used = port_number; status = -1; if( bindto == 0 ){ src_sin.sin_family = AF_Protocol(); src_sin.sin_addr.s_addr = INADDR_ANY; } else { src_sin.sin_family = ((struct sockaddr_in *)bindto)->sin_family; src_sin.sin_addr = ((struct sockaddr_in *)bindto)->sin_addr; } if( port_number > maxportno ) port_number = minportno; /* make sure we don't use the port 515 */ if( port_number == incoming_port ) continue; DEBUGF(DNW2) ("getconnection: trying port %d, bound to addr '%s'", port_number, inet_ntoa(src_sin.sin_addr) ); src_sin.sin_port = htons((u_short)(port_number)); /* set the reuse_addr before bind */ status = 0; if( Reuse_addr_DYN ){ /* set up the 'resuse' flag on socket, or you may not be able to reuse a port for up to 10 minutes */ /* we do the next without interrupts and as root */ plp_block_all_signals( &oblock ); if( UID_root ) (void)To_euid_root(); status = Link_setreuse( sock ); err = errno; if( UID_root ) (void)To_euid( euid ); plp_set_signal_mask( &oblock, 0 ); DEBUGF(DNW2) ("getconnection: sock %d, reuse status %d", sock, status ); if( status < 0 ){ logerr(LOG_ERR, "getconnection: set SO_REUSEADDR failed" ); } } if( status >= 0 ){ /* we do the next without interrupts */ plp_block_all_signals( &oblock ); if( UID_root ) (void)To_euid_root(); status = bind(sock, (struct sockaddr *)&src_sin, sizeof(src_sin)); err = errno; if( UID_root ) (void)To_euid( euid ); plp_set_signal_mask( &oblock, 0 ); DEBUGF(DNW2) ("getconnection: bind returns %d, sock %d, port %d, src '%s'", status, sock, ntohs(src_sin.sin_port), inet_ntoa(src_sin.sin_addr) ); } if( status >= 0 && Keepalive_DYN ){ /* we do the next without interrupts */ plp_block_all_signals( &oblock ); if( UID_root ) (void)To_euid_root(); status = Link_setkeepalive( sock ); err = errno; if( UID_root ) (void)To_euid( euid ); plp_set_signal_mask( &oblock, 0 ); if( status < 0 ){ logerr(LOG_ERR, "getconnection: set SO_KEEPALIVE failed" ); } } } while( ++port_number && status < 0 && ++port_count < range ); if( status < 0 ){ close( sock ); sock = LINK_OPEN_FAIL; logerr(LOG_DEBUG, "getconnection: cannot bind to port"); return( sock ); } } /* * set up timeout and then make connect call */ errno = 0; status = -1; Alarm_timed_out = 0; use_host = hostname; DEBUGF(DNW2)("getconnection: trying connect to '%s', timeout %d", use_host, timeout ); status = connect_timeout(timeout,sock, (struct sockaddr *) &dest_sin, sizeof(dest_sin)); err = errno; DEBUGF(DNW2)( "getconnection: connect sock %d, status %d, err '%s', timedout %d", sock, status, Errormsg(err), Alarm_timed_out ); if( status < 0 || Alarm_timed_out ){ (void) close (sock); sock = LINK_OPEN_FAIL; if( Alarm_timed_out ) { DEBUGF(DNW1)("getconnection: connection to '%s' timed out", use_host); err = errno = ETIMEDOUT; } else { DEBUGF(DNW1)("getconnection: connection to '%s' failed '%s'", use_host, Errormsg(err) ); } if( err == ECONNREFUSED ){ sock = LINK_ECONNREFUSED; } if( err == ETIMEDOUT ){ sock = LINK_ETIMEDOUT; } ++connect_count; if( connect_count < range && ( (Retry_ECONNREFUSED_DYN && err == ECONNREFUSED) || err == EADDRINUSE || err == EADDRNOTAVAIL ) ){ goto again; } /* try next address in list */ if( ++address_count < LookupHost_IP.h_addr_list.count ){ memcpy( &dest_sin.sin_addr, LookupHost_IP.h_addr_list.list[address_count], LookupHost_IP.h_length ); goto next_addr; } } else { socklen_t len; len = sizeof( src_sin ); if( getsockname( sock, (struct sockaddr *)&src_sin, &len ) < 0 ){ logerr_die(LOG_ERR, "getconnnection: getsockname failed" ); } DEBUGF(DNW1)( "getconnection: sock %d, src ip %s, port %d", sock, inet_ntoa( src_sin.sin_addr ), ntohs( src_sin.sin_port ) ); DEBUGF(DNW1)( "getconnection: dest ip %s, port %d", inet_ntoa( dest_sin.sin_addr ), ntohs( dest_sin.sin_port ) ); if( Socket_linger_DYN > 0 ){ Set_linger( sock, Socket_linger_DYN ); } } DEBUGF(DNW1)("getconnection: connection to '%s' socket %d, errormsg '%s'", use_host, sock, Errormsg(err) ); errno = err; return (sock); } void Set_linger( int sock, int n ) { #ifdef SO_LINGER socklen_t len; struct linger option; len = sizeof( option ); DEBUGF(DNW2) ("Set_linger: SO_LINGER socket %d, value %d", sock, n ); if( getsockopt( sock,SOL_SOCKET,SO_LINGER,(char *)&option, &len) == -1 ){ DEBUGF(DNW2) ("Set_linger: getsockopt linger failed - '%s'", Errormsg(errno) ); return; } DEBUGF(DNW4) ("Set_linger: SO_LINGER socket %d, onoff %d, linger %d", sock, (int)(option.l_onoff), (int)(option.l_linger)); if( n > 0 ){ option.l_onoff = 1; option.l_linger = n; } else { option.l_onoff = 0; option.l_linger = 0; } if( setsockopt( sock, SOL_SOCKET, SO_LINGER, (char *)&option, sizeof(option) ) == -1 ){ DEBUGF(DNW2) ("Set_linger: setsockopt linger %d failed - '%s'", n, Errormsg(errno) ); } #else DEBUGF(DNW2) ("Set_linger: NO SO_LINGER, socket %d, value %d", sock, n); #endif } /* * int Link_listen(port) * 1. opens a socket on the current host * 2. set the REUSE option on socket * 3. does a bind to port determined by Link_dest_port_num(); */ int Link_listen( char *port_name ) { int sock; /* socket */ int status; /* socket */ struct sockaddr_in sinaddr; /* inet socket address */ int euid; /* euid at time of call*/ int port; int err; char *s; /* * Zero out the sockaddr_in struct */ memset(&sinaddr, 0, sizeof (sinaddr)); /* * Get the destination host address and remote port number to connect to. */ sinaddr.sin_family = AF_Protocol(); sinaddr.sin_addr.s_addr = INADDR_ANY; if( (s = safestrchr( port_name, '%')) ){ *s = 0; if( Find_fqdn( &LookupHost_IP, port_name ) ){ /* * Get the destination host address and remote port number to connect to. */ DEBUGF(DNW1)("Link_listen: fqdn found %s, h_addr_list count %d", LookupHost_IP.fqdn, LookupHost_IP.h_addr_list.count ); sinaddr.sin_family = LookupHost_IP.h_addrtype; if( LookupHost_IP.h_length > (int)sizeof( sinaddr.sin_addr ) ){ fatal(LOG_ALERT, "getconnection: addresslength outsize value"); } /* use the first address in the list */ memcpy( &sinaddr.sin_addr, LookupHost_IP.h_addr_list.list[0], LookupHost_IP.h_length ); } else if( inet_pton( AF_Protocol(), port_name, &sinaddr.sin_addr ) != 1 ){ *s = '%'; Errorcode = JABORT; fatal(LOG_ERR, "Link_listen: bad lpd_port value, cannot resolve IP address '%s'", port_name ); } sinaddr.sin_port = Link_dest_port_num(s+1); *s = '%'; } else if( port_name ){ sinaddr.sin_port = Link_dest_port_num(port_name); } port = ntohs( sinaddr.sin_port ); DEBUGF(DNW2)("Link_listen: bind to IP '%s' port %d", inet_ntoa( sinaddr.sin_addr ), ntohs( sinaddr.sin_port ) ); if( port == 0 ){ errno = 0; return( 0 ); } euid = geteuid(); if( UID_root ) (void)To_euid_root(); errno = 0; status = (sock = socket (AF_Protocol(), SOCK_STREAM, 0)) < 0 || Link_setreuse( sock ) < 0 || (Keepalive_DYN && Link_setkeepalive( sock ) < 0) || bind(sock, (struct sockaddr *)&sinaddr, sizeof(sinaddr)) < 0; err = errno; if( UID_root ) (void)To_euid( euid ); if( status ){ DEBUGF(DNW4)("Link_listen: bind to lpd port %d failed '%s'", port, Errormsg(err)); if( sock >= 0 ){ (void)close( sock ); sock = -1; } errno = err; return( LINK_BIND_FAIL ); } status = listen(sock, 64 ); /* backlog of 10 is inadequate */ err = errno; if( status ){ logerr_die(LOG_ERR, "Link_listen: listen failed"); (void)close( sock ); sock = -1; err = errno; return( LINK_OPEN_FAIL ); } DEBUGF(DNW4)("Link_listen: port %d, socket %d", ntohs( sinaddr.sin_port ), sock); errno = err; return (sock); } int Unix_link_listen( char *unix_socket_path ) { int sock; /* socket */ int status; /* socket */ struct sockaddr_un sunaddr; /* inet socket address */ int euid; /* euid at time of call*/ int err; int omask; euid = geteuid(); DEBUGF(DNW2)("Unix_link_listen: path %s", unix_socket_path ); /* * Zero out the sunaddr struct */ memset(&sunaddr, 0, sizeof (sunaddr)); /* * Get the destination host address and remote port number to connect to. */ DEBUGF(DNW1)("Unix_link_listen: using unix socket"); safestrncpy( sunaddr.sun_path, Unix_socket_path_DYN ); #ifdef AF_LOCAL sunaddr.sun_family = AF_LOCAL; #else sunaddr.sun_family = AF_UNIX; #endif if( UID_root ) (void)To_euid_root(); unlink( sunaddr.sun_path ); status = ((sock = socket (sunaddr.sun_family, SOCK_STREAM, 0)) < 0); err = errno; if( UID_root ) (void)To_euid( euid ); Max_open(sock); if( sock < 0 ){ errno = err; logerr_die(LOG_DEBUG, "Unix_link_listen: UNIX domain socket call failed"); } omask = umask(0); if( UID_root ) (void)To_euid_root(); status = bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0; err = errno; if( UID_root ) (void)To_euid( euid ); umask(omask); if( status ){ DEBUGF(DNW4)("Unix_link_listen: bind to unix port %s failed '%s'", Unix_socket_path_DYN, Errormsg(err)); if( sock >= 0 ){ (void)close( sock ); sock = -1; } errno = err; return( LINK_BIND_FAIL ); } if( UID_root ) (void)To_euid_root(); status = listen(sock, 64 ); /* backlog of 10 is inadequate */ err = errno; if( UID_root ) (void)To_euid( euid ); if( status ){ logerr_die(LOG_ERR, "Unix_link_listen: listen failed"); (void)close( sock ); sock = -1; err = errno; return( LINK_OPEN_FAIL ); } DEBUGF(DNW4)("Unix_link_listen: socket %d", sock); errno = err; return (sock); } int Link_open(char *host, int timeout, struct sockaddr *bindto, char *unix_socket_path, char *errmsg, int errlen ) { int sock; DEBUGF(DNW4) ("Link_open: host '%s', timeout %d", host, timeout); sock = Link_open_type( host, timeout, SOCK_STREAM, bindto, unix_socket_path, errmsg, errlen ); DEBUGF(DNW4) ("Link_open: socket %d", sock ); return(sock); } int Link_open_type(char *host, int timeout, int connection_type, struct sockaddr *bindto, char * unix_socket_path, char *errmsg, int errlen ) { int sock = -1; DEBUGF(DNW4)( "Link_open_type: host '%s', timeout %d, type %d", host, timeout, connection_type ); sock = getconnection( host, timeout, connection_type, bindto, unix_socket_path, errmsg, errlen ); DEBUGF(DNW4) ("Link_open_type: socket %d", sock ); return( sock ); } int Link_open_list( char *hostlist, char **result, int timeout, struct sockaddr *bindto, char *unix_socket_path, char *errmsg, int errlen ) { int sock = -1, i, err = 0; struct line_list list; Init_line_list( &list ); DEBUGFC(DNW4){ LOGDEBUG( "Link_open_line_list_type: hostlist '%s', timeout %d, bindto 0x%lx", hostlist, timeout, Cast_ptr_to_long(bindto) ); } if( result ) *result = 0; Split(&list,hostlist,Host_sep,0,0,0,0,0,0); err = errno = 0; for( i = 0; sock < 0 && i < list.count; ++i ){ DEBUGF(DNW4) ("Link_open_list: host trying '%s'", list.list[i] ); sock = getconnection( list.list[i], timeout, SOCK_STREAM, bindto, unix_socket_path, errmsg, errlen ); err = errno; DEBUGF(DNW4) ("Link_open_list: result host '%s' socket %d", list.list[i], sock ); if( sock >= 0 ){ if( result ){ *result = safestrdup( list.list[i], __FILE__, __LINE__ ); } break; } } errno = err; Free_line_list(&list); return( sock ); } /*************************************************************************** * void Link_close( int timeout, int socket ) * closes the link to the remote host * We first do a shutdown(*sock,1) and THEN do a close ***************************************************************************/ void Link_close( int timeout, int *sock ) { char buf[SMALLBUFFER]; DEBUGF(DNW4) ("Link_close: closing socket %d", *sock ); if( *sock >= 0 ){ shutdown(*sock,1); while( Read_fd_len_timeout(timeout, *sock,buf,sizeof(buf)) > 0 ); (void)close(*sock); } *sock = -1; } /*************************************************************************** * int Link_send( char *host, int *socket, int timeout, * char ch, char *str, int lf, int *ack ) * sends 'ch'str to the remote host * if write/read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * if ch != 0, send ch at start of line * if lf != 0, send LF at end of line * if ack != 0, wait for ack, and report it * returns 0 if successful, LINK errorcode if failure * closes socket and sets to LINK errorcode if a failure * NOTE: if timeout > 0, local to this function; * if timeout < 0, global to all functions * * Note: several implementations of LPD expect the line to be written/read * with a single system call (i.e.- TPC/IP does not have the PSH flag * set in the output stream until the last byte, for those in the know) * After having gnashed my teeth and pulled my hair, I have modified * this code to try to use a single write. Note that timeouts, errors, * interrupts, etc., may render this impossible on some systems. * Tue Jul 25 05:50:54 PDT 1995 Patrick Powell ***************************************************************************/ int Link_send( char *host, int *sock, int timeout, const char *sendstr, int count, int *ack ) { int i; /* Watch out for longjmp * ACME Integers, Inc. */ int status; /* return status */ int err = 0; /* * set up initial conditions */ i = status = 0; /* shut up GCC */ if(*sock < 0) { DEBUGF(DNW1)( "Link_send: bad socket" ); return( LINK_TRANSFER_FAIL ); } if( ack ){ *ack = 0; } DEBUGF(DNW1)( "Link_send: host '%s' socket %d, timeout %d", host, *sock, timeout ); DEBUGF(DNW1)( "Link_send: str '%s', count %d, ack 0x%p", sendstr, count , ack ); /* * set up timeout and then write */ i = Write_fd_len_timeout( timeout, *sock, sendstr, count ); /* now decode the results */ DEBUGF(DNW2)("Link_send: final write status %d", i ); if( i < 0 || Alarm_timed_out ){ if( Alarm_timed_out ){ DEBUGF(DNW2)("Link_send: write to '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else { DEBUGF(DNW2)("Link_send: write to '%s' failed '%s'", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } } /* check for an ACK to be received */ if( status == 0 && ack ){ char buffer[1]; DEBUGF(DNW2)("Link_send: ack required" ); buffer[0] = 0; i = Read_fd_len_timeout(timeout, *sock, buffer, 1 ); err = errno; DEBUGF(DNW2)("Link_send: read status '%d'", i ); if( i < 0 || Alarm_timed_out ){ if( Alarm_timed_out ){ DEBUGF(DNW2)("Link_send: ack read from '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else { DEBUGF(DNW2)("Link_send: ack read from '%s' failed - %s", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } } else if( i == 0 ){ DEBUGF(DNW2)("Link_send: ack read EOF from '%s'", host ); status = LINK_TRANSFER_FAIL; } else if( buffer[0] ){ *ack = buffer[0]; status = LINK_ACK_FAIL; } DEBUGF(DNW2)("Link_send: read %d, status %s, ack=%s", i, Link_err_str(status), Ack_err_str(*ack) ); if( Check_for_protocol_violations_DYN && status == 0 && *ack == 0 ){ /* check to see if you have some additional stuff pending */ fd_set readfds; struct timeval delay; memset( &delay,0,sizeof(delay)); /* delay.tv_usec = 1000; */ FD_ZERO( &readfds ); FD_SET( *sock, &readfds ); i = select( (*sock)+1, &readfds, NULL, NULL, &delay ); if( i > 0 ){ logmsg( LOG_ERR, "Link_send: PROTOCOL ERROR - pending input from '%s' after ACK received", host ); } } } DEBUGF(DNW1)("Link_send: final status %s", Link_err_str(status) ); return (status); } /*************************************************************************** * int Link_copy( char *host, int *socket, int timeout, * char *src, int fd, int count) * copies count bytes from fd to the socket * if write does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * if count < 0, will read until end of file * returns 0 if successful, LINK errorcode if failure ***************************************************************************/ int Link_copy( char *host, int *sock, int readtimeout, int writetimeout, const char *src, int fd, double pcount) { char buf[LARGEBUFFER]; /* buffer */ int len; /* ACME Integer, Inc. */ int status; /* status of operation */ double count; /* might be clobbered by longjmp */ int err; /* saved error status */ count = pcount; len = status = 0; /* shut up GCC */ DEBUGF(DNW4)("Link_copy: sending %0.0f of '%s' to %s, rdtmo %d, wrtmo %d, fd %d", count, src, host, readtimeout, writetimeout, fd ); /* check for valid sock */ if(*sock < 0) { DEBUGF(DNW4)( "Link_copy: bad socket" ); return (LINK_OPEN_FAIL); } /* do the read */ while( status == 0 && (count > 0 || pcount == 0) ){ len = sizeof(buf); if( pcount && len > count ) len = count; /* do the read with timeout */ len = Read_fd_len_timeout( readtimeout, fd, buf, len ); err = errno; DEBUGF(DNW4)("Link_copy: read %d bytes", len ); if( pcount && len > 0 ) count -= len; if( Alarm_timed_out || len <= 0 ){ /* EOF on input */ if( pcount && count > 0 ){ DEBUGF(DNW4)( "Link_copy: read from '%s' failed, %0.0f bytes left - %s", src, count, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } else { DEBUGF(DNW4)("Link_copy: read status %d count %0.0f", len, count ); status = 0; } break; } len = Write_fd_len_timeout(writetimeout, *sock, buf, len ); DEBUGF(DNW4)("Link_copy: write done, status %d", len ); if( len < 0 || Alarm_timed_out ){ if( Alarm_timed_out ){ DEBUGF(DNW4)("Link_copy: write to '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else { DEBUGF(DNW4)("Link_copy: write to '%s' failed - %s", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } } } if( status == 0 ){ /* check to see if you have some additional stuff pending */ fd_set readfds; struct timeval delay; int i; memset( &delay,0,sizeof(delay)); FD_ZERO( &readfds ); FD_SET( *sock, &readfds ); i = select( *sock+1, &readfds, NULL, NULL, &delay ); if( i != 0 ){ logmsg( LOG_ERR, "Link_copy: PROTOCOL ERROR - pending input from '%s' after transfer", host ); } } DEBUGF(DNW4)("Link_copy: status %d", status ); return( status ); } /*************************************************************************** * Link_dest_port_num ( char *port ) * Get the destination port number * look up the service in the service directory using getservent * returned in the network standard order * The port specification can be host%port * if none is specified the Lpd_port_DYN used ***************************************************************************/ int Link_dest_port_num( char *port ) { struct servent *sp; int port_num = 0; char *s; if( port == 0 ) port = Lpd_port_DYN; if( port == 0 ){ Errorcode = JABORT; fatal( LOG_ERR, "Link_dest_port_num: LOGIC ERROR! no port number!"); } if( (s = strchr(port, '%')) ) port = s+1; s = 0; port_num = strtol(port,&s,0); port_num = htons(port_num); if( s == 0 || *s ){ if( (sp = getservbyname(port, "tcp")) == 0) { DEBUGF(DNW4)("getservbyname(\"%s\",tcp) failed", port); /* try integer value */ port_num = 0; } else { port_num = sp->s_port; } } DEBUGF(DNW1)("Link_dest_port_num: port %s = %d", port, ntohs( port_num ) ); return (port_num); } /*************************************************************************** * int Link_line_read(char *host, int *sock, int timeout, * char *str, int *count ) * reads and copies characters from socket to str until '\n' read, * '\n' NOT copied. \r\n -> \n * *count points to maximum number of bytes to read; * updated with actual value read (less 1 for '\n' ) * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * if *count read and not '\n', then error set; last character * will be discarded. * returns 0 if '\n' read at or before *count characters * 0 if EOF and no characters read (*count == 0) * LINK errorcode otherwise ***************************************************************************/ int Link_line_read(char *host, int *sock, int timeout, char *buf, int *count ) { int i, len, max, err = 0; /* ACME Integer, Inc. */ int status; /* status of operation */ int cr, lf; /* lf found */ len = i = status = 0; /* shut up GCC */ max = *count; *count = 0; buf[0] = 0; DEBUGF(DNW1) ("Link_line_read: reading %d from '%s' on %d, timeout %d", max, host, *sock, timeout ); /* check for valid socket */ if(*sock < 0) { DEBUGF(DNW4)("Link_line_read: bad socket" ); *count = 0; return (LINK_OPEN_FAIL); } /* * set up timeout and then do operation */ cr = lf = len = 0; errno = 0; while( len < max-1 &&(i = Read_fd_len_timeout(timeout, *sock, &buf[len], 1 )) > 0 && !Alarm_timed_out ){ if( (lf = (buf[len] == '\n')) ){ break; } if( (cr = (buf[len] == '\r')) ){ cr = 1; } else { ++len; } } err = errno; buf[len] = 0; DEBUGF(DNW2)( "Link_line_read: read %d, timeout %d, '%s'", len, Alarm_timed_out, buf); /* * conditions will be: * long line, timeout, error, or OK */ if( Alarm_timed_out ){ DEBUGF(DNW4)( "Link_line_read: read from '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else if( i == 0 ){ DEBUGF(DNW4)("Link_line_read: EOF from '%s'", host ); if( len != 0 ){ status = LINK_TRANSFER_FAIL; } } else if( i < 0 ){ DEBUGF(DNW4)("Link_line_read: read from '%s' failed - %s", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } else if( lf == 0 ){ DEBUGF(DNW4)("Link_line_read: no LF on line from '%s'", host ); status = LINK_LONG_LINE_FAIL; } *count = len; DEBUGF(DNW4)("Link_line_read: status %d, len %d", status, len ); errno = err; return( status ); } /*************************************************************************** * int Link_read(char *host, int *sock, int timeout, * char *str, int *count ) * reads and copies '*count' characters from socket to str * *count points to maximum number of bytes to read; * updated with actual value read * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * returns 0 *count not read * LINK errorcode otherwise ***************************************************************************/ int Link_read(char *host, int *sock, int timeout, char *buf, int *count ) { int len, i, status; /* ACME Integer, Inc. */ char *str; /* input buffer pointer */ int err; status = 0; /* shut up GCC */ DEBUGF(DNW1) ("Link_read: reading %d from '%s' on socket %d", *count, host, *sock ); /* check for valid socket */ if(*sock < 0) { DEBUGF(DNW1)( "Link_read: bad socket" ); return (LINK_OPEN_FAIL); } if( *count < 0 ) *count = 0; len = *count; *count = 0; str = buf; /* * set up timeout and then do operation */ i = Read_fd_len_timeout(timeout, *sock, str, len ); err = errno; if( i >= 0 ){ *count = i; } DEBUGFC(DNW2){ char shortpart[32]; shortpart[0] = 0; if( i > 0 ){ safestrncpy( shortpart, str ); } LOGDEBUG( "Link_read: wanted %d, got %d, start='%s'", len, i, shortpart ); } if( Alarm_timed_out ){ DEBUGF(DNW2)("Link_read: read %d from '%s' timed out", len, host ); status = LINK_TRANSFER_FAIL; } else if( i < 0 ) { DEBUGF(DNW2)("Link_read: read %d from '%s' failed, returned %d - %s", len, host, i, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } errno = err; return( status ); } /*************************************************************************** * int Link_file_read( char *host, int *sock, int readtimeout, * int writetimeout, int fd, int *count, int *ack ) * reads and copies '*count' characters from socket to fd * *count points to maximum number of bytes to read; * updated with actual value read * if ack then will read an additional ACK character * returns value in *ack * if read does not complete within timeout seconds, * terminate action with error. * if timeout == 0, wait indefinitely * returns 0 *count not read * ***************************************************************************/ int Link_file_read(char *host, int *sock, int readtimeout, int writetimeout, int fd, double *count, int *ack ) { char str[LARGEBUFFER]; /* input buffer pointer */ int i, l, cnt; /* number to read or write */ int status; /* status of operation */ int err; /* error */ double len; double readcount; len = i = status = cnt = 0; /* shut up GCC */ readcount = 0; *ack = 0; DEBUGF(DNW1) ("Link_file_read: reading %0.0f from '%s' on %d", *count, host, *sock ); /* check for valid socket */ if(*sock < 0) { DEBUGF(DNW2)( "Link_file_read: bad socket" ); return (LINK_OPEN_FAIL); } /* * set up timeout and then do the transfer */ /* do the read */ len = *count; while( status == 0 && (*count == 0 || len > 0) ){ DEBUGF(DNW2)("Link_file_read: doing data read" ); l = sizeof(str); if( *count && l > len ) l = len; i = Read_fd_len_timeout( readtimeout, *sock, str, l ); err = errno; if( Alarm_timed_out ){ DEBUGF(DNW2)( "Link_file_read: read from '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else if( i > 0 ){ DEBUGF(DNW2)("Link_file_read: len %0.0f, readlen %d, read %d", len, l, i ); if( *count ) len -= i; readcount += i; cnt = Write_fd_len_timeout(writetimeout, fd, str, i ); err = errno; if( Alarm_timed_out || cnt < 0 ){ DEBUGF(DNW2)( "Link_file_read: write %d to fd %d failed - %s", i, fd, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } } else if( *count ){ DEBUGF(DNW2)("Link_file_read: read from '%s' failed - %s", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } else { break; } } if( *count ){ *count -= len; } else { *count = readcount; } if( *count && status == 0 && ack ){ DEBUGF(DNW2)("Link_file_read: doing end marker byte read" ); i = Read_fd_len_timeout(readtimeout, *sock, str, 1 ); err = errno; if( Alarm_timed_out ){ DEBUGF(DNW2)( "Link_file_read: end marker byte read from '%s' timed out", host); status = LINK_TRANSFER_FAIL; } else if( i > 0 ){ DEBUGF(DNW2)("Link_file_read: end marker read count %d value %d", i, *str ); *ack = *str; if( *ack ){ DEBUGF(DNW2)( "Link_file_read: nonzero end marker '%d'", *ack ); status = LINK_ACK_FAIL; } } else if( i == 0 ){ DEBUGF(DNW2)("Link_file_read: EOF and no end marker" ); } else { DEBUGF(DNW2)("Link_file_read: end marker read from '%s' failed - %s", host, Errormsg(err) ); status = LINK_TRANSFER_FAIL; } } DEBUGF(DNW2)("Link_file_read: status %d", status ); return( status ); } #undef PAIR #ifndef _UNPROTO_ # define PAIR(X) { #X, X } #else # define __string(X) "X" # define PAIR(X) { __string(X), X } #endif /* PAIR(LINK_OPEN_FAIL), */ /* PAIR(LINK_TRANSFER_FAIL), */ /* PAIR(LINK_ACK_FAIL), */ /* PAIR(LINK_FILE_READ_FAIL), */ /* PAIR(LINK_LONG_LINE_FAIL), */ /* PAIR(LINK_BIND_FAIL), */ /* PAIR(LINK_PERM_FAIL), */ static struct link_err { const char *str; int value; } link_err[] = { { "NO ERROR", 0 }, {"ERROR OPENING CONNECTION",LINK_OPEN_FAIL}, {"ERROR TRANSFERRING DATA",LINK_TRANSFER_FAIL}, {"NONZERO RFC1179 ERROR CODE FROM SERVER",LINK_ACK_FAIL}, {"ERROR TRANSFERRING FILE",LINK_FILE_READ_FAIL}, {"COMMAND TOO LONG FOR RFC1179, POSSIBLE BUFFER OVERRUN ATTEMPT", LINK_LONG_LINE_FAIL}, {"CANNOT BIND TO PORT - POSSIBLE DENIAL OF SERVICE ATTACK", LINK_BIND_FAIL}, {"NO PERMISSIONS TO MANANGE SOCKET- MAY NEED SUID INSTALLATION", LINK_BIND_FAIL}, {0,0} }; const char *Link_err_str (int n) { int i; static char buf[40]; const char *s = 0; /* DEBUG1("Link_err_str: %d\n", n ); */ for( i = 0; link_err[i].str && link_err[i].value != n; ++i ){ /* DEBUG1("Link_err_str: %d = '%s'\n", link_err[i].value, link_err[i].str ); */ } /* DEBUG1("Link_err_str: %d = '%s'\n", link_err[i].value, link_err[i].str ); */ s = link_err[i].str; if( s == 0 ){ s = buf; (void) plp_snprintf(buf, sizeof(buf), "link error %d", n); } return(s); } static struct link_err ack_err[] = { PAIR(ACK_SUCCESS), PAIR(ACK_STOP_Q), PAIR(ACK_RETRY), PAIR(ACK_FAIL), {0,0} }; const char *Ack_err_str (int n) { int i; static char buf[40]; const char *s = 0; for( i = 0; ack_err[i].str && ack_err[i].value != n; ++i ); s = ack_err[i].str; if( s == 0 ){ s = buf; (void) plp_snprintf(buf, sizeof(buf), "ack error %d", n); } return(s); } int AF_Protocol(void) { /* we now know if we are using IPV4 or IPV6 from configuration */ int af_protocol = AF_INET; #if defined(IPV6) if( IPV6Protocol_DYN ){ af_protocol = AF_INET6; # if defined(HAVE_RESOLV_H) && defined(RES_USE_INET6) && defined(HAVE_RES) _res.options |= RES_USE_INET6; # endif } #endif DEBUG4("AF_Protocol: af_protocol %d, AF_INET %d", af_protocol, AF_INET ); return( af_protocol ); } #if !defined(HAVE_INET_PTON) /*************************************************************************** * inet_pton( int family, const char *strptr, void *addrptr * p means presentation, i.e. - ASCII C string * n means numeric, i.e. - network byte ordered address * family = AF_Protocol or AF_Protocol6 * strptr = string to convert * addrprt = destination ***************************************************************************/ int inet_pton( int family, const char *strptr, void *addr ) { if( family != AF_INET ){ fatal(LOG_ERR, "inet_pton: bad family '%d'", family ); } #if defined(HAVE_INET_ATON) return( inet_aton( strptr, addr ) ); #else #if !defined(INADDR_NONE) #define INADDR_NONE 0xffffffff #endif if( inet_addr( strptr ) != INADDR_NONE ){ ((struct in_addr *)addr)->s_addr = inet_addr(strptr); return(1); } return(0); #endif } #endif #if !defined(HAVE_INET_NTOP) /*************************************************************************** * inet_ntop( int family, const void *addr, * const char *strptr, int len ) * p means presentation, i.e. - ASCII C string * n means numeric, i.e. - network byte ordered address * family = AF_Protocol or AF_Protocol6 * addr = binary to convert * strptr = string where to place * len = length ***************************************************************************/ const char *inet_ntop( int family, const void *addr, char *str, size_t len ) { char *s; if( family != AF_INET ){ fatal(LOG_ERR, "inet_ntop: bad family '%d'", family ); } s = inet_ntoa(((struct in_addr *)addr)[0]); mystrncpy( str, s, len ); return(str); } #endif /*************************************************************************** * inet_ntop_sockaddr( struct sockaddr *addr, * const char *strptr, int len ) * get the address type and format it correctly * p means presentation, i.e. - ASCII C string * n means numeric, i.e. - network byte ordered address * family = AF_Protocol or AF_Protocol6 * addr = binary to convert * strptr = string where to place * len = length ***************************************************************************/ const char *inet_ntop_sockaddr( struct sockaddr *addr, char *str, int len ) { void *a = 0; /* we get the printable from the socket address */ if( addr->sa_family == AF_INET ){ a = &((struct sockaddr_in *)addr)->sin_addr; #if defined(IN6_ADDR) } else if( addr->sa_family == AF_INET6 ){ a = &((struct sockaddr_in6 *)addr)->sin6_addr; #endif } else if( addr->sa_family == 0 #if defined(AF_LOCAL) || addr->sa_family == AF_LOCAL #endif #if defined(AF_UNIX) || addr->sa_family == AF_UNIX #endif ){ plp_snprintf(str, len, "%s", Unix_socket_path_DYN ); return( str ); } else { fatal(LOG_ERR, "inet_ntop_sockaddr: bad family '%d'", addr->sa_family ); } return( inet_ntop( addr->sa_family, a, str, len ) ); } lprng-3.8.B/src/common/linelist.c0000644000131400013140000026765111531672131013666 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errorcodes.h" #include "globmatch.h" #include "gethostinfo.h" #include "child.h" #include "fileopen.h" #include "getqueue.h" #include "getprinter.h" #include "linelist.h" /* Forward declartions: */ static int Find_last_key( struct line_list *l, const char *key, const char *sep, int *m ); static int Find_last_casekey( struct line_list *l, const char *key, const char *sep, int *m ); static int Find_first_casekey( struct line_list *l, const char *key, const char *sep, int *m ); static const char *Fix_val( const char *s ); static void Read_file_and_split( struct line_list *list, char *file, const char *linesep, int sort, const char *keysep, int uniq, int trim, int nocomment ); static void Find_pc_info( char *name, struct line_list *info, struct line_list *aliases, struct line_list *names, struct line_list *order, struct line_list *input, int depth, int wildcard ); static void Config_value_conversion( struct keywords *key, const char *s ); /* lowercase and uppercase (destructive) a string */ void lowercase( char *s ) { int c; if( s ){ for( ; (c = cval(s)); ++s ){ if( isupper(c) ) *s = tolower(c); } } } void uppercase( char *s ) { int c; if( s ){ for( ; (c = cval(s)); ++s ){ if( islower(c) ) *s = toupper(c); } } } /* * Trunc str - remove trailing white space (destructive) */ char *trunc_str( char *s) { char *t; if(s && *s){ for( t=s+safestrlen(s); t > s && isspace(cval(t-1)); --t ); *t = 0; } return( s ); } static int Lastchar( char *s ) { int c = 0; if( s && *s ){ s += safestrlen(s)-1; c = cval(s); } return(c); } /* * Memory Allocation Routines * - same as malloc, realloc, but with error messages */ void *malloc_or_die( size_t size, const char *file, int line ) { void *p; #if defined(DMALLOC) p = dmalloc_malloc(file, line, size, DMALLOC_FUNC_MALLOC,0,0); #else p = malloc(size); #endif if( p == 0 ){ logerr_die(LOG_INFO, "malloc of %d failed, file '%s', line %d", (int)size, file, line ); } DEBUG6("malloc_or_die: size %d, addr 0x%lx, file '%s', line %d", (int)size, Cast_ptr_to_long(p), file, line ); return( p ); } void *realloc_or_die( void *p, size_t size, const char *file, int line ) { void *orig = p; if( p == 0 ){ p = malloc_or_die(size, file, line); } else { #if defined(DMALLOC) p = dmalloc_realloc(file, line, p, size, DMALLOC_FUNC_REALLOC,0); #else p = realloc(p, size); #endif } if( p == 0 ){ logerr(LOG_INFO, "realloc of 0x%lx, new size %d failed, file '%s', line %d", Cast_ptr_to_long(orig), (int)size, file, line ); abort(); } DEBUG6("realloc_or_die: size %d, orig 0x%lx, addr 0x%lx, file '%s', line %d", (int)size, Cast_ptr_to_long(orig), Cast_ptr_to_long(p), file, line ); return( p ); } /* * duplicate a string safely, generate an error message */ char *safestrdup (const char *p, const char *file, int line) { char *new = 0; if( p == 0) p = ""; new = malloc_or_die( safestrlen (p) + 1, file, line ); strcpy( new, p ); return( new ); } /* * char *safestrdup2( char *s1, char *s2, char *file, int line ) * duplicate two concatenated strings * returns: malloced string area */ char *safestrdup2( const char *s1, const char *s2, const char *file, int line ) { int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0); char *s = malloc_or_die( n, file, line ); s[0] = 0; if( s1 ) strcat(s,s1); if( s2 ) strcat(s,s2); return( s ); } /* * char *safeextend2( char *s1, char *s2, char *file, int line ) * extends a malloc'd string * returns: malloced string area */ char *safeextend2( char *s1, const char *s2, const char *file, int line ) { char *s; int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0); s = realloc_or_die( s1, n, file, line ); if( s1 == 0 ) *s = 0; if( s2 ) strcat(s,s2); return(s); } /* * char *safestrdup3( char *s1, char *s2, char *s3, char *file, int line ) * duplicate three concatenated strings * returns: malloced string area */ char *safestrdup3( const char *s1, const char *s2, const char *s3, const char *file, int line ) { int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0); char *s = malloc_or_die( n, file, line ); s[0] = 0; if( s1 ) strcat(s,s1); if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); return( s ); } /* * char *safeextend3( char *s1, char *s2, char *s3 char *file, int line ) * extends a malloc'd string * returns: malloced string area */ char *safeextend3( char *s1, const char *s2, const char *s3, const char *file, int line ) { char *s; int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0); s = realloc_or_die( s1, n, file, line ); if( s1 == 0 ) *s = 0; if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); return(s); } /* * char *safeextend4( char *s1, char *s2, char *s3, char *s4, * char *file, int line ) * extends a malloc'd string * returns: malloced string area */ char *safeextend4( char *s1, const char *s2, const char *s3, const char *s4, const char *file, int line ) { char *s; int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0) + (s4?safestrlen(s4):0); s = realloc_or_die( s1, n, file, line ); if( s1 == 0 ) *s = 0; if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); if( s4 ) strcat(s,s4); return(s); } /* * char *safestrdup4 * duplicate four concatenated strings * returns: malloced string area */ char *safestrdup4( const char *s1, const char *s2, const char *s3, const char *s4, const char *file, int line ) { int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0) + (s4?safestrlen(s4):0); char *s = malloc_or_die( n, file, line ); s[0] = 0; if( s1 ) strcat(s,s1); if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); if( s4 ) strcat(s,s4); return( s ); } /* * char *safeextend5( char *s1, char *s2, char *s3, char *s4, char *s5 * char *file, int line ) * extends a malloc'd string * returns: malloced string area */ char *safeextend5( char *s1, const char *s2, const char *s3, const char *s4, const char *s5, const char *file, int line ) { char *s; int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0) + (s4?safestrlen(s4):0) + (s5?safestrlen(s5):0); s = realloc_or_die( s1, n, file, line ); if( s1 == 0 ) *s = 0; if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); if( s4 ) strcat(s,s4); if( s5 ) strcat(s,s5); return(s); } /* * char *safestrdup5 * duplicate five concatenated strings * returns: malloced string area */ char *safestrdup5( const char *s1, const char *s2, const char *s3, const char *s4, const char *s5, const char *file, int line ) { int n = 1 + (s1?safestrlen(s1):0) + (s2?safestrlen(s2):0) + (s3?safestrlen(s3):0) + (s4?safestrlen(s4):0) + (s5?safestrlen(s5):0); char *s = malloc_or_die( n, file, line ); s[0] = 0; if( s1 ) strcat(s,s1); if( s2 ) strcat(s,s2); if( s3 ) strcat(s,s3); if( s4 ) strcat(s,s4); if( s5 ) strcat(s,s5); return( s ); } /* Line Splitting and List Management Model: we have a list of malloced and duplicated lines we never remove the lines unless we free them. we never put them in unless we malloc them */ /* * void Init_line_list( struct line_list *l ) * - inititialize a list by zeroing it */ void Init_line_list( struct line_list *l ) { memset(l, 0, sizeof(l[0])); } /* * void Free_line_list( struct line_list *l ) * - clear a list by freeing the allocated array */ void Free_line_list( struct line_list *l ) { int i; if( l == 0 ) return; if( l->list ){ for( i = 0; i < l->count; ++i ){ if( l->list[i] ) free( l->list[i]); l->list[i] = 0; } free(l->list); } memset(l,0,sizeof(l[0])); } void Free_listof_line_list( struct line_list *l ) { int i; struct line_list *lp; if( l == 0 ) return; for( i = 0; i < l->count; ++i ){ lp = (void *)l->list[i]; Free_line_list(lp); memset( lp, 0, sizeof(lp[0]) ); } Free_line_list(l); } /* * void Check_max( struct line_list *l, int incr ) * */ void Check_max( struct line_list *l, int incr ) { if( l->count+incr >= l->max ){ l->max += 100+incr; if( !(l->list = realloc_or_die( l->list, l->max*sizeof(char *), __FILE__,__LINE__)) ){ Errorcode = JFAIL; logerr(LOG_INFO, "Check_max: realloc %d failed", (int)(l->max*sizeof(char*)) ); } } } /* *char *Add_line_list( struct line_list *l, char *str, * char *sep, int sort, int uniq ) * - add a copy of str to the line list * sep - key separator, used for sorting * sort = 1 - sort the values * uniq = 1 - only one value * returns: added string */ char *Add_line_list( struct line_list *l, const char *instr, const char *sep, int sort, int uniq ) { char *s = 0; char *str; int c = 0, cmp, mid; if(DEBUGL5){ char b[48]; int n; plp_snprintf( b,sizeof(b)-8, "%s",instr ); if( (n = safestrlen(b)) > (int)sizeof(b)-10 ) strcpy( b+n,"..." ); LOGDEBUG("Add_line_list: '%s', sep '%s', sort %d, uniq %d", b, sep, sort, uniq ); } Check_max(l, 2); str = safestrdup( instr,__FILE__,__LINE__); if( sort == 0 ){ l->list[l->count++] = str; } else { s = 0; if( sep && (s = safestrpbrk( str, sep )) ){ c = *s; *s = 0; } /* find everything <= the mid point */ /* cmp = key <> list[mid] */ cmp = Find_last_key( l, str, sep, &mid ); if( s ) *s = c; /* str < list[mid+1] */ if( cmp == 0 && uniq ){ /* we replace */ free( l->list[mid] ); l->list[mid] = str; } else if( cmp >= 0 ){ /* we need to insert after mid */ ++l->count; memmove( l->list+mid+2, l->list+mid+1, sizeof( char * ) * (l->count - mid - 1)); l->list[mid+1] = str; } else if( cmp < 0 ) { /* we need to insert before mid */ ++l->count; memmove( l->list+mid+1, l->list+mid, sizeof( char * ) * (l->count - mid)); l->list[mid] = str; } } if(DEBUGL5)Dump_line_list("Add_line_list: result", l); return( str ); } /* *void Add_casekey_line_list( struct line_list *l, char *str, * char *sep ) * - add a copy of str to the line list, using case sensitive keys * sep - key separator, used for sorting * sort = 1 - sort the values * uniq = 1 - only one value */ static void Add_casekey_line_list( struct line_list *l, char *str, const char *sep) { char *s = 0; int c = 0, cmp, mid; if(DEBUGL5){ char b[40]; int n; plp_snprintf( b,sizeof(b)-8, "%s",str ); if( (n = safestrlen(b)) > (int)sizeof(b)-10 ) strcpy( b+n,"..." ); LOGDEBUG("Add_casekey_line_list: '%s', sep '%s', sort 1, uniq 1", b, sep ); } Check_max(l, 2); str = safestrdup( str,__FILE__,__LINE__); s = 0; if( sep && (s = safestrpbrk( str, sep )) ){ c = *s; *s = 0; } /* find everything <= the mid point */ /* cmp = key <> list[mid] */ cmp = Find_last_casekey( l, str, sep, &mid ); if( s ) *s = c; /* str < list[mid+1] */ if( cmp == 0 ){ /* we replace */ free( l->list[mid] ); l->list[mid] = str; } else if( cmp >= 0 ){ /* we need to insert after mid */ ++l->count; memmove( l->list+mid+2, l->list+mid+1, sizeof( char * ) * (l->count - mid - 1)); l->list[mid+1] = str; } else if( cmp < 0 ) { /* we need to insert before mid */ ++l->count; memmove( l->list+mid+1, l->list+mid, sizeof( char * ) * (l->count - mid)); l->list[mid] = str; } /* if(DEBUGL4)Dump_line_list("Add_casekey_line_list: result", l); */ } void Merge_line_list( struct line_list *dest, struct line_list *src, const char *sep, int sort, int uniq ) { int i; for( i = 0; i < src->count; ++i ){ Add_line_list( dest, src->list[i], sep, sort, uniq ); } } void Merge_listof_line_list( struct line_list *dest, struct line_list *src) { struct line_list *sp, *dp; int i; for( i = 0; i < src->count; ++i ){ if( (sp = (void *)src->list[i]) ){ Check_max( dest, 1 ); dp = malloc_or_die(sizeof(dp[0]),__FILE__,__LINE__); memset(dp,0,sizeof(dp[0])); Merge_line_list( dp, sp, 0, 0, 0); dest->list[dest->count++] = (void *)dp; } } } /* * Split( struct line_list *l, char *str, int sort, char *keysep, * int uniq, int trim, int nocomments, char *escape ) * Split the str up into strings, as delimted by sep. * put duplicates of the original into the line_list l. * If sort != 0, then sort them using keysep to separate sort key from value * if uniq != then replace rather than add entries * if trim != 0 then remove leading and trailing whitespace and * if trim is a printable character any characters at start == trim * if nocomments != 0, then remove comments as well * if escape != 0, then allow the characters in the string to be escaped * i.e. - escape = ":" then \: would be replace by : * */ void Split( struct line_list *l, const char *str, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, const char *escape ) { const char *end = 0, *t; char *buffer = 0; int len, blen = 0; if(DEBUGL5){ char b[40]; int n; plp_snprintf( b,sizeof(b)-8, "%s",str ); if( (n = safestrlen(b)) > (int)sizeof(b)-10 ) strcpy( b+n,"..." ); LOGDEBUG("Split: str 0x%lx '%s', sep '%s', escape '%s', sort %d, keysep '%s', uniq %d, trim %d", Cast_ptr_to_long(str), b, sep, escape, sort, keysep, uniq, trim ); } for( ; str && *str; str = end ){ end = 0; t = str; if( !ISNULL(sep) ) while( (t = safestrpbrk( t, sep )) ){ if( escape && t != str && cval(t-1) == '\\' && strchr( escape, cval(t) ) ){ ++t; DEBUG5("Split: escape '%s'", t ); continue; } end = t+1; break; } if( !end ){ t = str + safestrlen(str); } DEBUG5("Split: str 0x%lx, ('%c%c...') end 0x%lx, t 0x%lx", Cast_ptr_to_long(str), str[0], str[1], Cast_ptr_to_long(end), Cast_ptr_to_long(t)); if( trim ){ while( isspace(cval(str)) ) ++str; /* you can also remove leading characters */ if( cval(str) == trim && isprint(trim) ) ++str; for( ; t > str && isspace(cval(t-1)); --t ); } len = t - str; DEBUG5("Split: after trim len %d, str 0x%lx, end 0x%lx, t 0x%lx", len, Cast_ptr_to_long(str), Cast_ptr_to_long(end), Cast_ptr_to_long(t)); if( len < 0 ) continue; if( trim && len == 0 ) continue; if( nocomments && (cval(str) == '#') ) continue; if( blen <= len ){ blen = 2*len; buffer = realloc_or_die(buffer,blen+1,__FILE__,__LINE__); } memmove(buffer,str,len); buffer[len] = 0; Add_line_list( l, buffer, keysep, sort, uniq ); } if( buffer ) free(buffer); } char *Join_line_list( struct line_list *l, const char *sep ) { char *s, *t, *str = 0; int len = 0, i, n = 0; if( sep ) n = safestrlen(sep); for( i = 0; i < l->count; ++i ){ s = l->list[i]; if( s && *s ) len += safestrlen(s) + n; } if( len ){ str = malloc_or_die(len+1,__FILE__,__LINE__); t = str; for( i = 0; i < l->count; ++i ){ s = l->list[i]; if( s && *s ){ strcpy( t, s ); t += safestrlen(t); if( n ){ strcpy(t,sep); t += n; } } } *t = 0; } return( str ); } char *Join_line_list_with_sep( struct line_list *l, const char *sep ) { char *s = Join_line_list( l, sep ); int len = 0; if( sep ) len = safestrlen(sep); if( s ){ *(s+safestrlen(s)-len) = 0;; } return( s ); } void Dump_line_list( const char *title, struct line_list *l ) { int i; LOGDEBUG("Dump_line_list: %s - 0x%lx, count %d, max %d, list 0x%lx", title, Cast_ptr_to_long(l), l?l->count:0, l?l->max:0, l?Cast_ptr_to_long(l->list):(long)0 ); if(l)for( i = 0; i < l->count; ++i ){ LOGDEBUG( " [%2d] 0x%lx ='%s'", i, Cast_ptr_to_long(l->list[i]), l->list[i] ); } } void Dump_line_list_sub( const char *title, struct line_list *l ) { int i; LOGDEBUG(" %s - 0x%lx, count %d, max %d, list 0x%lx", title, Cast_ptr_to_long(l), l?l->count:0, l?l->max:0, l?Cast_ptr_to_long(l->list):(long)0 ); if(l)for( i = 0; i < l->count; ++i ){ LOGDEBUG( " [%2d] 0x%lx ='%s'", i, Cast_ptr_to_long(l->list[i]), l->list[i] ); } } /* * int Find_first_key( struct line_list *l, char *key, char *sep, int *mid ) * int Find_last_key( struct line_list *l, char *key, char *sep, int *mid ) * Search the list for the last corresponding key value * The list has lines of the form: * key [separator] value * returns: * *at = index of last tested value * return value: 0 if found; * <0 if list[*at] < key * >0 if list[*at] > key */ static int Find_last_key( struct line_list *l, const char *key, const char *sep, int *m ) { int c=0, cmp=-1, cmpl = 0, bot, top, mid; char *s, *t; mid = bot = 0; top = l->count-1; DEBUG5("Find_last_key: count %d, key '%s'", l->count, key ); while( cmp && bot <= top ){ mid = (top+bot)/2; s = l->list[mid]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmp = safestrcasecmp(key,s); if( t ) *t = c; if( cmp > 0 ){ bot = mid+1; } else if( cmp < 0 ){ top = mid -1; } else while( mid+1 < l->count ){ s = l->list[mid+1]; DEBUG5("Find_last_key: existing entry, mid %d, '%s'", mid, l->list[mid] ); t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmpl = safestrcasecmp(s,key); if( t ) *t = c; if( cmpl ) break; ++mid; } DEBUG5("Find_last_key: cmp %d, top %d, mid %d, bot %d", cmp, top, mid, bot); } if( m ) *m = mid; DEBUG5("Find_last_key: key '%s', cmp %d, mid %d", key, cmp, mid ); return( cmp ); } /* * int Find_first_casekey( struct line_list *l, char *key, char *sep, int *mid ) * int Find_last_casekey( struct line_list *l, char *key, char *sep, int *mid ) * Search the list for the last corresponding key value using case sensitive keys * The list has lines of the form: * key [separator] value * returns: * *at = index of last tested value * return value: 0 if found; * <0 if list[*at] < key * >0 if list[*at] > key */ static int Find_last_casekey( struct line_list *l, const char *key, const char *sep, int *m ) { int c=0, cmp=-1, cmpl = 0, bot, top, mid; char *s, *t; mid = bot = 0; top = l->count-1; DEBUG5("Find_last_casekey: count %d, key '%s'", l->count, key ); while( cmp && bot <= top ){ mid = (top+bot)/2; s = l->list[mid]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmp = safestrcmp(key,s); if( t ) *t = c; if( cmp > 0 ){ bot = mid+1; } else if( cmp < 0 ){ top = mid -1; } else while( mid+1 < l->count ){ s = l->list[mid+1]; DEBUG5("Find_last_key: existing entry, mid %d, '%s'", mid, l->list[mid] ); t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmpl = safestrcmp(s,key); if( t ) *t = c; if( cmpl ) break; ++mid; } DEBUG5("Find_last_casekey: cmp %d, top %d, mid %d, bot %d", cmp, top, mid, bot); } if( m ) *m = mid; DEBUG5("Find_last_casekey: key '%s', cmp %d, mid %d", key, cmp, mid ); return( cmp ); } int Find_first_key( struct line_list *l, const char *key, const char *sep, int *m ) { int c=0, cmp=-1, cmpl = 0, bot, top, mid; char *s, *t; mid = bot = 0; top = l->count-1; DEBUG5("Find_first_key: count %d, key '%s', sep '%s'", l->count, key, sep ); while( cmp && bot <= top ){ mid = (top+bot)/2; s = l->list[mid]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmp = safestrcasecmp(key,s); if( t ) *t = c; if( cmp > 0 ){ bot = mid+1; } else if( cmp < 0 ){ top = mid -1; } else while( mid > 0 ){ s = l->list[mid-1]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmpl = safestrcasecmp(s,key); if( t ) *t = c; if( cmpl ) break; --mid; } DEBUG5("Find_first_key: cmp %d, top %d, mid %d, bot %d", cmp, top, mid, bot); } if( m ) *m = mid; DEBUG5("Find_first_key: cmp %d, mid %d, key '%s', count %d", cmp, mid, key, l->count ); return( cmp ); } static int Find_first_casekey( struct line_list *l, const char *key, const char *sep, int *m ) { int c=0, cmp=-1, cmpl = 0, bot, top, mid; char *s, *t; mid = bot = 0; top = l->count-1; DEBUG5("Find_first_casekey: count %d, key '%s', sep '%s'", l->count, key, sep ); while( cmp && bot <= top ){ mid = (top+bot)/2; s = l->list[mid]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmp = safestrcmp(key,s); if( t ) *t = c; if( cmp > 0 ){ bot = mid+1; } else if( cmp < 0 ){ top = mid -1; } else while( mid > 0 ){ s = l->list[mid-1]; t = 0; if( sep && (t = safestrpbrk(s, sep )) ) { c = *t; *t = 0; } cmpl = safestrcmp(s,key); if( t ) *t = c; if( cmpl ) break; --mid; } DEBUG5("Find_first_casekey: cmp %d, top %d, mid %d, bot %d", cmp, top, mid, bot); } if( m ) *m = mid; DEBUG5("Find_first_casekey: cmp %d, mid %d, key '%s', count %d", cmp, mid, key, l->count ); return( cmp ); } /* * char *Find_value( struct line_list *l, char *key ) * Search the list for a corresponding key value * value * key "1" * key@ "0" * key#v v * key=v v * key v v * If key does not exist, we return "0" */ static const char *Find_value( struct line_list *l, const char *key ) { const char *s = "0"; int mid, cmp = -1; const char *sep = Option_value_sep; DEBUG5("Find_value: key '%s', sep '%s'", key, sep ); if( l ) cmp = Find_first_key( l, key, sep, &mid ); DEBUG5("Find_value: key '%s', cmp %d, mid %d", key, cmp, mid ); if( cmp==0 ){ s = Fix_val( safestrpbrk(l->list[mid], sep ) ); } DEBUG4( "Find_value: key '%s', value '%s'", key, s ); return(s); } /* * char *Find_exists_value( struct line_list *l, char *key, char *sep ) * Search the list for a corresponding key value * value * key "1" * key@ "0" * key#v v * key=v v * If key does not exist we return 0 (null) */ const char *Find_exists_value( struct line_list *l, const char *key, const char *sep ) { const char *s = 0; int mid, cmp = -1; if( l ) cmp = Find_first_key( l, key, sep, &mid ); if( cmp==0 ){ if( sep ){ s = Fix_val( safestrpbrk(l->list[mid], sep ) ); } else { s = l->list[mid]; } } DEBUG4( "Find_exists_value: key '%s', cmp %d, value '%s'", key, cmp, s ); return(s); } /* * char *Find_str_value( struct line_list *l, char *key ) * Search the list for a corresponding key value * value * key 0 * key@ 0 * key#v 0 * key=v v */ char *Find_str_value( struct line_list *l, const char *key ) { char *s = 0; int mid, cmp = -1; const char *sep = Option_value_sep; if( l ) cmp = Find_first_key( l, key, sep, &mid ); if( cmp==0 ){ /* * value: NULL, "", "@", "=xx", "#xx". * returns: "0", "1","0", "xx", "xx" */ s = safestrpbrk(l->list[mid], sep ); if( s && *s == '=' ){ ++s; } else { s = 0; } } DEBUG4( "Find_str_value: key '%s', value '%s'", key, s ); return(s); } /* * char *Find_casekey_str_value( struct line_list *l, char *key, char *sep ) * Search the list for a corresponding key value using case sensitive keys * value * key 0 * key@ 0 * key#v 0 * key=v v */ char *Find_casekey_str_value( struct line_list *l, const char *key, const char *sep ) { char *s = 0; int mid, cmp = -1; if( l ) cmp = Find_first_casekey( l, key, sep, &mid ); if( cmp==0 ){ /* * value: NULL, "", "@", "=xx", "#xx". * returns: "0", "1","0", "xx", "xx" */ if( sep ){ s = safestrpbrk(l->list[mid], sep ); if( s && *s == '=' ){ ++s; } else { s = 0; } } else { s = l->list[mid]; } } DEBUG4( "Find_casekey_str_value: key '%s', value '%s'", key, s ); return(s); } /* * Set_str_value( struct line_list *l, char *key, char *value ) * set a string value in an ordered, sorted list */ void Set_str_value( struct line_list *l, const char *key, const char *value ) { char *s = 0; int mid; if( key == 0 ) return; if(DEBUGL6){ char buffer[16]; plp_snprintf(buffer,sizeof(buffer)-5, "%s",value); buffer[12] = 0; if( value && safestrlen(value) > 12 ) strcat(buffer,"..."); LOGDEBUG("Set_str_value: '%s'= 0x%lx '%s'", key, Cast_ptr_to_long(value), buffer); } if( value && *value ){ s = safestrdup3(key,"=",value,__FILE__,__LINE__); Add_line_list(l,s,Hash_value_sep,1,1); if(s) free(s); s = 0; } else if( !Find_first_key(l, key, Hash_value_sep, &mid ) ){ Remove_line_list(l,mid); } } /* * Set_casekey_str_value( struct line_list *l, char *key, char *value ) * set an string value in an ordered, sorted list, with case sensitive keys */ void Set_casekey_str_value( struct line_list *l, const char *key, const char *value ) { char *s = 0; int mid; if( key == 0 ) return; if(DEBUGL6){ char buffer[16]; plp_snprintf(buffer,sizeof(buffer)-5, "%s",value); buffer[12] = 0; if( value && safestrlen(value) > 12 ) strcat(buffer,"..."); LOGDEBUG("Set_str_value: '%s'= 0x%lx '%s'", key, Cast_ptr_to_long(value), buffer); } if( value && *value ){ s = safestrdup3(key,"=",value,__FILE__,__LINE__); Add_casekey_line_list(l,s,Hash_value_sep); if(s) free(s); s = 0; } else if( !Find_first_casekey(l, key, Hash_value_sep, &mid ) ){ Remove_line_list(l,mid); } } /* * Set_flag_value( struct line_list *l, char *key, int value ) * set a flag value in an ordered, sorted list */ void Set_flag_value( struct line_list *l, const char *key, long value ) { char buffer[SMALLBUFFER]; if( key == 0 ) return; plp_snprintf(buffer,sizeof(buffer), "%s=0x%lx",key,value); Add_line_list(l,buffer,Hash_value_sep,1,1); } /* * Set_nz_flag_value( struct line_list *l, char *key, int value ) * set a nonzero flag value in an ordered, sorted list */ void Set_nz_flag_value( struct line_list *l, const char *key, long value ) { if( !Find_flag_value( l, key ) ){ Set_flag_value( l, key, value ); } } /* * Set_double_value( struct line_list *l, char *key, int value ) * set a double value in an ordered, sorted list */ void Set_double_value( struct line_list *l, const char *key, double value ) { char buffer[SMALLBUFFER]; if( key == 0 ) return; plp_snprintf(buffer,sizeof(buffer), "%s=%0.0f",key,value); Add_line_list(l,buffer,Hash_value_sep,1,1); } /* * Set_decimal_value( struct line_list *l, char *key, int value ) * set a decimal value in an ordered, sorted list */ void Set_decimal_value( struct line_list *l, const char *key, long value ) { char buffer[SMALLBUFFER]; if( key == 0 ) return; plp_snprintf(buffer,sizeof(buffer), "%s=%ld",key,value); Add_line_list(l,buffer,Hash_value_sep,1,1); } /* * Remove_line_list( struct line_list *l, int mid ) * Remove the indicated entry and move the other * entries up. */ void Remove_line_list( struct line_list *l, int mid ) { char *s; if( mid >= 0 && mid < l->count ){ if( (s = l->list[mid]) ){ free(s); l->list[mid] = 0; } memmove(&l->list[mid],&l->list[mid+1],(l->count-mid-1)*sizeof(char *)); --l->count; } } /* * Remove_duplicates_line_list( struct line_list *l ) * Remove duplicate entries in the list */ static void Remove_duplicates_line_list( struct line_list *l ) { char *s, *t; int i, j; for( i = 0; i < l->count; ){ if( (s = l->list[i]) ){ for( j = i+1; j < l->count; ){ if( !(t = l->list[j]) || !safestrcmp(s,t) ){ Remove_line_list( l, j ); } else { ++j; } } ++i; } else { Remove_line_list( l, i ); } } } /* * char *Find_flag_value( struct line_list *l, char *key ) * Search the list for a corresponding key value * value * key 1 * key@ 0 * key#v v if v is integer, 0 otherwise * key=v v if v is integer, 0 otherwise */ int Find_flag_value( struct line_list *l, const char *key ) { const char *s; char *e; int n = 0; if( l && (s = Find_value( l, key )) ){ e = 0; n = strtol(s,&e,0); if( !e || *e ) n = 0; } DEBUG4( "Find_flag_value: key '%s', value '%d'", key, n ); return(n); } /* * char *Find_decimal_value( struct line_list *l, char *key ) * Search the list for a corresponding key value * value * key 1 * key@ 0 * key#v v if v is decimal, 0 otherwise * key=v v if v is decimal, 0 otherwise */ int Find_decimal_value( struct line_list *l, const char *key ) { const char *s = 0; char *e; int n = 0; if( l && (s = Find_value( l, key )) ){ e = 0; n = strtol(s,&e,10); if( !e || *e ){ e = 0; n = strtol(s,&e,0); if( !e || *e ) n = 0; } } DEBUG4( "Find_decimal_value: key '%s', value '%d'", key, n ); return(n); } /* * double Find_double_value( struct line_list *l, char *key ) * Search the list for a corresponding key value * value * key 1 * key@ 0 * key#v v if v is decimal, 0 otherwise * key=v v if v is decimal, 0 otherwise */ double Find_double_value( struct line_list *l, const char *key ) { const char *s = 0; char *e; double n = 0; if( l && (s = Find_value( l, key )) ){ e = 0; n = strtod(s,&e); } DEBUG4( "Find_double_value: key '%s', value '%0.0f'", key, n ); return(n); } /* * char *Fix_val( char *s ) * passed: NULL, "", "@", "=xx", "#xx". * returns: "0", "1","0", "xx", "xx" */ static const char *Fix_val( const char *s ) { int c = 0; if( s ){ c = cval(s); ++s; while( isspace(cval(s)) ) ++s; } if( c == 0 ){ s = "1"; } else if( c == '@' ){ s = "0"; } return( s ); } /* * Find_tags( struct line_list dest, * struct line_list *list, char *tag ) * * Scan the list (ordered, of course) for the * set of entries starting with 'tag' and extract them * to list */ void Find_tags( struct line_list *dest, struct line_list *l, const char *key ) { int cmp=-1, cmpl = 0, bot, top, mid, len; char *s; if( key == 0 || *key == 0 ) return; mid = bot = 0; top = l->count-1; len = safestrlen(key); DEBUG5("Find_tags: count %d, key '%s'", l->count, key ); while( cmp && bot <= top ){ mid = (top+bot)/2; s = l->list[mid]; cmp = safestrncasecmp(key,s,len); if( cmp > 0 ){ bot = mid+1; } else if( cmp < 0 ){ top = mid -1; } else while( mid > 0 ){ DEBUG5("Find_tags: existing entry, mid %d, '%s'", mid, l->list[mid] ); s = l->list[mid-1]; cmpl = safestrncasecmp(s,key,len); if( cmpl ) break; --mid; } DEBUG5("Find_tags: cmp %d, top %d, mid %d, bot %d", cmp, top, mid, bot); } if( cmp == 0 ){ s = l->list[mid]; do{ DEBUG5("Find_tags: adding '%s'", s+len ); Add_line_list(dest,s+len,Hash_value_sep,1,1); ++mid; } while( mid < l->count && (s = l->list[mid]) && !(cmp = safestrncasecmp(key,s,len))); } } /* * Find_defaulttags( struct line_list dest, * struct keywords *var_list, char *tag ) * * Scan the variable list for default values * starting with 'tag' and extract them * to list */ void Find_default_tags( struct line_list *dest, struct keywords *var_list, const char *tag ) { int len = safestrlen(tag); const char *key, *value; if( var_list ) while( var_list->keyword ){ if( !strncmp((key = var_list->keyword), tag, len) && (value = var_list->default_value) ){ if( *value == '=' ) ++value; DEBUG5("Find_default_tags: adding '%s'='%s'", key, value); Set_str_value(dest, key+len, value ); } ++var_list; } } /* * Read_file_list( struct line_list *model, char *str * char *sep, int sort, char *keysep, int uniq, int trim, int marker, * int doinclude, int nocomment, int depth, int maxdepth ) * read the model information from these files * if marker != then add a NULL line after each file */ void Read_file_list( int required, struct line_list *model, char *str, const char *linesep, int sort, const char *keysep, int uniq, int trim, int marker, int doinclude, int nocomment, int depth, int maxdepth ) { struct line_list l; int i, start, end, c=0, n, found; char *s, *t; struct stat statb; Init_line_list(&l); DEBUG3("Read_file_list: '%s', doinclude %d, depth %d, maxdepth %d, keysep '%s'", str, doinclude, depth, maxdepth, keysep ); if( depth > maxdepth ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Read_file_list: recursion depth %d exceeds maxdepth %d for file '%s'", depth, maxdepth, str ); } Split( &l, str, File_sep, 0, 0, 0, 1, 0 ,0); start = model->count; for( i = 0; i < l.count; ++i ){ if( stat( l.list[i], &statb ) == -1 ){ if( required || depth ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Read_file_list: cannot stat required or included file '%s'", l.list[i] ); } continue; } Read_file_and_split( model, l.list[i], linesep, sort, keysep, uniq, trim, nocomment ); if( doinclude ){ /* scan through the list, looking for include lines */ for( end = model->count; start < end; ){ t = 0; s = model->list[start]; found = 0; t = 0; if( s && (t = safestrpbrk( s, Whitespace )) ){ c = *t; *t = 0; found = !safestrcasecmp( s, "include" ); *t = c; } if( found ){ DEBUG4("Read_file_list: include '%s'", t+1 ); Read_file_list( 1, model, t+1, linesep, sort, keysep, uniq, trim, marker, doinclude, nocomment, depth+1, maxdepth ); /* at this point the include lines are at * end to model->count-1 * we need to move the lines from start to end-1 * to model->count, and then move end to start */ n = end - start; Check_max( model, n ); /* copy to end */ if(DEBUGL5)Dump_line_list("Read_file_list: include before", model ); memmove( &model->list[model->count], &model->list[start], n*sizeof(char *) ); memmove( &model->list[start], &model->list[end],(model->count-start)*sizeof(char *)); if(DEBUGL4)Dump_line_list("Read_file_list: include after", model ); end = model->count; start = end - n; DEBUG4("Read_file_list: start now '%s'",model->list[start]); /* we get rid of include line */ s = model->list[start]; free(s); model->list[start] = 0; memmove( &model->list[start], &model->list[start+1], n*sizeof(char *) ); --model->count; end = model->count; } else { ++start; } } } if( marker ){ /* put null at end of list */ Check_max( model, 1 ); model->list[model->count++] = 0; } } Free_line_list(&l); if(DEBUGL5)Dump_line_list("Read_file_list: result", model); } void Read_fd_and_split( struct line_list *list, int fd, const char *linesep, int sort, const char *keysep, int uniq, int trim, int nocomment ) { int size = 0, count, len; char *sv; char buffer[LARGEBUFFER]; sv = 0; while( (count = ok_read(fd, buffer, sizeof(buffer)-1)) > 0 ){ buffer[count] = 0; len = size+count+1; sv = realloc_or_die( sv, len,__FILE__,__LINE__); memmove( sv+size, buffer, count ); size += count; sv[size] = 0; } close( fd ); DEBUG4("Read_fd_and_split: size %d", size ); Split( list, sv, linesep, sort, keysep, uniq, trim, nocomment ,0); if( sv ) free( sv ); } static void Read_file_and_split( struct line_list *list, char *file, const char *linesep, int sort, const char *keysep, int uniq, int trim, int nocomment ) { int fd; struct stat statb; DEBUG3("Read_file_and_split: '%s', trim %d, nocomment %d", file, trim, nocomment ); if( (fd = Checkread( file, &statb )) < 0 ){ logerr_die(LOG_INFO, "Read_file_and_split: cannot open '%s' - '%s'", file, Errormsg(errno) ); } Read_fd_and_split( list, fd, linesep, sort, keysep, uniq, trim, nocomment ); } /* * Printcap information */ /* * Build_pc_names( struct line_list *names, struct line_list *order, char *s ) * names = list of aliases and names * order = order that names were found * * get the primary name * if it is not in the names lists, add to order list * put the names and aliases in the names list */ static int Build_pc_names( struct line_list *names, struct line_list *order, char *str, struct host_information *hostname ) { char *s, *t; int c = 0, i, ok = 0, len, start_oh, end_oh; struct line_list l, opts, oh; Init_line_list(&l); Init_line_list(&opts); Init_line_list(&oh); DEBUG4("Build_pc_names: start '%s'", str); if( (s = safestrpbrk(str, ":")) ){ c = *s; *s = 0; Split(&opts,s+1,":",1,Option_value_sep,0,1,0,":"); } Split(&l,str,"|",0,0,0,1,0,0); if( s ) *s = c; if(DEBUGL4)Dump_line_list("Build_pc_names- names", &l); if(DEBUGL4)Dump_line_list("Build_pc_names- options", &opts); if( l.count == 0 ){ if(Warnings){ WARNMSG( "no name for printcap entry '%s'", str ); } else { logmsg(LOG_INFO, "no name for printcap entry '%s'", str ); } } else { ok = 1; if( Find_flag_value( &opts,SERVER ) && !Is_server ){ DEBUG4("Build_pc_names: not server" ); ok = 0; } else if( Find_flag_value( &opts,CLIENT ) && Is_server ){ DEBUG4("Build_pc_names: not client" ); ok = 0; } else if( !Find_first_key(&opts,"oh",Hash_value_sep,&start_oh) && !Find_last_key(&opts,"oh",Hash_value_sep,&end_oh) ){ ok = 0; DEBUG4("Build_pc_names: start_oh %d, end_oh %d", start_oh, end_oh ); for( i = start_oh; !ok && i <= end_oh; ++i ){ DEBUG4("Build_pc_names: [%d] '%s'", i, opts.list[i] ); if( (t = safestrchr( opts.list[i], '=' )) ){ Split(&oh,t+1,File_sep,0,0,0,1,0,0); ok = !Match_ipaddr_value(&oh, hostname); DEBUG4("Build_pc_names: check host '%s', ok %d", t+1, ok ); Free_line_list(&oh); } } } if( ok && (s = safestrpbrk( l.list[0], Option_value_sep)) ){ ok = 0; if(Warnings){ WARNMSG( "bad printcap name '%s', has '%c' character", l.list[0], *s ); } else { logmsg(LOG_INFO, "bad printcap name '%s', has '%c' character", l.list[0], *s ); } } if( ok ){ if(DEBUGL4)Dump_line_list("Build_pc_names: adding ", &l); if(DEBUGL4)Dump_line_list("Build_pc_names- before names", names ); if(DEBUGL4)Dump_line_list("Build_pc_names- before order", order ); if( !Find_exists_value( names, l.list[0], Hash_value_sep ) ){ Add_line_list(order,l.list[0],0,0,0); } for( i = 0; i < l.count; ++i ){ if( safestrpbrk( l.list[i], Option_value_sep ) ){ continue; } Set_str_value(names,l.list[i],l.list[0]); } len = safestrlen(str); s = str; DEBUG4("Build_pc_names: before '%s'", str ); *s = 0; for( i = 0; i < l.count; ++i ){ if( *str ) *s++ = '|'; strcpy(s,l.list[i]); s += safestrlen(s); } for( i = 0; i < opts.count; ++i ){ *s++ = ':'; strcpy(s,opts.list[i]); s += safestrlen(s); } if( safestrlen(str) > len ){ Errorcode = JABORT; fatal(LOG_ERR, "Build_pc_names: LINE GREW! fatal error"); } DEBUG4("Build_pc_names: end '%s'", str ); } } Free_line_list(&l); Free_line_list(&opts); DEBUG4("Build_pc_names: returning ok '%d'", ok ); return ok; } /* * Build_printcap_info * OUTPUT * names = list of names in the form * alias=primary * order = list of names in order * list = list of all of the printcap entries * INPUT * input = orginal list information in split line format * * run through the raw information, extrating primary name and aliases * create entries in the names and order lists */ void Build_printcap_info( struct line_list *names, struct line_list *order, struct line_list *list, struct line_list *raw, struct host_information *hostname ) { int i, c; char *t, *keyid = 0; int appendline = 0; DEBUG1("Build_printcap_info: list->count %d, raw->count %d", list->count, raw->count ); for( i = 0; i < raw->count; ++i ){ t = raw->list[i]; DEBUG4("Build_printcap_info: doing '%s'", t ); if( t ) while( isspace( cval(t) ) ) ++t; /* ignore blank lines and comments */ if( t == 0 || (c = *t) == 0 || c == '#') continue; /* append lines starting with :, | */ if( keyid && (safestrchr(Printcap_sep,c) || appendline) ){ DEBUG4("Build_printcap_info: old keyid '%s', adding '%s'", keyid, t ); keyid = safeextend3(keyid, " ", t,__FILE__,__LINE__ ); if( (appendline = (Lastchar(keyid) == '\\')) ){ keyid[safestrlen(keyid)-1] = 0; } } else { DEBUG4("Build_printcap_info: old keyid '%s', new '%s'", keyid, t ); if( keyid ){ if( Build_pc_names( names, order, keyid, hostname ) ){ Add_line_list( list, keyid, Printcap_sep, 1, 0 ); } free(keyid); keyid = 0; } keyid = safestrdup(t,__FILE__,__LINE__); if( (appendline = (Lastchar(keyid) == '\\')) ){ keyid[safestrlen(keyid)-1] = 0; } } } if( keyid ){ if( Build_pc_names( names, order, keyid, hostname ) ){ Add_line_list( list, keyid, Printcap_sep, 1, 0 ); } free(keyid); keyid = 0; } if(DEBUGL4) Dump_line_list( "Build_printcap_info- end", list ); return; } /* * char *Select_pc_info( * - returns the main name of the print queue * struct line_list *aliases = list of names and aliases * struct line_list *info = printcap infor * struct line_list *names = entry names in the input list * alias=mainname * struct line_list *input = printcap entries, starting with mainname * * Select the printcap information and put it in the info list. * Return the main name; */ char *Select_pc_info( const char *id, struct line_list *info, struct line_list *aliases, struct line_list *names, struct line_list *order, struct line_list *input, int depth, int wildcard ) { int start, end, i, c; char *s, *t, *found = 0, *allglob = 0; struct line_list l; Init_line_list(&l); DEBUG1("Select_pc_info: looking for '%s', depth %d", id, depth ); if( depth > 5 ){ Errorcode = JABORT; fatal(LOG_ERR, "Select_pc_info: printcap tc recursion depth %d", depth ); } if(DEBUGL4)Dump_line_list("Select_pc_info- names", names ); if(DEBUGL4)Dump_line_list("Select_pc_info- order", order ); if(DEBUGL4)Dump_line_list("Select_pc_info- input", input ); start = 0; end = 0; found = Find_str_value( names, id ); if( !found && PC_filters_line_list.count ){ Filterprintcap( &l, &PC_filters_line_list, id); Build_printcap_info( names, order, input, &l, &Host_IP ); Free_line_list( &l ); if(DEBUGL4)Dump_line_list("Select_pc_info- after filter aliases", aliases ); if(DEBUGL4)Dump_line_list("Select_pc_info- after filter info", info ); if(DEBUGL4)Dump_line_list("Select_pc_info- after filter names", names ); if(DEBUGL4)Dump_line_list("Select_pc_info- after filter input", input ); found = Find_str_value( names, id ); } /* do partial glob match */ c = 0; for( i = 0; !found && i < names->count; ++i ){ s = names->list[i]; if( (t = safestrpbrk(s, Hash_value_sep)) ){ c = *t; *t = 0; DEBUG1("Select_pc_info: wildcard trying '%s'", s ); if( !safestrcmp(s, id ) ){ found = t+1; } *t = c; } } if( !found && wildcard ){ c = 0; for( i = 0; !found && i < names->count; ++i ){ s = names->list[i]; if( (t = safestrpbrk(s, Hash_value_sep)) ){ c = *t; *t = 0; DEBUG1("Select_pc_info: wildcard trying '%s'", s ); if( !strcmp(s,"*") ){ if( ISNULL(allglob) ){ allglob = t+1; } } else if( !Globmatch( s, id ) ){ found = t+1; } *t = c; } } } if( !found ){ found = allglob; } if( found ){ Find_pc_info( found, info, aliases, names, order, input, depth, 0 ); } DEBUG1("Select_pc_info: returning '%s'", found ); if(DEBUGL4)Dump_line_list("Select_pc_info- returning aliases", aliases ); if(DEBUGL4)Dump_line_list("Select_pc_info- returning info", info ); return( found ); } static void Find_pc_info( char *name, struct line_list *info, struct line_list *aliases, struct line_list *names, struct line_list *order, struct line_list *input, int depth, int wildcard ) { int start, end, i, j, c, start_tc, end_tc; char *s, *t, *u; struct line_list l, pc, tc; Init_line_list(&l); Init_line_list(&pc); Init_line_list(&tc); DEBUG1("Find_pc_info: found name '%s'", name ); if( Find_first_key(input,name,Printcap_sep,&start) || Find_last_key(input,name,Printcap_sep,&end) ){ Errorcode = JABORT; fatal(LOG_ERR, "Find_pc_info: name '%s' in names and not in input list", name ); } DEBUG4("Find_pc_info: name '%s', start %d, end %d", name, start, end ); for(; start <= end; ++start ){ u = input->list[start]; DEBUG4("Find_pc_info: line [%d]='%s'", start, u ); if( u && *u ){ Add_line_list( &pc, u, 0, 0, 0 ); } } if(DEBUGL4)Dump_line_list("Find_pc_info- entry lines", &l ); for( start = 0; start < pc.count; ++ start ){ u = pc.list[start]; c = 0; if( (t = safestrpbrk(u,":")) ){ Split(&l, t+1, ":", 1, Option_value_sep, 0, 1, 0,":"); } if( aliases ){ if( t ){ c = *t; *t = 0; Split(aliases, u, Printcap_sep, 0, 0, 0, 0, 0,0); Remove_duplicates_line_list(aliases); *t = c; } else { Split(aliases, u, Printcap_sep, 0, 0, 0, 0, 0,0); Remove_duplicates_line_list(aliases); } } /* get the tc entries */ if(DEBUGL4)Dump_line_list("Find_pc_info- pc entry", &l ); if( !Find_first_key(&l,"tc",Hash_value_sep,&start_tc) && !Find_last_key(&l,"tc",Hash_value_sep,&end_tc) ){ for( ; start_tc <= end_tc; ++start_tc ){ if( (s = l.list[start_tc]) ){ lowercase(s); DEBUG4("Find_pc_info: tc '%s'", s ); if( (t = safestrchr( s, '=' )) ){ Split(&tc,t+1,File_sep,0,0,0,1,0,0); } free( l.list[start_tc] ); l.list[start_tc] = 0; } } } if(DEBUGL4)Dump_line_list("Find_pc_info- tc", &tc ); for( j = 0; j < tc.count; ++j ){ s = tc.list[j]; DEBUG4("Find_pc_info: tc entry '%s'", s ); if( !Select_pc_info( s, info, 0, names, order, input, depth+1, wildcard ) ){ fatal(LOG_ERR, "Find_pc_info: tc entry '%s' not found", s); } } Free_line_list(&tc); if(DEBUGL4)Dump_line_list("Find_pc_info - adding", &l ); for( i = 0; i < l.count; ++i ){ if( (t = l.list[i]) ){ Add_line_list( info, t, Option_value_sep, 1, 1 ); } } Free_line_list(&l); } Free_line_list(&pc); } /* * variable lists and initialization */ /*************************************************************************** * Clear_var_list( struct pc_var_list *vars ); * Set the printcap variable value to 0 or null; ***************************************************************************/ void Clear_var_list( struct keywords *v, int setv ) { char *s; void *p; struct keywords *vars; for( vars = v; vars->keyword; ++vars ){ if( !(p = vars->variable) ) continue; switch( vars->type ){ case STRING_K: s = ((char **)p)[0]; if(s)free(s); ((char **)p)[0] = 0; break; case INTEGER_K: case FLAG_K: ((int *)p)[0] = 0; break; default: break; } if( setv && vars->default_value ){ Config_value_conversion( vars, vars->default_value ); } } if(DEBUGL5)Dump_parms("Clear_var_list: after",v ); } /*************************************************************************** * Set_var_list( struct keywords *vars, struct line_list *values ); * for each name in keywords * find entry in values ***************************************************************************/ void Set_var_list( struct keywords *keys, struct line_list *values ) { struct keywords *vars; const char *s; for( vars = keys; vars->keyword; ++vars ){ if( (s = Find_exists_value( values, vars->keyword, Option_value_sep )) ){ Config_value_conversion( vars, s ); } } } /*************************************************************************** * int Check_str_keyword( char *name, int *value ) * - check a string for a simple keyword name ***************************************************************************/ #define FIXV(S,V) { S, N_(S), INTEGER_K, (void *)0, V, 0,0 } static struct keywords simple_words[] = { FIXV( "all", 1 ), FIXV( "yes", 1 ), FIXV( "allow", 1 ), FIXV( "true", 1 ), FIXV( "no", 0 ), FIXV( "deny", 0 ), FIXV( "false", 0 ), FIXV( "none", 0 ), {0,0,0,0,0,0,0} }; static int Check_str_keyword( const char *name, int *value ) { struct keywords *keys; for( keys = simple_words; keys->keyword; ++keys ){ if( !safestrcasecmp( name, keys->keyword ) ){ *value = keys->maxval; return( 1 ); } } return( 0 ); } /*************************************************************************** * void Config_value_conversion( struct keyword *key, char *value ) * set the value of the variable as required ***************************************************************************/ static void Config_value_conversion( struct keywords *key, const char *s ) { int i = 0, c = 0, value = 0; char *end; /* end of conversion */ void *p; DEBUG5("Config_value_conversion: '%s'='%s'", key->keyword, s ); if( !(p = key->variable) ) return; while(s && isspace(cval(s)) ) ++s; /* * we have null str "", "@", "#val", or "=val" * FLAG 1 0 val!=0 val!=0 * INT 1 0 val val */ switch( key->type ){ case FLAG_K: case INTEGER_K: DEBUG5("Config_value_conversion: int '%s'", s ); i = 1; if( s && (c=cval(s)) ){ if( c == '@' ){ i = 0; } else { /* get rid of leading junk */ while( safestrchr(Option_value_sep,c) ){ ++s; c = cval(s); } if( Check_str_keyword( s, &value ) ){ i = value; } else { end = 0; i = strtol( s, &end, 0 ); if( end == 0 ){ i = 1; } } } } ((int *)p)[0] = i; DEBUG5("Config_value_conversion: setting '%d'", i ); break; case STRING_K: end = ((char **)p)[0]; DEBUG5("Config_value_conversion: current value '%s'", end ); if( end ) free( end ); ((char **)p)[0] = 0; while(s && (c=cval(s)) && safestrchr(Option_value_sep,c) ) ++s; end = 0; if( s && *s ){ end = safestrdup(s,__FILE__,__LINE__); trunc_str(end); } ((char **)p)[0] = end; DEBUG5("Config_value_conversion: setting '%s'", end ); break; default: break; } } static struct keywords Keyletter[] = { { "P", 0, STRING_K, &Printer_DYN, 0,0,0 }, { "Q", 0, STRING_K, &Queue_name_DYN, 0,0,0 }, { "h", 0, STRING_K, &ShortHost_FQDN, 0,0,0 }, { "H", 0, STRING_K, &FQDNHost_FQDN, 0,0,0 }, { "a", 0, STRING_K, &Architecture_DYN, 0,0,0 }, { "R", 0, STRING_K, &RemotePrinter_DYN, 0,0,0 }, { "M", 0, STRING_K, &RemoteHost_DYN, 0,0,0 }, { "D", 0, STRING_K, &Current_date_DYN, 0,0,0 }, { 0,0,0,0,0,0,0 } }; void Expand_percent( char **var ) { struct keywords *key; char *str, *s, *t, *u, **v = var; int c, len; if( v == 0 || (str = *v) == 0 || !safestrpbrk(str,"%") ){ return; } DEBUG4("Expand_percent: starting '%s'", str ); if( Current_date_DYN == 0 ){ Set_DYN(&Current_date_DYN, Time_str(0,0) ); if( (s = safestrrchr(Current_date_DYN,'-')) ){ *s = 0; } } s = str; while( (s = safestrpbrk(s,"%")) ){ t = 0; if( (c = cval(s+1)) && isalpha( c ) ){ for( key = Keyletter; t == 0 && key->keyword; ++key ){ if( (c == key->keyword[0]) ){ t = *(char **)key->variable; break; } } } if( t ){ *s = 0; s += 2; len = safestrlen(str) + safestrlen(t); u = str; str = safestrdup3(str,t,s,__FILE__,__LINE__); if(u) free(u); u = 0; s = str+len; } else { ++s; } } *v = str; DEBUG4("Expand_percent: ending '%s'", str ); } /*************************************************************************** * Expand_vars: * expand the values of a selected list of strings * These should be from _DYN ***************************************************************************/ void Expand_vars( void ) { void *p; struct keywords *var; /* check to see if you need to expand */ for( var = Pc_var_list; var->keyword; ++var ){ if( var->type == STRING_K && (p = var->variable) ){ Expand_percent(p); } } } /*************************************************************************** * Expand_hash_values: * expand the values of a hash ***************************************************************************/ void Expand_hash_values( struct line_list *hash ) { char *u, *s; int i; /* check to see if you need to expand */ for( i = 0; i < hash->count; ++i ){ s = hash->list[i]; if( safestrchr( s, '%' ) ){ u = safestrdup(s,__FILE__,__LINE__); Expand_percent( &u ); if( s ) free(s); s = 0; hash->list[i] = u; } } } /* * Set a _DYN variable */ char *Set_DYN( char **v, const char *s ) { char *t = *v; *v = 0; if( s && *s ) *v = safestrdup(s,__FILE__,__LINE__); if( t ) free(t); return( *v ); } /* * Clear the total configuration information * - we simply remove all dynmically allocated values */ void Clear_config( void ) { struct line_list **l; DEBUGF(DDB1)("Clear_config: freeing everything"); Remove_tempfiles(); Clear_tempfile_list(); Clear_var_list( Pc_var_list, 1 ); Clear_var_list( DYN_var_list, 1 ); for( l = Allocs; *l; ++l ) Free_line_list(*l); } /*************************************************************************** * void Get_config( char *names ) * gets the configuration information from a list of files ***************************************************************************/ void Get_config( int required, char *path ) { int i; DEBUG1("Get_config: required '%d', '%s'", required, path ); /* void Read_file_list( int required, struct line_list *model, char *str, * const char *linesep, int sort, const char *keysep, int uniq, int trim, * int marker, int doinclude, int nocomment, int depth, int maxdepth ) */ Read_file_list( /*required*/required, /*model*/ &Config_line_list,/*str*/ path, /*linesep*/Line_ends, /*sort*/1, /*keysep*/Option_value_sep,/*uniq*/1, /*trim*/':',/*marker*/0,/*doinclude*/1,/*nocomment*/1, /*depth*/0,/*maxdepth*/4 ); if(DEBUGL4)Dump_line_list("Get_config - before", &Config_line_list ); /* * fix up the information by removing blanks between the key and values */ for( i = 0; i < Config_line_list.count; ++i ){ char *s = Config_line_list.list[i]; char *t = safestrpbrk( s, Option_value_sep ); int c; if( t && (c = cval(t)) && isspace(c) ){ char *e = t+1; while( isspace(cval(e)) ) ++e; if( e != t+1 ){ memmove(t+1,e,strlen(e)+1); } if( isspace(c) ) *t = '='; } } if(DEBUGL3)Dump_line_list("Get_config - after", &Config_line_list ); Set_var_list( Pc_var_list, &Config_line_list); Get_local_host(); Expand_vars(); } /*************************************************************************** * void Reset_config( char *names ) * Resets the configuration and printcap information ***************************************************************************/ void Reset_config( void ) { DEBUG1("Reset_config: starting"); Clear_var_list( Pc_var_list, 1 ); Free_line_list( &PC_entry_line_list ); Free_line_list( &PC_alias_line_list ); Set_var_list( Pc_var_list, &Config_line_list); Expand_vars(); } void close_on_exec( int fd ) { for( ;fd <= Max_fd+10; fd++ ){ (void) close( fd); } } static void Setup_env_for_process( struct line_list *env, struct job *job ) { struct line_list env_names; struct passwd *pw; char *s, *t, *u, *name; int i; Init_line_list(&env_names); if( (pw = getpwuid( getuid())) == 0 ){ logerr_die(LOG_INFO, "setup_envp: getpwuid(%ld) failed", (long)getuid()); } Set_str_value(env,"PRINTER",Printer_DYN); Set_str_value(env,"USER",pw->pw_name); Set_str_value(env,"LOGNAME",pw->pw_name); Set_str_value(env,"HOME",pw->pw_dir); Set_str_value(env,"LOGDIR",pw->pw_dir); Set_str_value(env,"PATH",Filter_path_DYN); Set_str_value(env,"LD_LIBRARY_PATH",Filter_ld_path_DYN); Set_str_value(env,"SHELL",Shell_DYN); Set_str_value(env,"IFS"," \t"); s = getenv( "TZ" ); Set_str_value(env,"TZ",s); Set_str_value(env,"SPOOL_DIR", Spool_dir_DYN ); if( PC_entry_line_list.count ){ t = Join_line_list_with_sep(&PC_alias_line_list,"|"); s = Join_line_list_with_sep(&PC_entry_line_list,"\n :"); u = safestrdup4(t,(s?"\n :":0),s,"\n",__FILE__,__LINE__); Expand_percent( &u ); Set_str_value(env, "PRINTCAP_ENTRY",u); if(s) free(s); s = 0; if(t) free(t); t = 0; if(u) free(u); u = 0; } if( job ){ if( (s = Make_job_ticket_image( job )) ){ Set_str_value(env, "HF", s ); free(s); s = 0; } if( (s = Find_str_value(&job->info,CF_OUT_IMAGE)) ){ Set_str_value(env, "CONTROL", s ); } if( (s = Find_str_value(&job->info,DATAFILES)) ){ Set_str_value(env, "DATAFILES", s ); } } if( Pass_env_DYN ){ Free_line_list(&env_names); Split(&env_names,Pass_env_DYN,File_sep,1,Hash_value_sep,1,1,0,0); for( i = 0; i < env_names.count; ++i ){ name = env_names.list[i]; if( (s = getenv( name )) ){ Set_str_value( env, name, s); } } } Free_line_list(&env_names); Check_max(env,1); env->list[env->count] = 0; if(DEBUGL1)Dump_line_list("Setup_env_for_process", env ); } /*************************************************************************** * void Getprintcap_pathlist( char *path ) * Read printcap information from a (semi)colon or comma separated set of files * or filter specifications * 1. break path up into set of path names * 2. read the printcap information into memory * 3. parse the printcap informormation ***************************************************************************/ void Getprintcap_pathlist( int required, struct line_list *raw, struct line_list *filters, char *path ) { struct line_list l; int i, c; Init_line_list(&l); DEBUG2("Getprintcap_pathlist: processing '%s'", path ); Split(&l,path,Strict_file_sep,0,0,0,1,0,0); for( i = 0; i < l.count; ++i ){ path = l.list[i]; c = path[0]; switch( c ){ case '|': DEBUG2("Getprintcap_pathlist: filter '%s'", path ); if( filters ) Add_line_list( filters, path, 0, 0, 0 ); break; case '/': DEBUG2("Getprintcap_pathlist: file '%s'", path ); /* void Read_file_list( int required, struct line_list *model, char *str, const char *linesep, int sort, const char *keysep, int uniq, int trim, int marker, int doinclude, int nocomment, int depth, int maxdepth ) */ Read_file_list(/*required*/required,/*model*/raw,/*str*/path, /*linesep*/Line_ends,/*sort*/0,/*keysep*/0,/*uniq*/0,/*trim*/1, /*marker*/0,/*doinclude*/1,/*nocomment*/1,/*depth*/0,/*maxdepth*/4); break; default: fatal(LOG_ERR, "Getprintcap_pathlist: entry not filter or absolute pathname '%s'", path ); } } Free_line_list(&l); if(DEBUGL4){ Dump_line_list( "Getprintcap_pathlist - filters", filters ); Dump_line_list( "Getprintcap_pathlist - info", raw ); } } /*************************************************************************** * int Filterprintcap( struct line_list *raw, *filters, char *str ) * - for each entry in the filters list do the following: * - make the filter, sending it the 'name' for access * - read from the filter until EOF, adding it to the raw list * - kill off the filter process ***************************************************************************/ void Filterprintcap( struct line_list *raw, struct line_list *filters, const char *str ) { int count, n, intempfd, outtempfd; char *filter; if( filters->count > 0 ){ intempfd = Make_temp_fd( 0 ); outtempfd = Make_temp_fd( 0 ); if( Write_fd_str( intempfd, str) < 0 || Write_fd_str( intempfd,"\n") < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Filterprintcap: Write_fd_str failed"); } for( count = 0; count < filters->count; ++count ){ filter = filters->list[count]; DEBUG2("Filterprintcap: filter '%s'", filter ); if( lseek(intempfd,0,SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Filterprintcap: lseek intempfd failed"); } n = Filter_file(Send_query_rw_timeout_DYN, intempfd, outtempfd, "PC_FILTER", filter, Filter_options_DYN, 0, 0, 0 ); if( n ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Filterprintcap: filter '%s' failed", filter); } } if( lseek(outtempfd,0,SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Filterprintcap: lseek outtempfd failed"); } Read_fd_and_split( raw,outtempfd,Line_ends,0,0,0,1,1); /* do not worry if these fail */ close( intempfd); intempfd = -1; close( outtempfd); outtempfd = -1; } } /*************************************************************************** * int In_group( char* *group, char *user ); * returns 1 on failure, 0 on success * scan group for user name * Note: we first check for the group. If there is none, we check for * wildcard (*) in group name, and then scan only if we need to ***************************************************************************/ static int In_group( char *group, char *user ) { struct group *grent; struct passwd *pwent; char **members; int result = 1; DEBUGF(DDB3)("In_group: checking '%s' for membership in group '%s'", user, group); if( group == 0 || user == 0 ){ return( result ); } /* first try getgrnam, see if it is a group */ pwent = getpwnam(user); if( (grent = getgrnam( group )) ){ DEBUGF(DDB3)("In_group: group id: %ld\n", (long)grent->gr_gid); if( pwent && ((long)pwent->pw_gid == (long)grent->gr_gid) ){ DEBUGF(DDB3)("In_group: user default group id: %ld\n", (long)pwent->pw_gid); result = 0; } else for( members = grent->gr_mem; result && *members; ++members ){ DEBUGF(DDB3)("In_group: member '%s'", *members); result = (safestrcmp( user, *members ) != 0); } } if( result && safestrchr( group, '*') ){ /* wildcard in group name, scan through all groups */ setgrent(); while( result && (grent = getgrent()) ){ DEBUGF(DDB3)("In_group: group name '%s'", grent->gr_name); /* now do match against group */ if( Globmatch( group, grent->gr_name ) == 0 ){ if( pwent && ((long)pwent->pw_gid == (long)grent->gr_gid) ){ DEBUGF(DDB3)("In_group: user default group id: %ld\n", (long)pwent->pw_gid); result = 0; } else { DEBUGF(DDB3)("In_group: found '%s'", grent->gr_name); for( members = grent->gr_mem; result && *members; ++members ){ DEBUGF(DDB3)("In_group: member '%s'", *members); result = (safestrcmp( user, *members ) != 0); } } } } endgrent(); } if( result && group[0] == '@' ) { /* look up user in netgroup */ #ifdef HAVE_INNETGR if( !innetgr( group+1, NULL, user, NULL ) ) { DEBUGF(DDB3)( "In_group: user %s NOT in netgroup %s", user, group+1 ); } else { DEBUGF(DDB3)( "In_group: user %s in netgroup %s", user, group+1 ); result = 0; } #else DEBUGF(DDB3)( "In_group: no innetgr() call, netgroups not permitted" ); #endif } DEBUGF(DDB3)("In_group: result: %d", result ); return( result ); } int Check_for_rg_group( char *user ) { int i, match = 0; struct line_list l; char *s; Init_line_list(&l); s = RestrictToGroupMembers_DYN; DEBUG3("Check_for_rg_group: name '%s', restricted_group '%s'", user, s ); if( s ){ match = 1; Split(&l,s,List_sep,0,0,0,0,0,0); for( i = 0; match && i < l.count; ++i ){ s = l.list[i]; match = In_group( s, user ); } } Free_line_list(&l); DEBUG3("Check_for_rg_group: result: %d", match ); return( match ); } /*************************************************************************** * Make_temp_fd( char *name, int namelen ) * 1. we can call this repeatedly, and it will make * different temporary files. * 2. we NEVER modify the temporary file name - up to the first '.' * is the base - we keep adding suffixes as needed. * 3. Remove_files uses the tempfile information to find and delete temp * files so be careful. ***************************************************************************/ static char *Init_tempfile( void ) { char *dir = 0, *s; struct stat statb; if( Is_server ){ if( dir == 0 ) dir = Spool_dir_DYN; if( dir == 0 ) dir = Server_tmp_dir_DYN; } else { dir = getenv( "LPR_TMP" ); if( dir == 0 ) dir = Default_tmp_dir_DYN; } /* remove trailing / */ if( (s = safestrrchr(dir,'/')) && s[1] == 0 ) *s = 0; if( dir == 0 || stat( dir, &statb ) != 0 || !S_ISDIR(statb.st_mode) ){ fatal(LOG_ERR, "Init_tempfile: bad tempdir '%s'", dir ); } DEBUG3("Init_tempfile: temp file '%s'", dir ); return( dir ); } int Make_temp_fd_in_dir( char **temppath, char *dir ) { int tempfd; struct stat statb; char pathname[MAXPATHLEN]; plp_snprintf(pathname,sizeof(pathname), "%s/temp%02dXXXXXX",dir,Tempfiles.count ); tempfd = mkstemp( pathname ); if( tempfd == -1 ){ Errorcode = JFAIL; fatal(LOG_INFO, "Make_temp_fd_in_dir: cannot create tempfile '%s'", pathname ); } Add_line_list(&Tempfiles,pathname,0,0,0); if( temppath ){ *temppath = Tempfiles.list[Tempfiles.count-1]; } if( fchmod(tempfd,(Is_server?Spool_file_perms_DYN:0) | 0600 ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Make_temp_fd_in_dir: chmod '%s' to 0%o failed ", pathname, Spool_file_perms_DYN ); } if( stat(pathname,&statb) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Make_temp_fd_in_dir: stat '%s' failed ", pathname ); } DEBUG1("Make_temp_fd_in_dir: fd %d, name '%s'", tempfd, pathname ); return( tempfd ); } int Make_temp_fd( char **temppath ) { return( Make_temp_fd_in_dir( temppath, Init_tempfile()) ); } /*************************************************************************** * Clear_tempfile_list() * - clear the list of tempfiles created for this job * - this is done by a child process ***************************************************************************/ void Clear_tempfile_list(void) { Free_line_list(&Tempfiles); } /*************************************************************************** * Unlink_tempfiles() * - remove the tempfiles created for this job ***************************************************************************/ void Unlink_tempfiles(void) { int i; for( i = 0; i < Tempfiles.count; ++i ){ DEBUG4("Unlink_tempfiles: unlinking '%s'", Tempfiles.list[i] ); unlink(Tempfiles.list[i]); } Free_line_list(&Tempfiles); } /*************************************************************************** * Remove_tempfiles() * - remove the tempfiles created for this job ***************************************************************************/ void Remove_tempfiles(void) { Unlink_tempfiles(); } /*************************************************************************** * Split_cmd_line * if we have xx "yy zz" we split this as * xx * yy zz ***************************************************************************/ void Split_cmd_line( struct line_list *l, char *line ) { char *s = line, *t; int c; DEBUG1("Split_cmd_line: line '%s'", line ); while( s && cval(s) ){ while( strchr(Whitespace,cval(s)) ) ++s; /* ok, we have skipped the whitespace */ if( (c = cval(s)) ){ if( c == '"' || c == '\'' ){ /* we now have hit a quoted string */ ++s; t = strchr(s,c); } else if( !(t = strpbrk(s, Whitespace)) ){ t = s+safestrlen(s); } if( t ){ c = cval(t); *t = 0; Add_line_list(l, s, 0, 0, 0); *t = c; if( c ) ++t; } s = t; } } if(DEBUGL1){ Dump_line_list("Split_cmd_line", l ); } } /*************************************************************************** * Make_passthrough * * int Make_passthrough - returns PID of process * char *line - command line * char *flags, - additional flags * struct line_list *passfd, - file descriptors * struct job *job - job with for option expansion * struct line_list *env_init - environment ***************************************************************************/ int Make_passthrough( char *line, const char *flags, struct line_list *passfd, struct job *job, struct line_list *env_init ) { int c, i, pid = -1, noopts, root, newfd, fd; struct line_list cmd; struct line_list env; char error[SMALLBUFFER]; char *s; DEBUG1("Make_passthrough: cmd '%s', flags '%s'", line, flags ); if( job ){ s = Find_str_value( &job->info,QUEUENAME ); if( !ISNULL(s) ){ Set_DYN(&Queue_name_DYN,s ); } } Init_line_list(&env); if( env_init ){ Merge_line_list(&env,env_init,Hash_value_sep,1,1); } Init_line_list(&cmd); while( isspace(cval(line)) ) ++line; if( cval(line) == '|' ) ++line; noopts = root = 0; while( cval(line) ){ while( isspace(cval(line)) ) ++line; if( !safestrncmp(line,"$-", 2) || !safestrncmp(line,"-$", 2) ){ noopts = 1; line += 2; } else if( !safestrncasecmp(line,"root", 4) ){ /* only set to root if it is the LPD server */ root = Is_server; line += 4; } else { break; } } c = cval(line); if( strpbrk(line, "<>|;") || c == '(' ){ Add_line_list( &cmd, Shell_DYN, 0, 0, 0 ); Add_line_list( &cmd, "-c", 0, 0, 0 ); Add_line_list( &cmd, line, 0, 0, 0 ); if( c != '(' ){ s = cmd.list[cmd.count-1]; s = safestrdup3("( ",s," )",__FILE__,__LINE__); if( cmd.list[cmd.count-1] ) free( cmd.list[cmd.count-1] ); cmd.list[cmd.count-1] = s; } Fix_dollars(&cmd, job, 1, flags); } else { Split_cmd_line(&cmd, line); if( !noopts ){ Split(&cmd, flags, Whitespace, 0,0, 0, 0, 0,0); } Fix_dollars(&cmd, job, 0, flags); } Check_max(&cmd,1); cmd.list[cmd.count] = 0; Setup_env_for_process(&env, job); if(DEBUGL1){ Dump_line_list("Make_passthrough - cmd",&cmd ); LOGDEBUG("Make_passthrough: fd count %d, root %d", passfd->count, root ); for( i = 0 ; i < passfd->count; ++i ){ fd = Cast_ptr_to_int(passfd->list[i]); LOGDEBUG(" [%d]=%d",i,fd); } Dump_line_list("Make_passthrough - env",&env ); } c = cmd.list[0][0]; if( c != '/' ){ fatal(LOG_ERR, "Make_passthrough: bad filter - not absolute path name'%s'", cmd.list[0] ); } if( (pid = dofork(0)) == -1 ){ logerr_die(LOG_ERR, "Make_passthrough: fork failed"); } else if( pid == 0 ){ for( i = 0; i < passfd->count; ++i ){ fd = Cast_ptr_to_int(passfd->list[i]); if( fd < i ){ /* we have fd 3 -> 4, but 3 gets wiped out */ do{ newfd = dup(fd); Max_open(newfd); if( newfd < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Make_passthrough: dup failed"); } DEBUG4("Make_passthrough: fd [%d] = %d, dup2 -> %d", i, fd, newfd ); passfd->list[i] = Cast_int_to_voidstar(newfd); } while( newfd < i ); } } if(DEBUGL4){ LOGDEBUG("Make_passthrough: after fixing fd, count %d", passfd->count ); for( i = 0 ; i < passfd->count; ++i ){ fd = Cast_ptr_to_int(passfd->list[i]); LOGDEBUG(" [%d]=%d",i,fd); } } /* set up full perms for filter */ if( Is_server ){ if( root ){ if( UID_root ) To_euid_root(); } else { Full_daemon_perms(); } } else { Full_user_perms(); } for( i = 0; i < passfd->count; ++i ){ fd = Cast_ptr_to_int(passfd->list[i]); if( dup2(fd,i) == -1 ){ plp_snprintf(error,sizeof(error), "Make_passthrough: pid %ld, dup2(%d,%d) failed", (long)getpid(), fd, i ); Write_fd_str(2,error); exit(JFAIL); } } close_on_exec(passfd->count); execve(cmd.list[0],cmd.list,env.list); plp_snprintf(error,sizeof(error), "Make_passthrough: pid %ld, execve '%s' failed - '%s'\n", (long)getpid(), cmd.list[0], Errormsg(errno) ); Write_fd_str(2,error); exit(JABORT); } passfd->count = 0; Free_line_list(passfd); Free_line_list(&env); Free_line_list(&cmd); return( pid ); } /* * Filter_file: we filter a file through this program * input_fd = input file descriptor. if -1, then we make it /dev/null * tempfile = name of tempfile for output * error_header = header used for error messages from filter * pgm = program * filter_options = options for filter * job = job we are doing the work for * env = environment options we want to pass * RETURN: * exit status of the filter, adjusted to be in the JXXX status * if it exits with error status, we get JSIGNAL */ int Filter_file( int timeout, int input_fd, int output_fd, const char *error_header, char *pgm, const char * filter_options, struct job *job, struct line_list *env, int verbose ) { int innull_fd, outnull_fd, pid, len, n; char *s; int of_error[2]; plp_status_t status; struct line_list files; char buffer[SMALLBUFFER]; Init_line_list( &files ); of_error[0] = of_error[1] = -1; innull_fd = input_fd; if( innull_fd < 0 && (innull_fd = open("/dev/null", O_RDWR )) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: open /dev/null failed"); } Max_open(innull_fd); outnull_fd = output_fd; if( outnull_fd < 0 && (outnull_fd = open("/dev/null", O_RDWR )) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: open /dev/null failed"); } Max_open(outnull_fd); if( pipe( of_error ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: pipe() failed"); } Max_open(of_error[0]); Max_open(of_error[1]); DEBUG3("Filter_file: fd of_error[%d,%d]", of_error[0], of_error[1] ); Check_max(&files, 10 ); files.list[files.count++] = Cast_int_to_voidstar(innull_fd); /* stdin */ files.list[files.count++] = Cast_int_to_voidstar(outnull_fd); /* stdout */ files.list[files.count++] = Cast_int_to_voidstar(of_error[1]); /* stderr */ if( (pid = Make_passthrough( pgm, filter_options, &files, job, env )) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: could not create process '%s'", pgm); } files.count = 0; Free_line_list(&files); if( input_fd < 0 ) close(innull_fd); innull_fd = -1; if( output_fd < 0 ) close(outnull_fd); outnull_fd = -1; if( (close(of_error[1]) == -1 ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: X8 close(%d) failed", of_error[1]); } of_error[1] = -1; buffer[0] = 0; len = 0; while( len < (int)sizeof(buffer)-1 && (n = Read_fd_len_timeout(timeout, of_error[0],buffer+len,sizeof(buffer)-len-1)) >0 ){ buffer[n+len] = 0; while( (s = safestrchr(buffer,'\n')) ){ *s++ = 0; setstatus(job, "%s: %s", error_header, buffer ); memmove(buffer,s,safestrlen(s)+1); } len = safestrlen(buffer); } if( buffer[0] ){ setstatus(job, "%s: %s", error_header, buffer ); } if( (close(of_error[0]) == -1 ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: X8 close(%d) failed", of_error[0]); } of_error[0] = -1; while( (n = plp_waitpid(pid,&status,0)) != pid ){ int err = errno; DEBUG1("Filter_file: waitpid(%d) returned %d, err '%s'", pid, n, Errormsg(err) ); if( err == EINTR ) continue; Errorcode = JABORT; logerr_die(LOG_ERR, "Filter_file: waitpid(%d) failed", pid); } DEBUG1("Filter_file: pid %d, exit status '%s'", pid, Decode_status(&status) ); n = 0; if( WIFSIGNALED(status) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_file: pgm '%s' died with signal %d, '%s'", pgm, n, Sigstr(n)); } n = WEXITSTATUS(status); if( n > 0 && n < 32 ) n+=(JFAIL-1); DEBUG1("Filter_file: final status '%s'", Server_status(n) ); if( verbose ){ setstatus(job, "Filter_file: pgm '%s' exited with status '%s'", pgm, Server_status(n)); } return( n ); } #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define LOWER "abcdefghijklmnopqrstuvwxyz" #define DIGIT "01234567890" #define SAFE "-_." #define LESS_SAFE SAFE "@/:()=,+-%" char *Is_clean_name( char *s ) { int c; if( s ){ for( ; (c = cval(s)); ++s ){ if( !(isalnum(c) || safestrchr( SAFE, c )) ) return( s ); } } return( 0 ); } void Clean_name( char *s ) { int c; if( s ){ for( ; (c = cval(s)); ++s ){ if( !(isalnum(c) || safestrchr( SAFE, c )) ) *s = '_'; } } } /* * Find a possible bad character in a line */ static int Is_meta( int c ) { return( !( isspace(c) || isalnum( c ) || (Safe_chars_DYN && safestrchr(Safe_chars_DYN,c)) || safestrchr( LESS_SAFE, c ) ) ); } static char *Find_meta( char *s ) { int c = 0; if( s ){ for( ; (c = cval(s)); ++s ){ if( Is_meta( c ) ) return( s ); } s = 0; } return( s ); } void Clean_meta( char *t ) { char *s = t; if( t ){ while( (s = safestrchr(s,'\\')) ) *s = '/'; s = t; for( s = t; (s = Find_meta( s )); ++s ){ *s = '_'; } } } /********************************************************************** * Dump_parms( char *title, struct keywords *k ) * - dump the list of keywords and variable values given by the * entries in the array. **********************************************************************/ void Dump_parms( const char *title, struct keywords *k ) { char *s; void *p; int v; if( title ) LOGDEBUG( "*** Current Values '%s' ***", title ); for( ; k && k->keyword; ++k ){ if( !(p = k->variable) ) continue; switch(k->type){ case FLAG_K: v = *(int *)(p); LOGDEBUG( " %s FLAG %d", k->keyword, v); break; case INTEGER_K: v = *(int *)(p); LOGDEBUG( " %s# %d (0x%x, 0%o)", k->keyword,v,v,v); break; case STRING_K: s = *(char **)(p); if( s ){ LOGDEBUG( " %s= '%s'", k->keyword, s ); } else { LOGDEBUG( " %s= ", k->keyword ); } break; default: LOGDEBUG( " %s: UNKNOWN TYPE", k->keyword ); } } if( title ) LOGDEBUG( "*** ***"); } /********************************************************************** * Dump_parms( char *title, struct keywords *k ) * - dump the list of keywords and variable values given by the * entries in the array. **********************************************************************/ void Dump_default_parms( int fd, const char *title, struct keywords *k ) { const char *def, *key; char buffer[2*SMALLBUFFER]; int n; if( title ){ plp_snprintf(buffer,sizeof(buffer), "%s\n", title ); Write_fd_str(fd, buffer); } for( ; k && k->keyword; ++k ){ n = 0; key = k->keyword; def = k->default_value; switch(k->type){ case FLAG_K: if( def ){ if( cval(def) == '=' ) ++def; n = strtol(def,0,0); } plp_snprintf(buffer,sizeof(buffer), " :%s%s\n", key, n?"":"@"); break; case INTEGER_K: if( def ){ if( cval(def) == '=' ) ++def; n = strtol(def,0,0); } plp_snprintf(buffer,sizeof(buffer), " :%s=%d\n", key, n); break; case STRING_K: if( def ){ if( cval(def) == '=' ) ++def; } else { def = ""; } plp_snprintf(buffer,sizeof(buffer), " :%s=%s\n", key, def); break; default: plp_snprintf(buffer,sizeof(buffer), "# %s UNKNOWN\n", key); } Write_fd_str(fd, buffer); } Write_fd_str(fd, "\n"); } /*************************************************************************** *char *Fix_Z_opts( struct job *job ) * * fix the -Z option value * Remove_Z_DYN - remove these from the Z string * Prefix_Z_DYN - put these at the start * Append_Z_DYN - put these at the end * Prefix_option_to_option - prefix options to start of option * OS Z -> O and S to Z * Z S -> Z to S ***************************************************************************/ void Fix_Z_opts( struct job *job ) { char *str, *s, *pattern, *start, *end; char buffer[16]; struct line_list l; int i, c, n; Init_line_list(&l); str = Find_str_value( &job->info,"Z" ); DEBUG4("Fix_Z_opts: initially '%s', remove '%s', append '%s', prefix '%s'", str, Remove_Z_DYN, Append_Z_DYN, Prefix_Z_DYN ); DEBUG4("Fix_Z_opts: prefix_options '%s'", Prefix_option_to_option_DYN ); if( Prefix_option_to_option_DYN ){ s = Prefix_option_to_option_DYN; while( s && *s ){ if( !isalpha(cval(s)) ){ memmove(s,s+1,safestrlen(s+1)+1); } else { ++s; } } s = Prefix_option_to_option_DYN; /* now we have the fixed value */ DEBUG4("Fix_Z_opts: prefix_options fixed '%s'", s); n = safestrlen(s); if( n < 2 ){ fatal(LOG_ERR, "Fix_Z_opts: not enough letters '%s'", s ); } /* find the starting values */ str = 0; buffer[1] = 0; for( i = 0; i < n-1; ++i ){ buffer[0] = s[i]; if( (start = Find_str_value(&job->info,buffer)) ){ str= safeextend2(str,start, __FILE__,__LINE__); Set_str_value(&job->info,buffer,0); } } /* do we need to prefix it? */ if( str ){ buffer[0] = s[i]; start = Find_str_value(&job->info,buffer); /* put at start */ start= safestrdup3(str,(start?",":""),start, __FILE__,__LINE__); Set_str_value(&job->info, buffer, start ); if( start ) free(start); start = 0; } if( str ) free(str); str = 0; } str = Find_str_value( &job->info,"Z" ); DEBUG4("Fix_Z_opts: after Prefix_option_to_option '%s'", str ); if( Remove_Z_DYN && str ){ /* remove the various options - split on commas */ Split(&l, Remove_Z_DYN, ",", 0, 0, 0, 0, 0,0); for( i = 0; i < l.count; ++i ){ pattern = l.list[i]; DEBUG4("Fix_Z_opts: REMOVE pattern '%s'", pattern ); for( start = str; start && *start; start = end ){ c = 0; if( !(end = strpbrk(start,",")) ){ end = start+safestrlen(start); } c = *end; *end = 0; /* now we have the option */ DEBUG4("Fix_Z_opts: str '%s'", start ); if( !Globmatch( pattern, start) ){ /* move the values up in the string, end -> ',' */ if( c ){ memmove( start,end+1, safestrlen(end+1)+1); } else { *start = 0; } end = start; } else { *end = c; if( c ) ++end; } } } Free_line_list(&l); } DEBUG4("Fix_Z_opts: after remove '%s'", str ); if( Append_Z_DYN && *Append_Z_DYN ){ s = safestrdup3(str,",",Append_Z_DYN,__FILE__,__LINE__); Set_str_value(&job->info,"Z",s); str = Find_str_value(&job->info,"Z"); if(s) free(s); s = 0; } DEBUG4("Fix_Z_opts: after append '%s'", str ); if( Prefix_Z_DYN && *Prefix_Z_DYN ){ s = safestrdup3(Prefix_Z_DYN,",",str,__FILE__,__LINE__); Set_str_value(&job->info,"Z",s); str = Find_str_value(&job->info,"Z"); if(s) free(s); s = 0; } DEBUG4("Fix_Z_opts: after Prefix_Z '%s'", str ); for( s = safestrchr(str,','); s; s = strchr(s,',') ){ if( cval(s+1) == ',' ){ memmove(s,s+1,safestrlen(s+1)+1); } else { ++s; } } if( str ){ if( cval(str) == ',' ){ memmove(str,str+1,safestrlen(str+1)+1); } if( (n = safestrlen(str)) && cval(str+n-1) == ',' ) str[n-1] = 0; } DEBUG4("Fix_Z_opts: final Z '%s'", str ); Free_line_list(&l); } /*************************************************************************** * void Fix_dollars( struct line_list *l, struct job *job, * int nosplit, char *flags ) * Note: see the code for the keys! * replace * \x with x except for \r,\n,\t, -> space * \nnn with nnn * $* with flag string, and then evaluate options * $X with -X * $0X with -X * $-X with * $0-X with (same as $-X) * ${s} with value of control file parameter s (must be upper case) * ${ss} with value of printcap option ss * $'{ss} with quoted value of printcap option ss * * nosplit - do not split the option value over two entries * flags - flags to use for $* ***************************************************************************/ void Fix_dollars( struct line_list *l, struct job *job, int nosplit, const char *flags ) { int i, j, count, space, notag, kind, n, c, position, quote; const char *str; char *strv, *s, *t, *rest; char buffer[SMALLBUFFER], tag[32]; if(DEBUGL4)Dump_line_list("Fix_dollars- before", l ); for( count = 0; count < l->count; ++count ){ position = 0; for( strv = l->list[count]; (s = safestrpbrk(strv+position,"$\\")); ){ DEBUG4("Fix_dollars: expanding [%d]='%s'", count, strv ); position = s - strv; c = cval(s); *s++ = 0; if( c == '\\' ){ c = *s++; /* check for end of string */ if( c == 0 ) break; if( c == 'r' || c == 'n' || c == 't' ){ c = ' '; } else if( isdigit( c ) ){ tag[0] = c; if( (tag[1] = *s) ) ++s; if( (tag[2] = *s) ) ++s; tag[3] = 0; c = strtol( tag, 0, 8 ); } if( !isprint(c) || isspace(c) ) c = ' '; strv[position] = c; ++position; memmove(strv+position,s,safestrlen(s)+1); continue; } /* now we handle the $ */ str = 0; rest = 0; n = space = notag = quote = 0; kind = STRING_K; while( (c = cval(s)) && safestrchr( " 0-'", c) ){ switch( c ){ case '0': case ' ': space = 1; break; case '-': notag = 1; break; case '\'': quote = 1; break; default: break; } ++s; } rest = s+1; if( c == '*' ){ if( flags && *flags ){ rest = safestrdup(rest,__FILE__,__LINE__); position = safestrlen(strv); l->list[count] = strv = safeextend3(strv,flags,rest,__FILE__,__LINE__); if( rest ) free(rest); rest = 0; } continue; } else if( c == '{' ){ ++s; if( !(rest = safestrchr(rest,'}')) ){ break; } *rest++ = 0; if( !cval(s+1) && isupper(cval(s)) ){ str = job?Find_str_value( &job->info,s):0; } else { str = Find_value( &PC_entry_line_list, s ); } notag = 1; space = 0; } else { quote = 0; switch( c ){ case 'a': str = Accounting_file_DYN; if( str && cval(str) == '|' ) str = 0; break; case 'b': str = job?Find_str_value(&job->info,SIZE):0; break; case 'c': notag = 1; space=0; t = job?Find_str_value(&job->info,FORMAT):0; if( t && *t == 'l'){ str="-c"; } break; case 'd': str = Spool_dir_DYN; break; case 'e': str = job?Find_str_value(&job->info, DF_NAME):0; break; case 'f': str = job?Find_str_value(&job->info,"N"):0; break; case 'h': str = job?Find_str_value(&job->info,FROMHOST):0; break; case 'i': str = job?Find_str_value(&job->info,"I"):0; break; case 'j': str = job?Find_str_value(&job->info,NUMBER):0; break; case 'k': str = job?Find_str_value(&job->info,XXCFTRANSFERNAME):0; break; case 'l': kind = INTEGER_K; n = Page_length_DYN; break; case 'n': str = job?Find_str_value(&job->info,LOGNAME):0; break; case 'p': str = RemotePrinter_DYN; break; case 'r': str = RemoteHost_DYN; break; case 's': str = Status_file_DYN; break; case 't': str = Time_str( 0, time( (void *)0 ) ); break; case 'w': kind = INTEGER_K; n = Page_width_DYN; break; case 'x': kind = INTEGER_K; n = Page_x_DYN; break; case 'y': kind = INTEGER_K; n = Page_y_DYN; break; case 'F': str = job?Find_str_value(&job->info,FORMAT):0; break; case 'P': str = Printer_DYN; break; case 'S': str = Comment_tag_DYN; break; /* case '_': str = esc_Auth_client_id_DYN; break; */ default: if( isupper(c) ){ buffer[1] = 0; buffer[0] = c; str = job?Find_str_value( &job->info,buffer):0; } break; } } buffer[0] = 0; tag[0] = 0; switch( kind ){ case INTEGER_K: plp_snprintf(buffer,sizeof(buffer), "%d", n ); str = buffer; break; } DEBUG4( "Fix_dollars: strv '%s', found '%s', rest '%s', notag %d, space %d", strv, str, rest, notag, space ); tag[0] = 0; if( str && !cval(str) ) str = 0; if( quote && !str ) str = ""; if( str ){ rest = safestrdup(rest,__FILE__,__LINE__); if( notag ){ space = 0; } else { i = 0; if( (quote || nosplit) && !space ) tag[i++] = '\''; tag[i++] = '-'; tag[i++] = c; tag[i++] = 0; l->list[count] = strv = safeextend2( strv, tag, __FILE__,__LINE__ ); if( !(quote || nosplit) ) tag[0] = 0; tag[1] = 0; } if( space ){ DEBUG4("Fix_dollars: space [%d]='%s'", count, l->list[count] ); if( quote || nosplit ){ position = safestrlen(strv) + safestrlen(str) + 2; l->list[count] = strv = safeextend5( strv," '",str,"'",rest,__FILE__,__LINE__); } else { Check_max(l,2); for( i = l->count; i >= count; --i ){ l->list[i+1] = l->list[i]; } ++l->count; ++count; l->list[count] = strv = safestrdup2(str,rest,__FILE__,__LINE__); position = safestrlen(str); } } else { position = safestrlen(strv) + safestrlen(str)+safestrlen(tag); l->list[count] = strv = safeextend4(strv,str,tag,rest,__FILE__,__LINE__); } if( rest ) free(rest); rest = 0; } else { memmove(strv+position,rest,safestrlen(rest)+1); } DEBUG4("Fix_dollars: [%d]='%s'", count, strv ); } } for( i = j = 0; i < l->count; ++i ){ if( (s = l->list[i]) && *s == 0 ){ free(s); s = 0; } l->list[j] = s; if( s ) ++j; } l->count = j; if(DEBUGL4)Dump_line_list("Fix_dollars- after", l ); } /* * char *Make_pathname( char *dir, char *file ) * - makes a full pathname from the dir and file part */ char *Make_pathname( const char *dir, const char *file ) { char *s, *path; if( file == 0 ){ path = 0; } else if( file[0] == '/' ){ path = safestrdup(file,__FILE__,__LINE__); } else if( dir ){ path = safestrdup3(dir,"/",file,__FILE__,__LINE__); } else { path = safestrdup2("./",file,__FILE__,__LINE__); } if( (s = path) ) while((s = strstr(s,"//"))) memmove(s,s+1,safestrlen(s)+1 ); return(path); } /*************************************************************************** * Get_keywords and keyval * - decode the control word and return a key ***************************************************************************/ int Get_keyval( char *s, struct keywords *controlwords ) { int i; const char *t; for( i = 0; controlwords[i].keyword; ++i ){ if( safestrcasecmp( s, controlwords[i].keyword ) == 0 || ( (t = controlwords[i].translation) && safestrcasecmp( s, _(t) ) == 0) ){ return( controlwords[i].type ); } } return( 0 ); } const char *Get_keystr( int c, struct keywords *controlwords ) { int i; for( i = 0; controlwords[i].keyword; ++i ){ if( controlwords[i].type == c ){ return( controlwords[i].keyword ); } } return( 0 ); } char *Escape( const char *str, int level ) { char *s = 0; int i, c, j, k, incr = 3*level; int len = 0; if( str == 0 || *str == 0 ) return(0); if( level <= 0 ) level = 1; len = safestrlen(str); for( j = 0; (c = cval(str+j)); ++j ){ if( c != ' ' && !isalnum( c ) ){ len += incr; } } DEBUG5("Escape: level %d, allocated length %d, length %d, for '%s'", level, len, safestrlen(str), str ); s = malloc_or_die(len+1,__FILE__,__LINE__); i = 0; for( i = j = 0; (c = cval(str+j)); ++j ){ if( c == ' ' ){ s[i++] = '?'; } else if( !isalnum( c ) ){ plp_snprintf(s+i,4, "%%%02x",c); /* we encode the % as %25 and move the other stuff over */ for( k = 1; k < level; ++k ){ /* we move the stuff after the % two positions */ /* s+i is the %, s+i+1 is the first digit */ memmove(s+i+3, s+i+1, safestrlen(s+i+1)+1); memmove(s+i+1, "25", 2 ); } i += safestrlen(s+i); } else { s[i++] = c; } } s[i] = 0; DEBUG5("Escape: final length %d '%s'", i, s ); return(s); } /* * we replace a colon by \072 in a dynmaically allocated string */ void Escape_colons( struct line_list *list ) { int linenumber, len, c; char *str, *s, *t, *newstr; for( linenumber = 0; list && linenumber < list->count; ++linenumber ){ str = list->list[linenumber]; if( str == 0 || strchr(str,':') == 0 ) continue; len = safestrlen(str); for( s = str; (s = strchr(s,':')); ++s ){ len += 4; } DEBUG4("Escape_colons: new length %d for '%s'", len, str ); newstr = t = malloc_or_die(len+1,__FILE__,__LINE__); for( s = str; (c = cval(s)); ++s ){ if( c != ':' ){ *t++ = c; } else { strcpy(t,"\\072"); t += 4; } } *t = 0; free(str); list->list[linenumber] = newstr; DEBUG4("Escape_colons: '%s'", newstr ); } } void Unescape( char *str ) { int i, c; char *s = str; char buffer[4]; if( str == 0 ) return; for( i = 0; (c = cval(str)); ++str ){ if( c == '?' ){ c = ' '; } else if( c == '%' && (buffer[0] = cval(str+1)) && (buffer[1] = cval(str+2)) ){ buffer[2] = 0; c = strtol(buffer,0,16); str += 2; } s[i++] = c; } s[i] = 0; DEBUG5("Unescape '%s'", s ); } /*************************************************************************** * int Fix_str( char * str ) * - make a copy of the original string * - substitute all the escape characters * \f, \n, \r, \t, and \nnn ***************************************************************************/ char *Fix_str( char *str ) { char *s, *end, *dupstr, buffer[4]; int c, len; DEBUG3("Fix_str: '%s'", str ); if( str == 0 ) return(str); dupstr = s = safestrdup(str,__FILE__,__LINE__); DEBUG3("Fix_str: dup '%s', 0x%lx", dupstr, Cast_ptr_to_long(dupstr) ); for( ; (s = safestrchr(s,'\\')); ){ end = s+1; c = cval(end); /* check for \nnn */ if( isdigit( c ) ){ for( len = 0; len < 3; ++len ){ if( !isdigit(cval(end)) ){ break; } buffer[len] = *end++; } c = strtol(buffer,0,8); } else { switch( c ){ case 'f': c = '\f'; break; case 'r': c = '\r'; break; case 'n': c = '\n'; break; case 't': c = '\t'; break; } ++end; } s[0] = c; if( c == 0 ) break; memcpy(s+1,end,safestrlen(end)+1); ++s; } if( *dupstr == 0 ){ free(dupstr); dupstr = 0; } DEBUG3( "Fix_str: final str '%s' -> '%s'", str, dupstr ); return( dupstr ); } /*************************************************************************** * int Shutdown_or_close( int fd ) * - if the file descriptor is a socket, then do a shutdown (write), return fd; * or if the * - otherwise close it and return -1; ***************************************************************************/ int Shutdown_or_close( int fd ) { struct stat statb; if( fd < 0 || fstat( fd, &statb ) == -1 ){ fd = -1; } else if( Backwards_compatible_DYN || !Half_close_DYN || !(S_ISSOCK(statb.st_mode)) || shutdown( fd, 1 ) == -1 ){ close(fd); fd = -1; } return( fd ); } /* change the format of the output of a filter * bq_format=IoIo...D * I is input type or '*' for all types * o is output type * D is default * If no default, preserve the original type */ /* moved here from lpd_jobs.c to avoid the whole file sucked into lpr - brl */ void Fix_bq_format( int format, struct line_list *datafile ) { char fmt[2], *s; fmt[0] = format; fmt[1] = 0; if( (s = Bounce_queue_format_DYN) ){ lowercase( s ); while( s[0] ){ if( s[1] ){ if( format == cval(s) || cval(s) == '*' ){ fmt[0] = s[1]; break; } } else { if( cval(s) != '*' ){ fmt[0] = s[0]; } break; } s += 2; } } Set_str_value(datafile,FORMAT,fmt); } lprng-3.8.B/src/common/user_objs.c0000644000131400013140000001151711531672132014023 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: user_objs.c,v 1.74 2004/09/24 20:19:59 papowell Exp $"; #include "lp.h" #include "getqueue.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * * Patrick Powell Mon May 29 11:49:21 PDT 2000 * This is a sample of what you need to do to implement * a chooser function at the routine level. You may need to do this * if your overhead for checking, etc., is too high for a filter. * * extern int CHOOSER_ROUTINE( struct line_list *servers, * struct line_list *available, int &use_subserver ); * * servers is a (dynamically) allocated array of pointers to line_list data * structures that contains the information about the subserver queue. * * The first entry in the queue is the information about load * balance queue itself, the remaining ones are the information about * the sub server queues. You can access this by using: * * struct line_list *sp; * for( i = 1; i < servers->count; ++i ){ * sp = (void *)servers->list[i]; * pr = Find_str_value(sp,PRINTER,Value_sep); * if( (s = Find_str_value(sp,SERVER,Value_sep)) ){ * DEBUG1("subserver '%s' active server '%s'", pr,s ); * } * } * * available: is list of lines of the form: * queue1=0x1 * queue2=0x2 * * These are the queue names that are available with the * indexes into the servers.list for their information. You can * use this as follows: * * for( i = 0; i < available->count; ++i ){ * s = available.list[i]; * if( (t = safestrpbrk(s,Value_sep)) ){ * *t++ = 0; * n = strtol(t,0,0); * sp = (void *)servers->list[n]; * / * now you have the information for the server * / * } * } * * use_subserver: return value for queue (subserver) to use in the * servers list. If you return or set it to -1, skip this job. * * RETURN VALUE: * * if 0, then process job. (note: return value of 0 and use_subserver[0] == -1 * will skip the job. * Nonzero - set job status to the value and update the job. Useful to * set JHOLD, etc., if you need to do something like this. * ***************************************************************************/ int test_chooser( struct line_list *servers, struct line_list *available, int *use_subserver ) { struct line_list *sp; char *s, *t, *pr; int i, n = -1; DEBUG1("test_chooser: servers %d, available %d", servers->count, available->count ); for( i = 0; i < available->count; ++i ){ s = available->list[i]; DEBUG1("test_chooser: avail[%d]='%s'", i, s ); if( (t = safestrpbrk(s,Value_sep)) ){ n = strtol(t+1,0,0); DEBUG1("test_chooser: '%s' index '%d'", s, n ); sp = (void *)servers->list[n]; pr = Find_str_value(sp,PRINTER,Value_sep); DEBUG1("test_chooser: available '%s'", pr ); if( i == 0 ){ *use_subserver = n; } } } return( 0 ); } /* * Make_sort_key * Make a sort key from the image information * See the comments in LPRng/src/common/getqueue for details on * the various functions and what they do. * * This routine returns a 'key;value' string (dynmically allocated) * that is used to sort the jobs in a spool directory. * The format of the key returned string is: * xxx|xxx|xxx|xxx;cfname * Note 1: xxx cannot have ';' in them. * Note 2: cfname must be at the end of the string. * */ char *test_sort_key( struct job *job ) { char *cmpstr = 0; /* first key is DONE_TIME - done jobs come last */ cmpstr = intval(DONE_TIME,&job->info,cmpstr); /* next key is REMOVE_TIME - removed jobs come before last */ cmpstr = intval(REMOVE_TIME,&job->info,cmpstr); /* next key is ERROR - error jobs jobs come before removed */ cmpstr = strzval(ERROR,&job->info,cmpstr); /* next key is HOLD - before the error jobs */ cmpstr = intval(HOLD_CLASS,&job->info,cmpstr); cmpstr = intval(HOLD_TIME,&job->info,cmpstr); /* next key is MOVE - before the held jobs */ cmpstr = strnzval(MOVE,&job->info,cmpstr); /* now by priority */ if( Ignore_requested_user_priority_DYN == 0 ){ cmpstr = strval(PRIORITY,&job->info,cmpstr,Reverse_priority_order_DYN); } /* now we do TOPQ */ cmpstr = revintval(PRIORITY_TIME,&job->info,cmpstr); /* now we do FirstIn, FirstOut */ cmpstr = intval(JOB_TIME,&job->info,cmpstr); cmpstr = intval(JOB_TIME_USEC,&job->info,cmpstr); /* now we do by job number if two at same time (very unlikely) */ cmpstr = intval(NUMBER,&job->info,cmpstr); DEBUG4("test_sort_key: cmpstr '%s'", cmpstr ); return(cmpstr); } lprng-3.8.B/src/common/getopt.c0000644000131400013140000000521611531672131013330 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "getopt.h" /**** ENDINCLUDE ****/ static char *next_opt; /* pointer to next option char */ static char **Argv_p; static int Argc_p; int Getopt (int argc, char *argv[], const char *optstring) { int option; /* current option found */ char *match; /* matched option in optstring */ if( argv == 0 ){ /* reset parsing */ next_opt = 0; Optind = 0; return(0); } if (Optind == 0 ) { char *basename; /* * set up the Name variable for error messages * setproctitle will change this, so * make a copy. */ if( Name == 0 ){ if( argv[0] ){ if( (basename = safestrrchr( argv[0], '/' )) ){ ++basename; } else { basename = argv[0]; } Name = basename; } else { Name = "???"; } } Argv_p = argv; Argc_p = argc; Optind = 1; } while( next_opt == 0 || *next_opt == '\0' ){ /* No more arguments left in current or initial string */ if (Optind >= argc){ return (EOF); } next_opt = argv[Optind++]; } /* check for start of option string AND no initial '-' */ if( (next_opt == argv[Optind-1]) ){ if( next_opt[0] != '-' ){ --Optind; return( EOF ); } else { ++next_opt; if( next_opt[0] == 0 ){ return( EOF ); } } } option = *next_opt++; /* * Case of '--', Force end of options */ if (option == '-') { if( *next_opt ){ if( Opterr ){ (void) FPRINTF (STDERR, _("--X option form illegal\n") ); return('?'); } } return ( EOF ); } /* * See if option is in optstring */ if ((match = (char *) safestrchr (optstring, option)) == 0 ){ if( Opterr ){ (void) FPRINTF (STDERR, _("%s: Illegal option '%c'\n"), Name, option); } return( '?' ); } /* * Argument? */ if (match[1] == ':') { /* * Set Optarg to proper value */ Optarg = 0; if (*next_opt != '\0') { Optarg = next_opt; } else if (Optind < argc) { Optarg = argv[Optind++]; if (Optarg != 0 && *Optarg == '-') { Optarg = 0; } } if( Optarg == 0 && Opterr ) { (void) FPRINTF (STDERR, _("%s: missing argument for '%c'\n"), Name, option); option = '?'; } next_opt = 0; } else if (match[1] == '?') { /* * Set Optarg to proper value */ if (*next_opt != '\0') { Optarg = next_opt; } else { Optarg = 0; } next_opt = 0; } return (option); } lprng-3.8.B/src/common/plp_snprintf.c0000644000131400013140000010553611531672132014553 00000000000000/************************************************************************** * Copyright 1994-2003 Patrick Powell, San Diego, CA **************************************************************************/ /* Overview: plp_snprintf( char *buffer, int len, const char *format,...) plp_unsafe_snprintf( char *buffer, int len, const char *format,...) its horribly unsafe companion that does NOT protect you from the printing of evil control characters, but may be necessary See the man page documentation below This version of snprintf was developed originally for printing on a motley collection of specialized hardware that had NO IO library. Due to contractual restrictions, a clean room implementation of the printf() code had to be developed. The method chosen for printf was to be as paranoid as possible, as these platforms had NO memory protection, and very small address spaces. This made it possible to try to print very long strings, i.e. - all of memory, very easily. To guard against this, all printing was done via a buffer, generous enough to hold strings, but small enough to protect against overruns, etc. Strangely enough, this proved to be of immense importance when SPRINTFing to a buffer on a stack... The rest, of course, is well known, as buffer overruns in the stack are a common way to do horrible things to operating systems, security, etc etc. This version of snprintf is VERY limited by modern standards. Revision History: First Released Version - 1994. This version had NO comments. First Released Version - 1994. This version had NO comments. Second Major Released Version - Tue May 23 10:43:44 PDT 2000 Configuration and other items changed. Read this doc. Treat this as a new version. Minor Revision - Mon Apr 1 09:41:28 PST 2002 - fixed up some constants and casts COPYRIGHT AND TERMS OF USE: You may use, copy, distribute, or otherwise incorporate this software and documentation into any product or other item, provided that the copyright in the documentation and source code as well as the source code generated constant strings in the object, executable or other code remain in place and are present in executable modules or objects. You may modify this code as appropriate to your usage; however the modified version must be identified by changing the various source and object code identification strings as is appropriately noted in the source code. You can use this with the GNU CONFIGURE utility. This should define the following macros appropriately: HAVE_STDARG_H - if the include file is available HAVE_VARARG_H - if the include file is available HAVE_STRERROR - if the strerror() routine is available. If it is not available, then examine the lines containing the tests below. HAVE_SYS_ERRLIST - have sys_errlist available HAVE_DECL_SYS_ERRLIST - sys_errlist declaration in include files HAVE_SYS_NERR - have sys_nerr available HAVE_DECL_SYS_NERR - sys_nerr declaration in include files HAVE_QUAD_T - if the quad_t type is defined HAVE_LONG_LONG - if the long long type is defined HAVE_LONG_DOUBLE - if the long double type is defined If you are using the GNU configure (autoconf) facility, add the following line to the configure.in file, to force checking for the quad_t and long long data types: AC_CHECK_HEADERS(stdlib.h,stdio.h,unistd.h,errno.h) AC_CHECK_FUNCS(strerror) AC_CACHE_CHECK(for errno, ac_cv_errno, [ AC_TRY_LINK(,[extern int errno; return (errno);], ac_cv_errno=yes, ac_cv_errno=no) ]) if test "$ac_cv_errno" = yes; then AC_DEFINE(HAVE_ERRNO) AC_CACHE_CHECK(for errno declaration, ac_cv_decl_errno, [ AC_TRY_COMPILE([ #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_ERRNO_H #include ],[return(sys_nerr);], ac_cv_decl_errno=yes, ac_cv_decl_errno=no) ]) if test "$ac_cv_decl_errno" = yes; then AC_DEFINE(HAVE_DECL_ERRNO) fi; fi AC_CACHE_CHECK(for sys_nerr, ac_cv_sys_nerr, [ AC_TRY_LINK(,[extern int sys_nerr; return (sys_nerr);], ac_cv_sys_nerr=yes, ac_cv_sys_nerr=no) ]) if test "$ac_cv_sys_nerr" = yes; then AC_DEFINE(HAVE_SYS_NERR) AC_CACHE_CHECK(for sys_nerr declaration, ac_cv_decl_sys_nerr, [ AC_TRY_COMPILE([ #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif],[return(sys_nerr);], ac_cv_decl_sys_nerr_def=yes, ac_cv_decl_sys_nerr_def=no) ]) if test "$ac_cv_decl_sys_nerr" = yes; then AC_DEFINE(HAVE_DECL_SYS_NERR) fi fi AC_CACHE_CHECK(for sys_errlist array, ac_cv_sys_errlist, [AC_TRY_LINK(,[extern char *sys_errlist[]; sys_errlist[0];], ac_cv_sys_errlist=yes, ac_cv_sys_errlist=no) ]) if test "$ac_cv_sys_errlist" = yes; then AC_DEFINE(HAVE_SYS_ERRLIST) AC_CACHE_CHECK(for sys_errlist declaration, ac_cv_sys_errlist_def, [AC_TRY_COMPILE([ #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif],[char *s = sys_errlist[0]; return(*s);], ac_cv_decl_sys_errlist=yes, ac_cv_decl_sys_errlist=no) ]) if test "$ac_cv_decl_sys_errlist" = yes; then AC_DEFINE(HAVE_DECL_SYS_ERRLIST) fi fi AC_CACHE_CHECK(checking for long long, ac_cv_long_long, [ AC_TRY_COMPILE([ #include #include ], [printf("%d",sizeof(long long));], ac_cv_long_long=yes, ac_cv_long_long=no) ]) if test $ac_cv_long_long = yes; then AC_DEFINE(HAVE_LONG_LONG) fi AC_CACHE_CHECK(checking for long double, ac_cv_long_double, [ AC_TRY_COMPILE([ #include #include ], [printf("%d",sizeof(long double));], ac_cv_long_double=yes, ac_cv_long_double=no) ]) if test $ac_cv_long_double = yes; then AC_DEFINE(HAVE_LONG_DOUBLE) fi AC_CACHE_CHECK(checking for quad_t, ac_cv_quad_t, [ AC_TRY_COMPILE([ #include #include ], [printf("%d",sizeof(quad_t));], ac_cv_quad_t=yes, ac_cv_quad_t=no) ]) if test $ac_cv_quad_t = yes; then AC_DEFINE(HAVE_QUAD_T) fi NAME plp_snprintf, plp_vsnprintf - formatted output conversion SYNOPSIS #include #include int plp_snprintf(const char *format, size_t size, va_list ap); int plp_unsafe_snprintf(const char *format, size_t size, va_list ap); AKA snprintf and unsafe_snprintf in the documentation below int vsnprintf(char *str, size_t size, const char *format, va_list ap); int unsafe_vsnprintf(char *str, size_t size, const char *format, va_list ap); AKA vsnprintf and unsafe_vsnprintf in the documentation below (Multithreaded Safe) DESCRIPTION The printf() family of functions produces output according to a format as described below. Snprintf(), and vsnprintf() write to the character string str. These functions write the output under the control of a format string that specifies how subsequent arguments (or arguments accessed via the variable-length argument facilities of stdarg(3)) are converted for output. These functions return the number of characters printed (not including the trailing `\0' used to end output to strings). Snprintf() and vsnprintf() will write at most size-1 of the characters printed into the output string (the size'th character then gets the terminating `\0'); if the return value is greater than or equal to the size argument, the string was too short and some of the printed characters were discarded. The size or str may be given as zero to find out how many characters are needed; in this case, the str argument is ignored. By default, the snprintf function will not format control characters (except new line and tab) in strings. This is a safety feature that has proven to be extremely critical when using snprintf for secure applications and when debugging. If you MUST have control characters formatted or printed, then use the unsafe_snprintf() and unsafe_vsnprintf() and on your own head be the consequences. You have been warned. There is one exception to the comments above, and that is the "%c" (character) format. It brutally assumes that the user will have performed the necessary 'isprint()' or other checks and uses the integer value as a character. The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments. Each conversion specification is introduced by the character %. The arguments must correspond properly (after type promotion) with the conversion specifier. After the %, the following appear in sequence: o Zero or more of the following flags: - A zero `0' character specifying zero padding. For all conversions except n, the converted value is padded on the left with zeros rather than blanks. If a precision is given with a numeric conversion (d, i, o, u, i, x, and X), the `0' flag is ignored. - A negative field width flag `-' indicates the converted value is to be left adjusted on the field boundary. Except for n conversions, the converted value is padded on the right with blanks, rather than on the left with blanks or zeros. A `-' overrides a `0' if both are given. - A space, specifying that a blank should be left before a positive number produced by a signed conversion (d, e, E, f, g, G, or i). - A `+' character specifying that a sign always be placed before a number produced by a signed conversion. A `+' overrides a space if both are used. o An optional decimal digit string specifying a minimum field width. If the converted value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the left-adjustment flag has been given) to fill out the field width. o An optional precision, in the form of a period `.' followed by an optional digit string. If the digit string is omitted, the precision is taken as zero. This gives the minimum number of digits to appear for d, i, o, u, x, and X conversions, the number of digits to appear after the decimal-point for e, E, and f conversions, the maximum number of significant digits for g and G conversions, or the maximum number of characters to be printed from a string for s conversions. o The optional character h, specifying that a following d, i, o, u, x, or X conversion corresponds to a short int or unsigned short int argument, or that a following n conversion corresponds to a pointer to a short int argument. o The optional character l (ell) specifying that a following d, i, o, u, x, or X conversion applies to a pointer to a long int or unsigned long int argument, or that a following n conversion corresponds to a pointer to a long int argument. o The optional character q, specifying that a following d, i, o, u, x, or X conversion corresponds to a quad_t or u_quad_t argument, or that a following n conversion corresponds to a quad_t argument. This value is always printed in HEX notation. Tough. quad_t's are an OS system implementation, and should not be allowed. o The character L specifying that a following e, E, f, g, or G conversion corresponds to a long double argument. o A character that specifies the type of conversion to be applied. A field width or precision, or both, may be indicated by an asterisk `*' instead of a digit string. In this case, an int argument supplies the field width or precision. A negative field width is treated as a left adjustment flag followed by a positive field width; a negative precision is treated as though it were missing. The conversion specifiers and their meanings are: diouxX The int (or appropriate variant) argument is converted to signed decimal (d and i), unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal (x and X) notation. The letters abcdef are used for x conversions; the letters ABCDEF are used for X conversions. The precision, if any, gives the minimum number of digits that must appear; if the converted value requires fewer digits, it is padded on the left with zeros. eE The double argument is rounded and converted in the style [-]d.ddde+-dd where there is one digit before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero, no decimal-point character appears. An E conversion uses the letter E (rather than e) to introduce the exponent. The exponent always contains at least two digits; if the value is zero, the exponent is 00. f The double argument is rounded and converted to decimal notation in the style [-]ddd.ddd, where the number of digits after the decimal-point character is equal to the precision specification. If the precision is missing, it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. If a decimal point appears, at least one digit appears before it. g The double argument is converted in style f or e (or E for G conversions). The precision specifies the number of significant digits. If the precision is missing, 6 digits are given; if the precision is zero, it is treated as 1. Style e is used if the exponent from its conversion is less than -4 or greater than or equal to the precision. Trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit. c The int argument is converted to an unsigned char, and the resulting character is written. s The ``char *'' argument is expected to be a pointer to an array of character type (pointer to a string). Characters from the array are written up to (but not including) a terminating NUL character; if a precision is specified, no more than the number specified are written. If a precision is given, no null character need be present; if the precision is not specified, or is greater than the size of the array, the array must contain a terminating NUL character. % A `%' is written. No argument is converted. The complete conversion specification is `%%'. In no case does a non-existent or small field width cause truncation of a field; if the result of a conversion is wider than the field width, the field is expanded to contain the conversion result. EXAMPLES To print a date and time in the form `Sunday, July 3, 10:02', where weekday and month are pointers to strings: #include fprintf(stdout, "%s, %s %d, %.2d:%.2d\n", weekday, month, day, hour, min); To print pi to five decimal places: #include #include fprintf(stdout, "pi = %.5f\n", 4 * atan(1.0)); To allocate a 128 byte string and print into it: #include #include #include char *newfmt(const char *fmt, ...) { char *p; va_list ap; if ((p = malloc(128)) == NULL) return (NULL); va_start(ap, fmt); (void) vsnprintf(p, 128, fmt, ap); va_end(ap); return (p); } SEE ALSO printf(1), scanf(3) STANDARDS Turkey C Standardization and wimpy POSIX folks did not define snprintf or vsnprintf(). BUGS The conversion formats %D, %O, and %U are not standard and are provided only for backward compatibility. The effect of padding the %p format with zeros (either by the `0' flag or by specifying a precision), and the benign effect (i.e., none) of the `#' flag on %n and %p conversions, as well as other nonsensical combinations such as %Ld, are not standard; such combinations should be avoided. The typedef names quad_t and u_quad_t are infelicitous. */ #include "config.h" #include #include #include #include #if defined(HAVE_STRING_H) # include #endif #if defined(HAVE_STRINGS_H) # include #endif #if defined(HAVE_ERRNO_H) #include #endif /* * For testing, define these values */ #if 0 #define HAVE_STDARG_H 1 #define TEST 1 #define HAVE_QUAD_T 1 #endif /**** ENDINCLUDE ****/ /************************************************* * KEEP THIS STRING - MODIFY AT THE END WITH YOUR REVISIONS * i.e. - the LOCAL REVISIONS part is for your use *************************************************/ static const char *const _id = "plp_snprintf V2000.08.18 Copyright Patrick Powell 1988-2000 " " - lprng "; /* varargs declarations: */ # undef HAVE_STDARGS /* let's hope that works everywhere (mj) */ # undef VA_LOCAL_DECL # undef VA_START # undef VA_SHIFT # undef VA_END #if defined(HAVE_STDARG_H) # include # define HAVE_STDARGS /* let's hope that works everywhere (mj) */ # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap, f) # define VA_SHIFT(v,t) ; /* no-op for ANSI */ # define VA_END va_end(ap) #else # if defined(HAVE_VARARGS_H) # include # undef HAVE_STDARGS # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap) /* f is ignored! */ # define VA_SHIFT(v,t) v = va_arg(ap,t) # define VA_END va_end(ap) # else XX ** NO VARARGS ** XX # endif #endif union value { #if defined(HAVE_QUAD_T) quad_t qvalue; #endif #if defined(HAVE_LONG_LONG) long long value; #else long value; #endif double dvalue; }; #ifdef __GNUC__ # define PRINTFATTR(fmtofs,dotsofs) __attribute__ ((format (printf, fmtofs, dotsofs))) #else # define PRINTFATTR(fmtofs,dotsofs) #endif #include "plp_snprintf.h" #undef CVAL #define CVAL(s) (*((unsigned char *)s)) static char * plp_Errormsg ( int err ); static void dopr( int visible_control, char **buffer, int *left, const char *format, va_list args ); static void fmtstr( int visible_control, char **buffer, int *left, const char *value, int ljust, int len, int precision ); static void fmtnum( char **buffer, int *left, union value *value, int base, int dosign, int ljust, int len, int zpad ); #if defined(HAVE_QUAD_T) static void fmtquad( char **buffer, int *left, union value *value, int base, int dosign, int ljust, int len, int zpad, int precision ); #endif static void fmtdouble( char **bufer, int *left, int fmt, double value, int ljust, int len, int zpad, int precision ); static void dostr( char **buffer, int *left, const char *str ); static void dopr_outch( char **buffer, int *left, int c ); /* VARARGS3 */ #ifdef HAVE_STDARGS int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) #else int plp_vsnprintf(char *str, size_t count, const char *fmt, va_list args) #endif { int left; char *buffer; if( (int)count < 0 ) count = 0; left = count; if( count == 0 ) str = 0; buffer = str; dopr( 1, &buffer, &left, fmt, args ); /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", (int)str, (int)buffer, count, left ); */ if( str && count > 0 ){ if( left > 0 ){ str[count-left] = 0; } else { str[count-1] = 0; } } return(count - left); } /* VARARGS3 */ #ifdef HAVE_STDARGS int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) #else int plp_unsafe_vsnprintf(char *str, size_t count, const char *fmt, va_list args) #endif { int left; char *buffer; if( (int)count < 0 ) count = 0; left = count; if( count == 0 ) str = 0; buffer = str; dopr( 0, &buffer, &left, fmt, args ); /* fprintf(stderr,"str 0x%x, buffer 0x%x, count %d, left %d\n", (int)str, (int)buffer, count, left ); */ if( str && count > 0 ){ if( left > 0 ){ str[count-left] = 0; } else { str[count-1] = 0; } } return(count - left); } /* VARARGS3 */ #ifdef HAVE_STDARGS int plp_snprintf (char *str,size_t count,const char *fmt,...) #else int plp_snprintf (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *str; size_t count; char *fmt; #endif int n = 0; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); VA_SHIFT (fmt, char *); n = plp_vsnprintf ( str, count, fmt, ap); VA_END; return( n ); } /* VARARGS3 */ #ifdef HAVE_STDARGS int plp_unsafe_snprintf (char *str,size_t count,const char *fmt,...) #else int plp_unsafe_snprintf (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *str; size_t count; char *fmt; #endif int n = 0; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (str, char *); VA_SHIFT (count, size_t ); VA_SHIFT (fmt, char *); n = plp_unsafe_vsnprintf ( str, count, fmt, ap); VA_END; return( n ); } static void dopr( int visible_control, char **buffer, int *left, const char *format, va_list args ) { int ch; union value value; int longflag = 0; int quadflag = 0; char *strvalue; int ljust; int len; int zpad; int precision; int set_precision; double dval; int err = errno; int base = 0; int signed_val = 0; while( (ch = *format++) ){ switch( ch ){ case '%': longflag = quadflag = ljust = len = zpad = base = signed_val = 0; precision = -1; set_precision = 0; nextch: ch = *format++; switch( ch ){ case 0: dostr( buffer, left, "**end of format**" ); return; case '-': ljust = 1; goto nextch; case '.': set_precision = 1; precision = 0; goto nextch; case '*': if( set_precision ){ precision = va_arg( args, int ); } else { len = va_arg( args, int ); } goto nextch; case '0': /* set zero padding if len not set */ if(len==0 && set_precision == 0 ) zpad = '0'; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if( set_precision ){ precision = precision*10 + ch - '0'; } else { len = len*10 + ch - '0'; } goto nextch; case 'l': ++longflag; goto nextch; case 'q': #if !defined( HAVE_QUAD_T ) dostr( buffer, left, "*no quad_t support *"); return; #else quadflag = 1; goto nextch; #endif case 'u': case 'U': if( base == 0 ){ base = 10; signed_val = 0; } case 'o': case 'O': if( base == 0 ){ base = 8; signed_val = 0; } case 'd': case 'D': if( base == 0 ){ base = 10; signed_val = 1; } case 'x': if( base == 0 ){ base = 16; signed_val = 0; } case 'X': if( base == 0 ){ base = -16; signed_val = 0; } #if defined( HAVE_QUAD_T ) if( quadflag ){ value.qvalue = va_arg( args, quad_t ); fmtquad( buffer, left, &value,base,signed_val, ljust, len, zpad, precision ); break; } else #endif if( longflag > 1 ){ #if defined(HAVE_LONG_LONG) if( signed_val ){ value.value = va_arg( args, long long ); } else { value.value = va_arg( args, unsigned long long ); } #else if( signed_val ){ value.value = va_arg( args, long ); } else { value.value = va_arg( args, unsigned long ); } #endif } else if( longflag ){ if( signed_val ){ value.value = va_arg( args, long ); } else { value.value = va_arg( args, unsigned long ); } } else { if( signed_val ){ value.value = va_arg( args, int ); } else { value.value = va_arg( args, unsigned int ); } } fmtnum( buffer, left, &value,base,signed_val, ljust, len, zpad ); break; case 's': strvalue = va_arg( args, char *); fmtstr( visible_control, buffer, left, strvalue,ljust,len, precision ); break; case 'c': ch = va_arg( args, int ); { char b[2]; b[0] = ch; b[1] = 0; fmtstr( 0, buffer, left, b,ljust,len, precision ); } break; case 'f': case 'g': case 'e': dval = va_arg( args, double ); fmtdouble( buffer, left, ch, dval,ljust,len, zpad, precision ); break; case 'm': fmtstr( visible_control, buffer, left, plp_Errormsg(err),ljust,len, precision ); break; case '%': dopr_outch( buffer, left, ch ); continue; default: dostr( buffer, left, "???????" ); } longflag = 0; break; default: dopr_outch( buffer, left, ch ); break; } } } /* * Format '%[-]len[.precision]s' * - = left justify (ljust) * len = minimum length * precision = numbers of chars in string to use */ static void fmtstr( int visible_control, char **buffer, int *left, const char *value, int ljust, int len, int precision ) { int padlen, strlenv, i, c; /* amount to pad */ if( value == 0 ){ value = ""; } /* cheap strlen so you do not have library call */ for( strlenv = i = 0; (c=CVAL(value+i)); ++i ){ if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ ++strlenv; } ++strlenv; } if( precision > 0 && strlenv > precision ){ strlenv = precision; } padlen = len - strlenv; if( padlen < 0 ) padlen = 0; if( ljust ) padlen = -padlen; while( padlen > 0 ) { dopr_outch( buffer, left, ' ' ); --padlen; } /* output characters */ for( i = 0; i < strlenv && (c = CVAL(value+i)); ++i ){ if( visible_control && iscntrl( c ) && c != '\t' && c != '\n' ){ dopr_outch(buffer, left, '^'); c = ('@' | (c & 0x1F)); } dopr_outch(buffer, left, c); } while( padlen < 0 ) { dopr_outch( buffer, left, ' ' ); ++padlen; } } static void fmtnum( char **buffer, int *left, union value *value, int base, int dosign, int ljust, int len, int zpad ) { int signvalue = 0; #if defined(HAVE_LONG_LONG) unsigned long long uvalue; #else unsigned long uvalue; #endif char convert[sizeof( union value) * 8 + 16]; int place = 0; int padlen = 0; /* amount to pad */ int caps = 0; /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", value, base, dosign, ljust, len, zpad );/ **/ uvalue = value->value; if( dosign ){ if( value->value < 0 ) { signvalue = '-'; uvalue = -value->value; } } if( base < 0 ){ caps = 1; base = -base; } do{ convert[place++] = (caps? "0123456789ABCDEF":"0123456789abcdef") [uvalue % (unsigned)base ]; uvalue = (uvalue / (unsigned)base ); }while(uvalue); convert[place] = 0; padlen = len - place; if( padlen < 0 ) padlen = 0; if( ljust ) padlen = -padlen; /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", convert,place,signvalue,padlen); / **/ if( zpad && padlen > 0 ){ if( signvalue ){ dopr_outch( buffer, left, signvalue ); --padlen; signvalue = 0; } while( padlen > 0 ){ dopr_outch( buffer, left, zpad ); --padlen; } } while( padlen > 0 ) { dopr_outch( buffer, left, ' ' ); --padlen; } if( signvalue ) dopr_outch( buffer, left, signvalue ); while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); while( padlen < 0 ){ dopr_outch( buffer, left, ' ' ); ++padlen; } } #if defined(HAVE_QUAD_T) static void fmtquad( char **buffer, int *left, union value *value, int base, int dosign, int ljust, int len, int zpad, int precision ) { int signvalue = 0; int place = 0; int padlen = 0; /* amount to pad */ int caps = 0; int i, c; union { quad_t qvalue; unsigned char qconvert[sizeof(quad_t)]; } vvalue; char convert[2*sizeof(quad_t)+1]; /* fprintf(stderr,"value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n", value, base, dosign, ljust, len, zpad );/ **/ vvalue.qvalue = value->qvalue; if( base < 0 ){ caps = 1; } for( i = 0; i < (int)sizeof(quad_t); ++i ){ c = vvalue.qconvert[i]; convert[2*i] = (caps? "0123456789ABCDEF":"0123456789abcdef")[ (c >> 4) & 0xF]; convert[2*i+1] = (caps? "0123456789ABCDEF":"0123456789abcdef")[ c & 0xF]; } convert[2*i] = 0; place = strlen(convert); padlen = len - place; if( padlen < 0 ) padlen = 0; if( ljust ) padlen = -padlen; /* fprintf( stderr, "str '%s', place %d, sign %c, padlen %d\n", convert,place,signvalue,padlen); / **/ if( zpad && padlen > 0 ){ if( signvalue ){ dopr_outch( buffer, left, signvalue ); --padlen; signvalue = 0; } while( padlen > 0 ){ dopr_outch( buffer, left, zpad ); --padlen; } } while( padlen > 0 ) { dopr_outch( buffer, left, ' ' ); --padlen; } if( signvalue ) dopr_outch( buffer, left, signvalue ); while( place > 0 ) dopr_outch( buffer, left, convert[--place] ); while( padlen < 0 ){ dopr_outch( buffer, left, ' ' ); ++padlen; } } #endif static void mystrcat(char *dest, const char *src ) { if( dest && src ){ dest += strlen(dest); strcpy(dest,src); } } static void fmtdouble( char **buffer, int *left, int fmt, double value, int ljust, int len, int zpad, int precision ) { char convert[sizeof( union value) * 8 + 512]; char formatstr[128]; /* fprintf(stderr,"len %d, precision %d\n", len, precision ); */ if( len > 255 ){ len = 255; } if( precision > 255 ){ precision = 255; } if( precision >= 0 && len > 0 && precision > len ) precision = len; strcpy( formatstr, "%" ); /* 1 */ if( ljust ) mystrcat(formatstr, "-" ); /* 1 */ if( zpad ) mystrcat(formatstr, "0" ); /* 1 */ if( len >= 0 ){ sprintf( formatstr+strlen(formatstr), "%d", len ); /* 3 */ } if( precision >= 0 ){ sprintf( formatstr+strlen(formatstr), ".%d", precision ); /* 3 */ } /* format string will be at most 10 chars long ... */ sprintf( formatstr+strlen(formatstr), "%c", fmt ); /* this is easier than trying to do the portable dtostr */ /* fprintf(stderr,"format string '%s'\n", formatstr); */ sprintf( convert, formatstr, value ); dostr( buffer, left, convert ); } static void dostr( char **buffer, int *left, const char *str ) { if(str)while(*str) dopr_outch( buffer, left, *str++ ); } static void dopr_outch( char **buffer, int *left, int c ) { if( *left > 0 ){ *(*buffer)++ = c; } *left -= 1; } /**************************************************************************** * static char *plp_errormsg( int err ) * returns a printable form of the * errormessage corresponding to the valie of err. * This is the poor man's version of sperror(), not available on all systems * Patrick Powell Tue Apr 11 08:05:05 PDT 1995 ****************************************************************************/ /****************************************************************************/ #if !defined(HAVE_STRERROR) # undef num_errors # if defined(HAVE_SYS_ERRLIST) # if !defined(HAVE_DECL_SYS_ERRLIST) extern const char *const sys_errlist[]; # endif # if defined(HAVE_SYS_NERR) # if !defined(HAVE_DECL_SYS_NERR) extern int sys_nerr; # endif # define num_errors (sys_nerr) # endif # endif # if !defined(num_errors) # define num_errors (-1) /* always use "errno=%d" */ # endif #endif static char * plp_Errormsg ( int err) { char *cp; #if defined(HAVE_STRERROR) cp = (void *)strerror(err); #else # if defined(HAVE_SYS_ERRLIST) if (err >= 0 && err < num_errors) { cp = (void *)sys_errlist[err]; } else # endif { (void) sprintf (buffer, "errno=%d", err); cp = buffer; } #endif return (cp); } #if defined(TEST) #include int main( void ) { char buffer[128]; char *t; char *test1 = "01234"; int n; errno = 1; buffer[0] = 0; n = plp_snprintf( buffer, 0, (t="test")); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t="errno '%m'")); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%-12s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%-12.2s"), test1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%g"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.1g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.3g"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%0*d"), 6, 1 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); #if defined(HAVE_LONG_LONG) n = plp_snprintf( buffer, sizeof(buffer), (t = "%llx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%llx"), (long long)1, (long long)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%qx"), 1, 2, 3, 4 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%qx"), (quad_t)1, (quad_t)2 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); #endif n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), (char *)(0x01234567), (char *)0x89ABCDEF, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "0%x, 0%x"), t, 0, 0, 0, 0); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.2345 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%12.2f"), 1.25 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%0.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%1.0f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%1.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); n = plp_snprintf( buffer, sizeof(buffer), (t = "%5.5f"), 1.0 ); printf( "[%d] %s = '%s'\n", n, t, buffer ); return(0); } #endif lprng-3.8.B/src/common/utilities.c0000644000131400013140000011506311531672132014044 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "utilities.h" #include "getopt.h" #include "errorcodes.h" /**** ENDINCLUDE ****/ /* * Time_str: return "cleaned up" ctime() string... * * in YY/MO/DY/hr:mn:sc * Thu Aug 4 12:34:17 BST 1994 -> 12:34:17 */ char *Time_str(int shortform, time_t t) { static char buffer[99]; struct tm *tmptr; struct timeval tv; tv.tv_usec = 0; if( t == 0 ){ if( gettimeofday( &tv, 0 ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_ERR, "Time_str: gettimeofday failed"); } t = tv.tv_sec; } tmptr = localtime( &t ); if( shortform && Full_time_DYN == 0 ){ plp_snprintf( buffer, sizeof(buffer), "%02d:%02d:%02d.%03d", tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, (int)(tv.tv_usec/1000) ); } else { plp_snprintf( buffer, sizeof(buffer), "%d-%02d-%02d-%02d:%02d:%02d.%03d", tmptr->tm_year+1900, tmptr->tm_mon+1, tmptr->tm_mday, tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, (int)(tv.tv_usec/1000) ); } /* now format the time */ if( Ms_time_resolution_DYN == 0 ){ char *s; if( ( s = safestrrchr( buffer, '.' )) ){ *s = 0; } } return( buffer ); } /* * Pretty_time: return "cleaned up" ctime() string... * * in YY/MO/DY/hr:mn:sc * Thu Aug 4 12:34:17 BST 1994 -> 12:34:17 */ char *Pretty_time( time_t t ) { static char buffer[99]; struct tm *tmptr; struct timeval tv; tv.tv_usec = 0; if( t == 0 ){ if( gettimeofday( &tv, 0 ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_ERR, "Time_str: gettimeofday failed"); } t = tv.tv_sec; } tmptr = localtime( &t ); strftime( buffer, sizeof(buffer), "%b %d %H:%M:%S %Y", tmptr ); return( buffer ); } time_t Convert_to_time_t( char *str ) { time_t t = 0; if(str) t = strtol(str,0,0); DEBUG5("Convert_to_time_t: %s = %ld", str, (long)t ); return(t); } /*************************************************************************** * Use for copyright printing ***************************************************************************/ void Printlist( const char **m, int fd ) { if( m ){ for( ; *m; ++m ){ Write_fd_str(fd, *m); Write_fd_str(fd,"\n"); } } } /*************************************************************************** * Utility functions: write a string to a fd (bombproof) * write a char array to a fd (fairly bombproof) * Note that there is a race condition here that is unavoidable; * The problem is that there is no portable way to disable signals; * post an alarm; * There is a solution that involves forking a subprocess, but this * is so painful as to be not worth it. Most of the timeouts * in the LPR stuff are in the order of minutes, so this is not a problem. * * Note: we do the write first and then check for timeout. ***************************************************************************/ /* * Write_fd_len( fd, msg, len ) * returns: * 0 - success * <0 - failure */ int Write_fd_len( int fd, const char *msg, int len ) { int i; i = len; while( len > 0 && (i = write( fd, msg, len ) ) >= 0 ){ len -= i, msg += i; } return( (i < 0) ? -1 : 0 ); } /* * Write_fd_len_timeout( timeout, fd, msg, len ) * returns: * 0 - success * <0 - failure */ int Write_fd_len_timeout( int timeout, int fd, const char *msg, int len ) { int i; if( timeout > 0 ){ if( Set_timeout() ){ Set_timeout_alarm( timeout ); i = Write_fd_len( fd, msg, len ); } else { i = -1; } Clear_timeout(); } else { i = Write_fd_len( fd, msg, len ); } return( i < 0 ? -1 : 0 ); } /* * Write_fd_str_timeout( fd, msg ) * returns: * 0 - success * <0 - failure */ int Write_fd_str( int fd, const char *msg ) { if( msg && *msg ){ return( Write_fd_len( fd, msg, safestrlen(msg) )); } return( 0 ); } /* * Write_fd_str_timeout( timeout, fd, msg ) * returns: * 0 - success * <0 - failure */ int Write_fd_str_timeout( int timeout, int fd, const char *msg ) { if( msg && *msg ){ return( Write_fd_len_timeout( timeout, fd, msg, safestrlen(msg) ) ); } return( 0 ); } /* * Read_fd_len_timeout( timeout, fd, msg, len ) * returns: * n>0 - read n * 0 - EOF * <0 - failure */ int Read_fd_len_timeout( int timeout, int fd, char *msg, int len ) { int i; if( timeout > 0 ){ if( Set_timeout() ){ Set_timeout_alarm( timeout ); i = ok_read( fd, msg, len ); } else { i = -1; errno = EINTR; } Clear_timeout(); } else { i = ok_read( fd, msg, len ); } return( i ); } /************************************************************** * * signal handling: * SIGALRM should be the only signal that terminates system calls; * all other signals should NOT terminate them. * This signal() emulation function attepts to do just that. * (Derived from Advanced Programming in the UNIX Environment, Stevens, 1992) * **************************************************************/ /* solaris 2.3 note: don't compile this with "gcc -ansi -pedantic"; * due to a bug in the header file, struct sigaction doesn't * get declared. :( */ /* plp_signal will set flags so that signal handlers will continue * Note that in Solaris, you MUST reinstall the * signal hanlders in the signal handler! The default action is * to try to restart the system call - note that the code should * be written so that you check for error returns from a system call * and continue if no error. * WARNING: read/write may terminate early? who knows... * See plp_signal_break. */ plp_sigfunc_t plp_signal (int signo, plp_sigfunc_t func) { #ifdef HAVE_SIGACTION struct sigaction act, oact; act.sa_handler = func; (void) sigemptyset (&act.sa_mask); act.sa_flags = 0; # ifdef SA_RESTART act.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */ # endif if (sigaction (signo, &act, &oact) < 0) { return (SIG_ERR); } return (plp_sigfunc_t) oact.sa_handler; #else /* sigaction is not supported. Just set the signals. */ return (plp_sigfunc_t)signal (signo, func); #endif } /* plp_signal_break is similar to plp_signal, but will cause * TERMINATION of a system call if possible. This allows * you to force a signal to cause termination of a system * wait or other action. * WARNING: read/write may terminate early? who knows... so * beware if you are expecting this and don't believe that * you got an entire buffer read/written. */ plp_sigfunc_t plp_signal_break (int signo, plp_sigfunc_t func) { #ifdef HAVE_SIGACTION struct sigaction act, oact; act.sa_handler = func; (void) sigemptyset (&act.sa_mask); act.sa_flags = 0; # ifdef SA_INTERRUPT act.sa_flags |= SA_INTERRUPT; /* SunOS */ # endif if (sigaction (signo, &act, &oact) < 0) { return (SIG_ERR); } return (plp_sigfunc_t) oact.sa_handler; #else /* sigaction is not supported. Just set the signals. */ return (plp_sigfunc_t)signal (signo, func); #endif } /**************************************************************/ void plp_block_all_signals ( plp_block_mask *oblock ) { #ifdef HAVE_SIGPROCMASK sigset_t block; (void) sigfillset (&block); /* block all signals */ if (sigprocmask (SIG_SETMASK, &block, oblock) < 0) logerr_die(LOG_ERR, "plp_block_all_signals: sigprocmask failed"); #else *oblock = sigblock( ~0 ); /* block all signals */ #endif } void plp_unblock_all_signals ( plp_block_mask *oblock ) { #ifdef HAVE_SIGPROCMASK sigset_t block; (void) sigemptyset (&block); /* block all signals */ if (sigprocmask (SIG_SETMASK, &block, oblock) < 0) logerr_die(LOG_ERR, "plp_unblock_all_signals: sigprocmask failed"); #else *oblock = sigblock( 0 ); /* unblock all signals */ #endif } void plp_set_signal_mask ( plp_block_mask *in, plp_block_mask *out ) { #ifdef HAVE_SIGPROCMASK if (sigprocmask (SIG_SETMASK, in, out ) < 0) logerr_die(LOG_ERR, "plp_set_signal_mask: sigprocmask failed"); #else sigset_t block; if( in ) block = sigsetmask( *in ); else block = sigblock( 0 ); if( out ) *out = block; #endif } void plp_unblock_one_signal ( int sig, plp_block_mask *oblock ) { #ifdef HAVE_SIGPROCMASK sigset_t block; (void) sigemptyset (&block); /* clear out signals */ (void) sigaddset (&block, sig ); /* clear out signals */ if (sigprocmask (SIG_UNBLOCK, &block, oblock ) < 0) logerr_die(LOG_ERR, "plp_unblock_one_signal: sigprocmask failed"); #else *oblock = sigblock( 0 ); (void) sigsetmask (*oblock & ~ sigmask(sig) ); #endif } void plp_block_one_signal( int sig, plp_block_mask *oblock ) { #ifdef HAVE_SIGPROCMASK sigset_t block; (void) sigemptyset (&block); /* clear out signals */ (void) sigaddset (&block, sig ); /* clear out signals */ if (sigprocmask (SIG_BLOCK, &block, oblock ) < 0) logerr_die(LOG_ERR, "plp_block_one_signal: sigprocmask failed"); #else *oblock = sigblock( sigmask( sig ) ); #endif } void plp_sigpause( void ) { #ifdef HAVE_SIGPROCMASK sigset_t block; (void) sigemptyset (&block); /* clear out signals */ (void) sigsuspend( &block ); #else (void)sigpause( 0 ); #endif } /************************************************************** * Bombproof versions of strcasecmp() and strncasecmp(); **************************************************************/ /* case insensitive compare for OS without it */ int safestrcasecmp (const char *s1, const char *s2) { int c1, c2, d = 0; if( (s1 == s2) ) return(0); if( (s1 == 0 ) && s2 ) return( -1 ); if( s1 && (s2 == 0 ) ) return( 1 ); for (;;) { c1 = *((unsigned char *)s1); s1++; c2 = *((unsigned char *)s2); s2++; if( isupper(c1) ) c1 = tolower(c1); if( isupper(c2) ) c2 = tolower(c2); if( (d = (c1 - c2 )) || c1 == 0 ) break; } return( d ); } /* case insensitive compare for OS without it */ int safestrncasecmp (const char *s1, const char *s2, int len ) { int c1, c2, d = 0; if( (s1 == s2) && s1 == 0 ) return(0); if( (s1 == 0 ) && s2 ) return( -1 ); if( s1 && (s2 == 0 ) ) return( 1 ); for (;len>0;--len){ c1 = *((unsigned char *)s1); s1++; c2 = *((unsigned char *)s2); s2++; if( isupper(c1) ) c1 = tolower(c1); if( isupper(c2) ) c2 = tolower(c2); if( (d = (c1 - c2 )) || c1 == 0 ) return(d); } return( 0 ); } /* perform safe comparison, even with null pointers */ int safestrcmp( const char *s1, const char *s2 ) { if( (s1 == s2) ) return(0); if( (s1 == 0 ) && s2 ) return( -1 ); if( s1 && (s2 == 0 ) ) return( 1 ); return( strcmp(s1, s2) ); } /* perform safe comparison, even with null pointers */ int safestrlen( const char *s1 ) { if( s1 ) return(strlen(s1)); return(0); } /* perform safe comparison, even with null pointers */ int safestrncmp( const char *s1, const char *s2, int len ) { if( (s1 == s2) && s1 == 0 ) return(0); if( (s1 == 0 ) && s2 ) return( -1 ); if( s1 && (s2 == 0 ) ) return( 1 ); return( strncmp(s1, s2, len) ); } /* perform safe strchr, even with null pointers */ char *safestrchr( const char *s1, int c ) { if( s1 ) return( strchr( s1, c ) ); return( 0 ); } /* perform safe strrchr, even with null pointers */ char *safestrrchr( const char *s1, int c ) { if( s1 ) return( strrchr( s1, c ) ); return( 0 ); } /* perform safe strchr, even with null pointers */ char *safestrpbrk( const char *s1, const char *s2 ) { if( s1 && s2 ) return( strpbrk( s1, s2 ) ); return( 0 ); } /*************************************************************************** * plp_usleep() with select - simple minded way to avoid problems ***************************************************************************/ int plp_usleep( int i ) { struct timeval t; DEBUG3("plp_usleep: starting usleep %d", i ); if( i > 0 ){ memset( &t, 0, sizeof(t) ); t.tv_usec = i%1000000; t.tv_sec = i/1000000; i = select( 0, NULL, NULL, NULL, &t ); DEBUG3("plp_usleep: select done, status %d", i ); } return( i ); } /*************************************************************************** * plp_sleep() with select - simple minded way to avoid problems ***************************************************************************/ int plp_sleep( int i ) { struct timeval t; DEBUG3("plp_sleep: starting sleep %d", i ); if( i > 0 ){ memset( &t, 0, sizeof(t) ); t.tv_sec = i; i = select( 0, NULL, NULL, NULL, &t ); DEBUG3("plp_sleep: select done, status %d", i ); } return( i ); } /*************************************************************************** * int get_max_processes() * get the maximum number of processes allowed ***************************************************************************/ int Get_max_servers( void ) { int n = 0; /* We need some sort of limit here */ #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NPROC) struct rlimit pcount; if( getrlimit(RLIMIT_NPROC, &pcount) == -1 ){ fatal(LOG_ERR, "Get_max_servers: getrlimit failed" ); } n = pcount.rlim_cur; #ifdef RLIMIT_INFINITY if( pcount.rlim_cur == RLIM_INFINITY ){ n = Max_servers_active_DYN; DEBUG1("Get_max_servers: using %d", n ); } #endif DEBUG1("Get_max_servers: getrlimit returns %d", n ); #else # if defined(HAVE_SYSCONF) && defined(_SC_CHILD_MAX) if( n == 0 && (n = sysconf(_SC_CHILD_MAX)) < 0 ){ fatal(LOG_ERR, "Get_max_servers: sysconf failed" ); } DEBUG1("Get_max_servers: sysconf returns %d", n ); # else # if defined(CHILD_MAX) n = CHILD_MAX; DEBUG1("Get_max_servers: CHILD_MAX %d", n ); # else n = 0; DEBUG1("Get_max_servers: default %d", n ); # endif # endif #endif n = n/4; if(( n > 0 && n > Max_servers_active_DYN) || (n <= 0 && Max_servers_active_DYN) ){ n = Max_servers_active_DYN; } if( n <= 0 ) n = 32; DEBUG1("Get_max_servers: returning %d", n ); return( n ); } /*************************************************************************** * int Get_max_fd() * get the maximum number of file descriptors allowed ***************************************************************************/ int Get_max_fd( void ) { int n = 0; /* We need some sort of limit here */ #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE) struct rlimit pcount; if( getrlimit(RLIMIT_NOFILE, &pcount) == -1 ){ fatal(LOG_ERR, "Get_max_fd: getrlimit failed" ); } n = pcount.rlim_cur; DEBUG4("Get_max_fd: getrlimit returns %d", n ); #else # if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) if( n == 0 && (n = sysconf(_SC_OPEN_MAX)) < 0 ){ fatal(LOG_ERR, "Get_max_servers: sysconf failed" ); } DEBUG4("Get_max_fd: sysconf returns %d", n ); # else n = 20; DEBUG4("Get_max_fd: using default %d", n ); # endif #endif if( n <= 0 || n > 10240 ){ /* we have some systems that will return a VERY * large or negative number for unlimited FD's. Well, we * don't want to use a large number here. So we * will make it a small number. The actual number of * file descriptors open by processes is VERY conservative. */ n = 256; } DEBUG1("Get_max_fd: returning %d", n ); return( n ); } char *Brk_check_size( void ) { static char b[128]; static char* Top_of_mem; /* top of allocated memory */ char *s = sbrk(0); int v = s - Top_of_mem; if( Top_of_mem == 0 ){ plp_snprintf(b, sizeof(b), "BRK: initial value 0x%lx", Cast_ptr_to_long(s) ); } else { plp_snprintf(b, sizeof(b), "BRK: new value 0x%lx, increment %d", Cast_ptr_to_long(s), v ); } Top_of_mem = s; return(b); } char *mystrncat( char *s1, const char *s2, int len ) { int size; s1[len-1] = 0; size = safestrlen( s1 ); if( s2 && len - size > 0 ){ strncpy( s1+size, s2, len - size ); } return( s1 ); } char *mystrncpy( char *s1, const char *s2, int len ) { s1[0] = 0; if( s2 && len-1 > 0 ){ strncpy( s1, s2, len-1 ); s1[len-1] = 0; } return( s1 ); } /* * Set_non_block_io(fd) * Set_block_io(fd) * Set blocking or non-blocking IO * Dies if unsuccessful * Get_nonblock_io(fd) * Returns O_NONBLOCK flag value */ int Get_nonblock_io( int fd ) { int mask; /* we set IO to non-blocking on fd */ if( (mask = fcntl( fd, F_GETFL, 0 ) ) == -1 ){ return(-1); } mask &= O_NONBLOCK; return( mask ); } int Set_nonblock_io( int fd ) { int mask; /* we set IO to non-blocking on fd */ if( (mask = fcntl( fd, F_GETFL, 0 ) ) == -1 ){ return(-1); } mask |= O_NONBLOCK; if( (mask = fcntl( fd, F_SETFL, mask ) ) == -1 ){ return(-1); } return(0); } int Set_block_io( int fd ) { int mask; /* we set IO to blocking on fd */ if( (mask = fcntl( fd, F_GETFL, 0 ) ) == -1 ){ return(-1); } mask &= ~O_NONBLOCK; if( (mask = fcntl( fd, F_SETFL, mask ) ) == -1 ){ return(-1); } return(0); } /* * Read_write_timeout * int readfd, char *inbuffer, int maxinlen - * read data from this fd into this buffer before this timeout * int *readlen - reports number of bytes read * int writefd, char **outbuffer, int *outlen - * **outbuffer and **outlen are updated after write * write data from to this fd from this buffer before this timeout * int timeout * > 0 - wait total of this long * 0 - wait indefinitely * -1 - do not wait * Returns: * **outbuffer, *outlen updated * 0 - success * JRDERR - IO error on output * JTIMEOUT - Timeout * JWRERR - IO error on input */ int Read_write_timeout( int readfd, char *inbuffer, int maxinlen, int *readlen, int writefd, char **outbuffer, int *outlen, int timeout ) { time_t start_t, current_t; int elapsed, m, err, done, retval; struct timeval timeval, *tp; fd_set readfds, writefds; /* for select() */ struct stat statb; DEBUG4( "Read_write_timeout: read(fd %d, buffer 0x%lx, maxinlen %d, readlen 0x%lx->%d", readfd, Cast_ptr_to_long(inbuffer), maxinlen, Cast_ptr_to_long(readlen), readlen?*readlen:0 ); DEBUG4( "Read_write_timeout: write(fd %d, buffer 0x%lx->0x%lx, len 0x%lx->%d, timeout %d)", writefd, Cast_ptr_to_long(outbuffer), Cast_ptr_to_long(outbuffer?*outbuffer:0), Cast_ptr_to_long(outlen), outlen?*outlen:0, timeout ); retval = done = 0; time( &start_t ); if( *outlen == 0 ) return( retval ); if( readfd > 0 ){ if( fstat( readfd, &statb ) ){ Errorcode = JABORT; fatal(LOG_ERR, "Read_write_timeout: readfd %d closed", readfd ); } Set_nonblock_io( readfd ); } else { Errorcode = JABORT; fatal(LOG_ERR, "Read_write_timeout: no readfd %d", readfd ); } if( writefd > 0 ){ if( fstat( writefd, &statb ) ){ Errorcode = JABORT; fatal(LOG_ERR, "Read_write_timeout: writefd %d closed", writefd ); } Set_nonblock_io( writefd ); } else { Errorcode = JABORT; fatal(LOG_ERR, "Read_write_timeout: no write %d", writefd ); } while(!done){ tp = 0; memset( &timeval, 0, sizeof(timeval) ); m = 0; if( timeout > 0 ){ time( ¤t_t ); elapsed = current_t - start_t; if( timeout > 0 && elapsed >= timeout ){ break; } timeval.tv_sec = m = timeout - elapsed; tp = &timeval; DEBUG4("Read_write_timeout: timeout now %d", m ); } else if( timeout < 0 ){ /* we simply poll once */ tp = &timeval; } FD_ZERO( &writefds ); FD_ZERO( &readfds ); m = 0; FD_SET( writefd, &writefds ); if( m <= writefd ) m = writefd+1; FD_SET( readfd, &readfds ); if( m <= readfd ) m = readfd+1; errno = 0; DEBUG4("Read_write_timeout: starting select" ); m = select( m, &readfds, &writefds, NULL, tp ); err = errno; DEBUG4("Read_write_timeout: select returned %d, errno '%s'", m, Errormsg(err) ); if( m < 0 ){ if( err != EINTR ){ logerr(LOG_INFO, "Read_write_timeout: select returned %d, errno '%s'", m, Errormsg(err) ); retval = JTIMEOUT; done = 1; } } else if( m == 0 ){ /* timeout */ retval = JTIMEOUT; done = 1; } else { if( FD_ISSET( readfd, &readfds ) ){ DEBUG4("Read_write_timeout: read possible on fd %d", readfd ); m = ok_read( readfd, inbuffer, maxinlen ); DEBUG4("Read_write_timeout: read() returned %d", m ); if( readlen ) *readlen = m; /* caller leaves space for this */ if( m >= 0 ) inbuffer[m] = 0; if( m < 0 ) retval = JRDERR; done = 1; } if( FD_ISSET( writefd, &writefds ) ){ DEBUG4("Read_write_timeout: write possible on fd %d", writefd ); Set_nonblock_io( writefd ); m = write( writefd, *outbuffer, *outlen ); err = errno; Set_block_io( writefd ); DEBUG4("Read_write_timeout: wrote %d", m ); if( m < 0 ){ /* we have EOF on the file descriptor */ retval = JWRERR; done = 1; } else { *outlen -= m; *outbuffer += m; if( *outlen == 0 ){ done = 1; } } errno = err; } } } err = errno; errno = err; return( retval ); } /*************************************************************************** * Set up alarms so LPRng doesn't hang forever during transfers. ***************************************************************************/ /* * timeout_alarm * When we get the alarm, we close the file descriptor (if any) * we are working with. When we next do an option, it will fail * Note that this will cause any ongoing read/write operation to fail * We then to a longjmp to the routine, returning a non-zero value * We set an alarm using: * * if( (setjmp(Timeout_env)==0 && Set_timeout_alarm(t,s)) ){ * timeout dependent stuff * } * Clear_alarm * We define the Set_timeout macro as: * #define Set_timeout(t,s) (setjmp(Timeout_env)==0 && Set_timeout_alarm(t,s)) */ static plp_signal_t timeout_alarm (int sig UNUSED) { Alarm_timed_out = 1; signal( SIGALRM, SIG_IGN ); errno = EINTR; #if defined(HAVE_SIGLONGJMP) siglongjmp(Timeout_env,1); #else longjmp(Timeout_env,1); #endif } static plp_signal_t timeout_break (int sig UNUSED) { Alarm_timed_out = 1; signal( SIGALRM, SIG_IGN ); } /*************************************************************************** * Set_timeout( int timeout, int *socket ) * Set up a timeout to occur; note that you can call this * routine several times without problems, but you must call the * Clear_timeout routine sooner or later to reset the timeout function. * A timeout value of 0 never times out * Clear_alarm() * Turns off the timeout alarm ***************************************************************************/ void Set_timeout_signal_handler( int timeout, plp_sigfunc_t handler ) { int err = errno; sigset_t oblock; alarm(0); signal(SIGALRM, SIG_IGN); plp_unblock_one_signal( SIGALRM, &oblock ); Alarm_timed_out = 0; Timeout_pending = 0; if( timeout > 0 ){ Timeout_pending = timeout; plp_signal_break(SIGALRM, handler); alarm (timeout); } errno = err; } void Set_timeout_alarm( int timeout ) { Set_timeout_signal_handler( timeout, timeout_alarm ); } void Set_timeout_break( int timeout ) { Set_timeout_signal_handler( timeout, timeout_break ); } void Clear_timeout( void ) { int err = errno; signal( SIGALRM, SIG_IGN ); alarm(0); Timeout_pending = 0; errno = err; } /* * setuid.c: * routines to manipulate user-ids securely (and hopefully, portably). * The * internals of this are very hairy, because * (a) there's lots of sanity checking * (b) there's at least three different setuid-swapping * semantics to support :( * * * Note that the various functions saves errno then restores it afterwards; * this means it's safe to do "root_to_user();some_syscall();user_to_root();" * and errno will be from the system call. * * "root" is the user who owns the setuid executable (privileged). * "user" is the user who runs it. * "daemon" owns data files used by the LPRng utilities (spool directories, etc). * and is set by the 'user' entry in the configuration file. * * To_ruid( user ); -- set ruid to user, euid to root * To_euid( user ); -- set euid to user, ruid to root * To_euid_root(); -- set euid to root, ruid to root * To_daemon(); -- set euid to daemon, ruid to root * To_user(); -- set euid to user, ruid to root * Full_daemon_perms() -- set both UID and EUID, one way, no return * */ /*************************************************************************** * Commentary: * Patrick Powell Sat Apr 15 07:56:30 PDT 1995 * * This has to be one of the ugliest parts of any portability suite. * The following models are available: * 1. process has (old SYSV, BSD) * 2. process has (new SYSV, BSD) * * There are several possibilites: * 1. need euid root to do some operations * 2. need euid user to do some operations * 3. need euid daemon to do some operations * * Group permissions are almost useless for a server; * usually you are running as a specified group ID and do not * need to change. Client programs are slightly different. * You need to worry about permissions when creating a file; * for this reason most client programs do a u mask(0277) before any * file creation to ensure that nobody can read the file, and create * it with only user access permissions. * * > int setuid(uid) uid_t uid; * > int seteuid(euid) uid_t euid; * > int setruid(ruid) uid_t ruid; * > * > DESCRIPTION * > setuid() (setgid()) sets both the real and effective user ID * > (group ID) of the current process as specified by uid (gid) * > (see NOTES). * > * > seteuid() (setegid()) sets the effective user ID (group ID) * > of the current process. * > * > setruid() (setrgid()) sets the real user ID (group ID) of * > the current process. * > * > These calls are only permitted to the super-user or if the * > argument is the real or effective user (group) ID of the * > calling process. * > * > SYSTEM V DESCRIPTION * > If the effective user ID of the calling process is not * > super-user, but if its real user (group) ID is equal to uid * > (gid), or if the saved set-user (group) ID from execve(2V) * > is equal to uid (gid), then the effective user (group) ID is * > set to uid (gid). * > ....... etc etc * * Conclusions: * 1. if EUID == ROOT or RUID == ROOT then you can set EUID, UID to anything * 3. if EUID is root, you can set EUID * * General technique: * Initialization * - use setuid() system call to force EUID/RUID = ROOT * * Change * - assumes that initialization has been carried out and * EUID == ROOT or RUID = ROOT * - Use the seteuid() system call to set EUID * ***************************************************************************/ #if !defined(HAVE_SETREUID) && !defined(HAVE_SETEUID) && !defined(HAVE_SETRESUID) #error You need one of setreuid(), seteuid(), setresuid() #endif /*************************************************************************** * Commentary * setuid(), setreuid(), and now setresuid() * This is probably the easiest road. * Note: we will use the most feature ridden one first, as it probably * is necessary on some wierd system. * Patrick Powell Fri Aug 11 22:46:39 PDT 1995 ***************************************************************************/ #if !defined(HAVE_SETEUID) && !defined(HAVE_SETREUID) && defined(HAVE_SETRESUID) # define setreuid(x,y) (setresuid( (x), (y), -1)) # define HAVE_SETREUID #endif /*************************************************************************** * Setup_uid() * 1. gets the original EUID, RUID, EGID, RGID * 2. if UID 0 or EUID 0 forces both UID and EUID to 0 (test) * 3. Sets the EUID to the original RUID * This leaves the UID (EUID) ***************************************************************************/ void Setup_uid(void) { int err = errno; static int SetRootUID; /* did we set UID to root yet? */ if( SetRootUID == 0 ){ OriginalEUID = geteuid(); OriginalRUID = getuid(); OriginalEGID = getegid(); OriginalRGID = getgid(); DEBUG1("Setup_uid: OriginalEUID %ld, OriginalRUID %ld", (long)OriginalEUID, (long)OriginalRUID ); DEBUG1("Setup_uid: OriginalEGID %ld, OriginalRGID %ld", (long)OriginalEGID, (long)OriginalRGID ); /* we now make sure that we are able to use setuid() */ /* notice that setuid() will work if EUID or RUID is 0 */ if( OriginalEUID == ROOTUID || OriginalRUID == ROOTUID ){ /* set RUID/EUID to ROOT - possible if EUID or UID is 0 */ if( # ifdef HAVE_SETEUID setuid( (uid_t)ROOTUID ) || seteuid( OriginalRUID ) # else setuid( (uid_t)ROOTUID ) || setreuid( ROOTUID, OriginalRUID ) # endif ){ fatal(LOG_ERR, "Setup_uid: RUID/EUID Start %ld/%ld seteuid failed", (long)OriginalRUID, (long)OriginalEUID); } if( getuid() != ROOTUID ){ fatal(LOG_ERR, "Setup_uid: IMPOSSIBLE! RUID/EUID Start %ld/%ld, now %ld/%ld", (long)OriginalRUID, (long)OriginalEUID, (long)getuid(), (long)geteuid() ); } UID_root = 1; } DEBUG1( "Setup_uid: Original RUID/EUID %ld/%ld, RUID/EUID %ld/%ld", (long)OriginalRUID, (long)OriginalEUID, (long)getuid(), (long)geteuid() ); SetRootUID = 1; } errno = err; } /*************************************************************************** * seteuid_wrapper() * 1. you must have done the initialization * 2. check to see if you need to do anything * 3. check to make sure you can ***************************************************************************/ static int seteuid_wrapper( uid_t to ) { int err = errno; uid_t euid; DEBUG4( "seteuid_wrapper: Before RUID/EUID %ld/%ld, DaemonUID %ld, UID_root %ld", (long)OriginalRUID, (long)OriginalEUID, (long)DaemonUID, (long)UID_root ); if( UID_root ){ /* be brutal: set both to root */ if( setuid( ROOTUID ) ){ logerr_die(LOG_ERR, "seteuid_wrapper: setuid() failed!!"); } #if defined(HAVE_SETEUID) if( seteuid( to ) ){ logerr_die(LOG_ERR, "seteuid_wrapper: seteuid() failed!!"); } #else if( setreuid( ROOTUID, to) ){ logerr_die(LOG_ERR, "seteuid_wrapper: setreuid() failed!!"); } #endif } euid = geteuid(); DEBUG4( "seteuid_wrapper: After uid/euid %ld/%ld", (long)getuid(), (long)euid ); errno = err; return( to != euid ); } /*************************************************************************** * setruid_wrapper() * 1. you must have done the initialization * 2. check to see if you need to do anything * 3. check to make sure you can ***************************************************************************/ static int setruid_wrapper( uid_t to ) { int err = errno; uid_t ruid; DEBUG4( "setruid_wrapper: Before RUID/EUID %ld/%ld, DaemonUID %ld, UID_root %ld", (long)OriginalRUID, (long)OriginalEUID, (long)DaemonUID, (long)UID_root ); if( UID_root ){ /* be brutal: set both to root */ if( setuid( ROOTUID ) ){ logerr_die(LOG_ERR, "setruid_wrapper: setuid() failed!!"); } #if defined(HAVE_SETRUID) if( setruid( to ) ){ logerr_die(LOG_ERR, "setruid_wrapper: setruid() failed!!"); } #elif defined(HAVE_SETREUID) if( setreuid( to, ROOTUID) ){ logerr_die(LOG_ERR, "setruid_wrapper: setreuid() failed!!"); } #elif defined(__CYGWIN__) if( seteuid( to ) ){ logerr_die(LOG_ERR, "setruid_wrapper: seteuid() failed!!"); } #else # error - you do not have a way to set ruid #endif } ruid = getuid(); DEBUG4( "setruid_wrapper: After uid/euid %ld/%ld", (long)getuid(), (long)geteuid() ); errno = err; return( to != ruid ); } /* * Superhero functions - change the EUID to the requested one * - these are really idiot level, as all of the tough work is done * in Setup_uid() and seteuid_wrapper() * We also change the groups, just to be nasty as well, except for * To_ruid and To_uid, which only does the RUID and EUID * Sigh... To every rule there is an exception. */ int To_euid_root(void) { return( seteuid_wrapper( ROOTUID ) ); } static int To_daemon_called; int To_daemon(void) { Set_full_group( DaemonUID, DaemonGID ); To_daemon_called = 1; return( seteuid_wrapper( DaemonUID ) ); } int To_user(void) { if( To_daemon_called ){ Errorcode = JABORT; logmsg(LOG_ERR, "To_user: LOGIC ERROR! To_daemon has been called"); abort(); } /* Set_full_group( OriginalRUID, OriginalRGID ); */ return( seteuid_wrapper( OriginalRUID ) ); } int To_ruid(int ruid) { return( setruid_wrapper( ruid ) ); } int To_euid( int euid ) { return( seteuid_wrapper( euid ) ); } /* * set both uid and euid to the same value, using setuid(). * This is unrecoverable! */ int setuid_wrapper(uid_t to) { int err = errno; if( UID_root ){ /* Note: you MUST use setuid() to force saved_setuid correctly */ if( setuid( (uid_t)ROOTUID ) ){ logerr_die(LOG_ERR, "setuid_wrapper: setuid(ROOTUID) failed!!"); } if( setuid( to ) ){ logerr_die(LOG_ERR, "setuid_wrapper: setuid(%ld) failed!!", (long)to); } if( to ) UID_root = 0; } DEBUG4("after setuid: (%ld, %ld)", (long)getuid(),(long)geteuid()); errno = err; return( to != getuid() || to != geteuid() ); } int Full_daemon_perms(void) { Setup_uid(); Set_full_group( DaemonUID, DaemonGID ); return(setuid_wrapper(DaemonUID)); } int Full_root_perms(void) { Setup_uid(); Set_full_group( ROOTUID, ROOTUID ); return(setuid_wrapper( ROOTUID )); } int Full_user_perms(void) { Setup_uid(); Set_full_group( OriginalRUID, OriginalRGID ); return(setuid_wrapper(OriginalRUID)); } /*************************************************************************** * Getdaemon() * get daemon uid * ***************************************************************************/ int Getdaemon(void) { const char *str = 0; char *t; struct passwd *pw; int uid; str = Daemon_user_DYN; DEBUG4( "Getdaemon: using '%s'", str ); if(!str) str = "daemon"; t = (char*)str; uid = strtol( str, &t, 10 ); if( str == t || *t ){ /* try getpasswd */ pw = getpwnam( str ); if( pw ){ uid = pw->pw_uid; } } DEBUG4( "Getdaemon: uid '%d'", uid ); if( uid == ROOTUID ) uid = getuid(); DEBUG4( "Getdaemon: final uid '%d'", uid ); return( uid ); } /*************************************************************************** * Getdaemon_group() * get daemon gid * ***************************************************************************/ int Getdaemon_group(void) { const char *str = 0; char *t; struct group *gr; gid_t gid; str = Daemon_group_DYN; DEBUG4( "Getdaemon_group: Daemon_group_DYN '%s'", str ); if( !str ) str = "daemon"; DEBUG4( "Getdaemon_group: name '%s'", str ); t = (char*)str; gid = strtol( str, &t, 10 ); if( str == t ){ /* try getpasswd */ gr = getgrnam( str ); if( gr ){ gid = gr->gr_gid; } } DEBUG4( "Getdaemon_group: gid '%ld'", (long)gid ); if( gid == 0 ) gid = getgid(); DEBUG4( "Getdaemon_group: final gid '%ld'", (long)gid ); return( gid ); } /*************************************************************************** * set daemon uid and group * 1. get the current EUID * 2. set up the permissions changing * 3. set the RGID/EGID ***************************************************************************/ int Set_full_group( int euid, int gid ) { int status=0; int err; struct passwd *pw = 0; DEBUG4( "Set_full_group: euid '%d'", euid ); /* get the user we want to set the groups for */ pw = getpwuid(euid); if( UID_root ){ setuid(ROOTUID); /* set RUID/EUID to root */ #if defined(HAVE_INITGROUPS) if( pw ){ /* froth froth... initgroups() uses the same buffer as * getpwuid... SHRIEK so we need to copy the user name */ char user[256]; safestrncpy(user,pw->pw_name); if( safestrlen(user) != safestrlen(pw->pw_name) ){ fatal(LOG_ERR, "Set_full_group: CONFIGURATION BOTCH! safestrlen of user name '%s' = %d larger than buffer size %d", pw->pw_name, (int)safestrlen(pw->pw_name), (int)sizeof(user) ); } if( initgroups(user, pw->pw_gid ) == -1 ){ err = errno; logerr_die(LOG_ERR, "Set_full_group: initgroups failed '%s'", Errormsg( err ) ); } } else #endif #if defined(HAVE_SETGROUPS) if( setgroups(0,0) == -1 ){ err = errno; logerr_die(LOG_ERR, "Set_full_group: setgroups failed '%s'", Errormsg( err ) ); } #endif status = setgid( gid ); if( status < 0 ){ err = errno; logerr_die(LOG_ERR, "Set_full_group: setgid '%d' failed '%s'", gid, Errormsg( err ) ); } } return( 0 ); } int Setdaemon_group(void) { Set_full_group( DaemonUID, DaemonGID ); return( 0 ); } /* * Testing magic: * if we are running SUID * We have set our RUID to root and EUID daemon * However, we may want to run as another UID for testing. * The config file allows us to do this, but we set the SUID values * from the hardwired defaults before we read the configuration file. * After reading the configuration file, we check the current * DaemonUID and the requested Daemon UID. If the requested * Daemon UID == 0, then we run as the user which started LPD. */ void Reset_daemonuid(void) { uid_t uid; uid = Getdaemon(); /* get the config file daemon id */ DaemonGID = Getdaemon_group(); /* get the config file daemon id */ if( uid != DaemonUID ){ if( uid == ROOTUID ){ DaemonUID = OriginalRUID; /* special case for testing */ } else { DaemonUID = uid; } } DEBUG4( "DaemonUID %ld", (long)DaemonUID ); } #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_STATFS_H # include #endif #if defined(HAVE_SYS_VFS_H) && !defined(SOLARIS) # include #endif # if USE_STATFS_TYPE == STATVFS # define plp_statfs(path,buf) statvfs(path,buf) # define plp_struct_statfs struct statvfs # define statfs(path, buf) statvfs(path, buf) # define USING "STATVFS" # define BLOCKSIZE(f) (double)(f.f_frsize?f.f_frsize:f.f_bsize) # define BLOCKS(f) (double)f.f_bavail # endif # if USE_STATFS_TYPE == ULTRIX_STATFS # define plp_statfs(path,buf) statfs(path,buf) # define plp_struct_statfs struct fs_data # define USING "ULTRIX_STATFS" # define BLOCKSIZE(f) (double)f.fd_bsize # define BLOCKS(f) (double)f.fd_bfree # endif # if USE_STATFS_TYPE == SVR3_STATFS # define plp_struct_statfs struct statfs # define plp_statfs(path,buf) statfs(path,buf,sizeof(struct statfs),0) # define USING "SV3_STATFS" # define BLOCKSIZE(f) (double)f.f_bsize # define BLOCKS(f) (double)f.f_bfree # endif # if USE_STATFS_TYPE == STATFS # define plp_struct_statfs struct statfs # define plp_statfs(path,buf) statfs(path,buf) # define USING "STATFS" # define BLOCKSIZE(f) (double)f.f_bsize # define BLOCKS(f) (double)f.f_bavail # endif /*************************************************************************** * Check_space() - check to see if there is enough space ***************************************************************************/ double Space_avail( const char *pathname ) { double space = 0; plp_struct_statfs fsb; if( plp_statfs( pathname, &fsb ) == -1 ){ DEBUG2( "Check_space: cannot stat '%s'", pathname ); } else { space = BLOCKS(fsb) * (BLOCKSIZE(fsb)/1024.0); } return(space); } /* VARARGS2 */ #ifdef HAVE_STDARGS int safefprintf (int fd, const char *format,...) #else int safefprintf (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int fd; char *format; #endif char buf[10240]; VA_LOCAL_DECL VA_START (format); VA_SHIFT (fd, int); VA_SHIFT (format, char *); (void) plp_vsnprintf(buf, sizeof(buf), format, ap); return Write_fd_str( fd, buf ); } lprng-3.8.B/src/common/printjob.c0000644000131400013140000011404711531672132013661 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errorcodes.h" #include "printjob.h" #include "getqueue.h" #include "child.h" #include "fileopen.h" #include "printjob.h" /**** ENDINCLUDE ****/ #if defined(HAVE_TCDRAIN) # if defined(HAVE_TERMIOS_H) # include # endif #endif /*************************************************************************** * Commentary: * Patrick Powell Sat May 13 08:24:43 PDT 1995 * * The following algorithm is used to print a job * * The 'Send_through OF_filter' operation does the following: * if the of filter process does not exist then we create it * if the 'suspend_of_filter' flag is true then we add the suspend * string to the buffer * we send the buffer to the of filter processes * if the 'suspend_of_filter' flag is false or the 'end of job' flag * is true then we wait for the filter to exit. * * now we put out the various initialization strings * * Leader_on_open_DYN -> buffer; * FF_on_open_DYN -> buffer; * if( ( Always_banner_DYN || !Suppress_banner) && !Banner_last_DYN ){ * banner -> buffer * } * * if( OF_FILTER ) buffer-> Send_through_of_filter * else buffer -> output * * print out the data files * for( i = 0; i < data_files; ++i ){ * if( i > 0 && FF between files && OF Filter ){ * FF -> buffer * if( OF_FILTER ) buffer-> Send_through_of_filter * else buffer -> output * } * filter = lookup filter * if( filter ) Send_file_through_filter( filter ) * else file ->output * } * * if( (Always_banner_DYN || !Suppress_banner) && Banner_last_DYN ){ * banner -> buffer; * } * Trailer_on_close_DYN -> buffer; * FF_on_close_DYN -> buffer; * * if( OF_FILTER ) buffer-> Send_through_of_filter(end_of_job as well) * else buffer -> output * ****************************************************************************/ static int Run_OF_filter( int send_job_rw_timeout, int *of_pid, int *of_stdin, int *of_stderr, int output, char **outbuf, int *outmax, int *outlen, struct job *job, const char *id, int terminate_of, char *msgbuffer, int msglen ); static void Print_banner( const char *name, char *pgm, struct job *job ); static int Write_outbuf_to_OF( struct job *job, const char *title, int of_fd, char *buffer, int outlen, int of_error, char *msg, int msgmax, int timeout, int poll_for_status, char *status_file ); /**************************************************************************** * int Print_job( int output, - output device * int status_device - read status from this device is > 0 * struct job *job - job to print * int timeout - timeout for job - 0 is no timeout * int poll_for_status - after write to device, poll for status * * We have a very complex set of IO requirements here. First, there is * the problem of the device and its status return. If we have a 'real' * device, then it is usually opened RW, so we can get status back. * In this case, output == status_device. If we have a 'filter' as an * output device, then we arrange to have the filter pipe file descriptor * bidirectional. This means that the filter can/must also read the * output from the device. * * This implies that output filters used as devices must handle their status * and error reporting themselves, and provide as little status back on their * STDERR as is possible, otherwise the pipe will block for them on write. * * So the following is now done: * * a) if you have a 'real device' which is opened RW then you * have output == status_device otherwise you have status_device == -1 * b) if you have an output device that requires that you poll it for * status after every write, then you set 'poll_for_status' * This has the effect of temporarily setting 'status_device = -1' * i.e. - not trying to get status. * c) If you need to use a filter, then you pass the output device to the * filter. The filter will then need to decide if it can read from * the device. After the filter has run and you have 'poll_for_status' * you should check for status from the device. * d) timeouts are handled by waiting for IO from either the file descriptor * OR checking to see if the status file exists and it has been updated. ****************************************************************************/ int Print_job( int output, int status_device, struct job *job, int send_job_rw_timeout, int poll_for_status, char *user_filter ) { char *FF_str, *leader_str, *trailer_str, *filter; int i, of_stdin, of_stderr, if_error[2], of_pid, copy, copies, do_banner, n, pid, count, fd, tempfd, files_printed, time_left; char msg[SMALLBUFFER]; char filter_name[8], filter_title[64], msgbuffer[SMALLBUFFER], filtermsgbuffer[SMALLBUFFER]; const char *id, *s, *banner_name, *transfername, *openname, *format; char *t; struct line_list *datafile, files; struct stat statb; of_pid = -1; msgbuffer[0] = 0; filtermsgbuffer[0] = 0; Errorcode = 0; Init_line_list(&files); of_stdin = of_stderr = tempfd = fd = -1; FF_str = leader_str = trailer_str = 0; files_printed = 0; DEBUG2( "Print_job: output fd %d", output ); if(DEBUGL5){ LOGDEBUG("Print_job: at start open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } if(DEBUGL2) Dump_job( "Print_job", job ); id = Find_str_value(&job->info,IDENTIFIER); if( id == 0 ) id = Find_str_value(&job->info,XXCFTRANSFERNAME); DEBUG2("Print_job: OF_Filter_DYN '%s'", OF_Filter_DYN ); /* clear output buffer */ Init_buf(&Outbuf, &Outmax, &Outlen ); FF_str = Fix_str( Form_feed_DYN ); leader_str = Fix_str( Leader_on_open_DYN ); trailer_str = Fix_str( Trailer_on_close_DYN ); /* Leader_on_open_DYN -> output; */ if( leader_str ) Put_buf_str( leader_str, &Outbuf, &Outmax, &Outlen ); /* FF_on_open_DYN -> output; */ if( FF_on_open_DYN ) Put_buf_str( FF_str, &Outbuf, &Outmax, &Outlen ); /* * if SupressHeader then no banner * if AlwaysBanner then get user name */ banner_name = Find_str_value(&job->info, BNRNAME ); if( Always_banner_DYN && banner_name == 0 ){ /* we are always going to do a banner; get the user name */ /* need a name to use */ banner_name = Find_str_value( &job->info,LOGNAME); if( banner_name == 0 ) banner_name = "ANONYMOUS"; Set_str_value(&job->info,BNRNAME,banner_name); } /* suppress header overrides everything */ do_banner = (!Suppress_header_DYN && banner_name); /* now we have a banner, is it at start or end? */ DEBUG2("Print_job: do_banner %d, :hl=%d, :bs=%s, :be=%s, banner_name '%s'", do_banner, Banner_last_DYN, Banner_start_DYN, Banner_end_DYN, banner_name ); if( do_banner && Generate_banner_DYN ){ Add_banner_to_job( job ); do_banner = 0; Outlen = 0; } if( do_banner && !Banner_last_DYN ){ Print_banner( banner_name, Banner_start_DYN, job ); } DEBUG2("Print_job: setup %d bytes '%s'", Outlen, Outbuf ); msgbuffer[0] = 0; /* do we need an OF filter? */ Set_block_io( output ); if( OF_Filter_DYN ){ if( Run_OF_filter( send_job_rw_timeout, &of_pid, &of_stdin, &of_stderr, output, &Outbuf, &Outmax, &Outlen, job, id, 0, msgbuffer, sizeof(msgbuffer)-1 ) ){ goto exit; } } else if( Outlen ){ /* no filter - direct to device */ n = Write_outbuf_to_OF(job,"LP",output, Outbuf, Outlen, status_device, msgbuffer, sizeof(msgbuffer)-1, send_job_rw_timeout, poll_for_status, Status_file_DYN ); if( n ){ Errorcode = JFAIL; setstatus(job, "LP device write error '%s'", Server_status(n)); goto exit; } } Init_buf(&Outbuf, &Outmax, &Outlen ); /* * print out the data files */ for( count = 0; count < job->datafiles.count; ++count ){ datafile = (void *)job->datafiles.list[count]; if(DEBUGL4)Dump_line_list("Print_job - datafile", datafile ); Set_block_io( output ); transfername = Find_str_value(datafile,DFTRANSFERNAME); openname = Find_str_value(datafile,OPENNAME); if( !openname ) openname = transfername; format = Find_str_value(datafile,FORMAT); copies = Find_flag_value(datafile,COPIES); if( copies == 0 ) copies = 1; Set_str_value(&job->info,FORMAT,format); Set_str_value(&job->info,DF_NAME,transfername); s = Find_str_value(datafile,"N"); Set_str_value(&job->info,"N",s); /* * now we check to see if there is an input filter */ plp_snprintf(filter_name,sizeof(filter_name), "%s","if"); filter_name[0] = cval(format); filter = user_filter; switch( cval(format) ){ case 'p': case 'f': case 'l': filter_name[0] = 'i'; if( !filter ) filter = IF_Filter_DYN; break; case 'a': case 'i': case 'o': case 's': setstatus(job, "bad data file format '%c', using 'f' format", cval(format) ); filter_name[0] = 'i'; if( !filter ) filter = IF_Filter_DYN; format = "f"; break; } if( !filter ){ filter = Find_str_value(&PC_entry_line_list, filter_name ); } if( !filter){ filter = Find_str_value(&Config_line_list,filter_name ); } if( filter == 0 ) filter = Filter_DYN; DEBUG3("Print_job: format '%s', filter '%s'", format, filter ); uppercase(filter_name); if( filter ){ s = filter; if( cval(s) == '(' ){ ++s; while( isspace(cval(s))) ++s; } else { if( !(s = strchr(filter,'/')) ) s = filter; } plp_snprintf(msg, sizeof(msg), "%s", s ); if( (t = strpbrk(msg,Whitespace)) ) *t = 0; if( (t = strrchr(msg,'/')) ) memmove(msg,t+1,strlen(t+1)+1); } else { plp_snprintf(msg, sizeof(msg), "%s", "none - passthrough" ); } plp_snprintf(filter_title,sizeof(filter_title), "%s filter '%s'", filter_name, msg ); if( fd >= 0 ) close(fd); fd = -1; if( !Is_server && openname == 0 ){ fd = 0; DEBUG3("Print_job: taking file from STDIN" ); } else if( (fd = Checkread( openname, &statb )) < 0 ){ Errorcode = JFAIL; logmsg( LOG_ERR, "Print_job: job '%s', cannot open data file '%s'", id, openname ); goto end_of_job; } setstatus(job, "processing '%s', size %0.0f, format '%s', %s", transfername, (double)statb.st_size, format, filter_title ); if( cval(format) == 'p' ){ DEBUG3("Print_job: using 'p' formatter '%s'", Pr_program_DYN ); setstatus(job, "format 'p' pretty printer '%s'", Pr_program_DYN); if( Pr_program_DYN == 0 ){ setstatus(job, "no 'p' format filter available" ); Errorcode = JABORT; goto end_of_job; } tempfd = Make_temp_fd(0); n = Filter_file( send_job_rw_timeout, fd, tempfd, "PR_PROGRAM", Pr_program_DYN, 0, job, 0, 1 ); if( n ){ Errorcode = JABORT; logerr(LOG_INFO, "Print_job: could not make '%s' process", Pr_program_DYN ); goto end_of_job; } if( tempfd != fd ){ if( dup2(tempfd,fd) == -1 ){ Errorcode = JABORT; logerr(LOG_INFO, "Print_job: dup2(%d,%d) failed", tempfd, fd ); } close(tempfd); } if( fstat(fd, &statb ) == -1 ){ Errorcode = JABORT; logerr(LOG_INFO, "Print_job: fstat() failed"); } setstatus(job, "data file '%s', size now %0.0f", transfername, (double)statb.st_size ); } for( copy = 0; copy < copies; ++copy ){ if( fd && lseek(fd,0,SEEK_SET) == -1 ){ Errorcode = JABORT; logerr(LOG_INFO, "Print_job: lseek tempfd failed"); goto end_of_job; } if( fstat(fd, &statb ) == -1 ){ Errorcode = JABORT; logerr(LOG_INFO, "Print_job: fstat() failed"); } DEBUG1("Print_job: copy %d, data file '%s', size now %0.0f", copy, transfername, (double)statb.st_size ); if( copies > 1 ){ setstatus(job, "doing copy %d of %d", copy+1, copies ); } if(DEBUGL5){ LOGDEBUG("Print_job: doing '%s' open fd's", openname); for( i = 0; i < 20; ++i ) if( fstat(i,&statb) == 0 ) LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } Init_buf(&Outbuf, &Outmax, &Outlen ); if( files_printed++ && (!No_FF_separator_DYN || FF_separator_DYN) && FF_str ){ /* FF separator -> of_fd; */ setstatus(job, "printing '%s' FF separator ",id); Put_buf_str( FF_str, &Outbuf, &Outmax, &Outlen ); } /* do we have output for the OF device/filter ? */ if( Outlen > 0 ){ Set_block_io( output ); /* yes */ if( OF_Filter_DYN ){ /* send it to the OF filter */ if( Run_OF_filter( send_job_rw_timeout, &of_pid, &of_stdin, &of_stderr, output, &Outbuf, &Outmax, &Outlen, job, id, 0, msgbuffer, sizeof(msgbuffer)-1 ) ){ goto exit; } } else { /* send it to the OF device */ n = Write_outbuf_to_OF(job,"LP",output, Outbuf, Outlen, status_device, msgbuffer, sizeof(msgbuffer)-1, send_job_rw_timeout, poll_for_status, Status_file_DYN ); if( n ){ Errorcode = n; setstatus(job, "error writing to device '%s'", Server_status(n)); goto end_of_job; } } Init_buf(&Outbuf, &Outmax, &Outlen ); } Set_block_io( output ); if( filter ){ DEBUG3("Print_job: format '%s' starting filter '%s'", format, filter ); DEBUG2("Print_job: filter_stderr_to_status_file %d, ps '%s'", Filter_stderr_to_status_file_DYN, Status_file_DYN ); if_error[0] = if_error[1] = -1; if( Filter_stderr_to_status_file_DYN && Status_file_DYN && *Status_file_DYN ){ if_error[1] = Checkwrite( Status_file_DYN, &statb, O_WRONLY|O_APPEND, 0, 0 ); } else if( pipe( if_error ) == -1 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Print_job: pipe() failed"); goto end_of_job; } Max_open(if_error[0]); Max_open(if_error[1]); DEBUG3("Print_job: %s fd if_error[%d,%d]", filter_title, if_error[0], if_error[1] ); s = 0; if( Backwards_compatible_filter_DYN ) s = BK_filter_options_DYN; if( s == 0 ) s = Filter_options_DYN; Free_line_list(&files); Check_max(&files, 10 ); files.list[files.count++] = Cast_int_to_voidstar(fd); /* stdin */ files.list[files.count++] = Cast_int_to_voidstar(output); /* stdout */ files.list[files.count++] = Cast_int_to_voidstar(if_error[1]); /* stderr */ if( (pid = Make_passthrough( filter, s, &files, job, 0 )) < 0 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Print_job: could not make %s process", filter_title ); goto end_of_job; } files.count = 0; Free_line_list(&files); if( (close(if_error[1]) == -1 ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Print_job: X5 close(%d) failed", if_error[1]); } if_error[1] = -1; Init_buf(&Outbuf, &Outmax, &Outlen ); filtermsgbuffer[0] = 0; if( if_error[0] != -1 ){ n = Get_status_from_OF(job,filter_title,pid, if_error[0], filtermsgbuffer, sizeof(filtermsgbuffer)-1, send_job_rw_timeout, 0, 0, Status_file_DYN ); if( filtermsgbuffer[0] ){ setstatus(job, "%s filter msg - '%s'", filter_title, filtermsgbuffer ); } if( n ){ Errorcode = n; setstatus(job, "%s filter problems, error '%s'", filter_title, Server_status(n)); goto end_of_job; } close(if_error[0]); if_error[0] = -1; } time_left = send_job_rw_timeout; while(1){ /* now we get the exit status for the filter */ n = Wait_for_pid( pid, filter_title, 0, time_left ); switch(n){ case JSUCC: break; case JTIMEOUT: /* get the timeout value */ if( send_job_rw_timeout > 0 && Status_file_DYN && !stat(Status_file_DYN, &statb) ){ int delta = time(0) - statb.st_mtime; /* OK, we need to wait a bit longer */ if( delta < send_job_rw_timeout ){ time_left = send_job_rw_timeout - delta; continue; } } default: Errorcode = n; setstatus(job, "%s filter exit status '%s'", filter_title, Server_status(n)); goto end_of_job; } setstatus(job, "%s filter finished", filter_title ); break; } } else { /* we write to the output device, and then get status */ DEBUG3("Print_job: format '%s' no filter, reading from %d", format, fd ); Init_buf(&Outbuf, &Outmax, &Outlen ); while( (Outlen = Read_fd_len_timeout(send_job_rw_timeout,fd,Outbuf,Outmax)) > 0 ){ Outbuf[Outlen] = 0; n = Write_outbuf_to_OF(job,"LP",output, Outbuf, Outlen, status_device, msgbuffer, sizeof(msgbuffer)-1, send_job_rw_timeout, poll_for_status, Status_file_DYN ); if( n ){ Errorcode = JFAIL; setstatus(job, "error '%s'", Server_status(n)); goto end_of_job; } } if( Outlen < 0 ){ Errorcode = JFAIL; setstatus(job, "error reading file '%s'", Errormsg(errno)); goto end_of_job; } Outlen = 0; } DEBUG3("Print_job: finished copy"); } DEBUG3("Print_job: finished file"); } /* * now we do the end */ end_of_job: DEBUG3("Print_job: end of job"); Init_buf(&Outbuf, &Outmax, &Outlen ); /* check for the banner at the end */ if( do_banner && (Banner_last_DYN || Banner_end_DYN) ){ Print_banner( banner_name, Banner_end_DYN, job ); } /* * FF_on_close_DYN -> of_fd; */ if( FF_on_close_DYN ) Put_buf_str( FF_str, &Outbuf, &Outmax, &Outlen ); /* * Trailer_on_close_DYN -> of_fd; */ if( trailer_str ) Put_buf_str( trailer_str, &Outbuf, &Outmax, &Outlen ); /* * close the OF Filters */ Set_block_io( output ); if( OF_Filter_DYN ){ if( Run_OF_filter( send_job_rw_timeout, &of_pid, &of_stdin, &of_stderr, output, &Outbuf, &Outmax, &Outlen, job, id, 1, msgbuffer, sizeof(msgbuffer)-1 ) ){ goto exit; } } else { if( Outlen ){ n = Write_outbuf_to_OF(job,"LP",output, Outbuf, Outlen, status_device, msgbuffer, sizeof(msgbuffer)-1, send_job_rw_timeout, poll_for_status, Status_file_DYN ); if( n && Errorcode == 0 ){ Errorcode = JFAIL; setstatus(job, "LP device write error '%s'", Errormsg(errno)); goto exit; } } if( msgbuffer[0] ){ setstatus(job, "%s filter msg - '%s'", "LP", msgbuffer ); } } Init_buf(&Outbuf, &Outmax, &Outlen ); #ifdef HAVE_TCDRAIN if( isatty( output ) && tcdrain( output ) == -1 ){ logerr_die(LOG_INFO, "Print_job: tcdrain failed"); } #endif setstatus(job, "printing finished"); exit: Init_buf(&Outbuf, &Outmax, &Outlen ); if( Outbuf ) free(Outbuf); Outbuf = 0; if(FF_str) free(FF_str); if(leader_str) free(leader_str); if(trailer_str) free(trailer_str); if( of_stdin != -1 ) close(of_stdin); of_stdin = -1; if( of_stderr != -1 ) close(of_stderr); of_stderr = -1; if( tempfd != -1 ) close(tempfd); tempfd = -1; if( fd != -1 ) close(fd); fd = -1; if(DEBUGL3){ LOGDEBUG("Print_job: at end open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } return( Errorcode ); } /* * int Create_OF_filter( int *of_stdin, int *of_stderr ) * of_stdin = STDIN of filter (writable) * of_stderr = STDERR of filter (readable) * - we create the OF filter and return the PID * RETURNS: * */ static const char *Filter_stop = "\031\001"; static int Run_OF_filter( int send_job_rw_timeout, int *of_pid, int *of_stdin, int *of_stderr, int output, char **outbuf, int *outmax, int *outlen, struct job *job, const char *id, int terminate_of, char *msgbuffer, int msglen ) { char msg[SMALLBUFFER]; char *s; int of_error[2], of_fd[2], n, time_left; struct stat statb; struct line_list files; if( *of_pid < 0 ){ Init_line_list(&files); of_fd[0] = of_fd[1] = of_error[0] = of_error[1] = -1; *of_stdin = *of_stderr = -1; if( !(s = strchr( OF_Filter_DYN, '/' )) ) s = OF_Filter_DYN; plp_snprintf( msg, sizeof(msg), "%s", s ); if( (s = strpbrk( msg, Whitespace )) ) *s = 0; if( (s = strrchr( msg, '/')) ){ memmove( msg, s+1, safestrlen(s)+1 ); } setstatus(job, "printing '%s' starting OF '%s'", id, msg ); if( pipe( of_fd ) == -1 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Run_OF_filter: pipe() failed"); goto exit; } Max_open(of_fd[0]); Max_open(of_fd[1]); DEBUG2("Run_OF_filter: errors_to_ps %d, ps '%s'", Filter_stderr_to_status_file_DYN, Status_file_DYN ); of_error[0] = of_error[1] = -1; if( Filter_stderr_to_status_file_DYN && Status_file_DYN && *Status_file_DYN ){ of_error[1] = Checkwrite( Status_file_DYN, &statb, O_WRONLY|O_APPEND, 0, 0 ); } else if( pipe( of_error ) == -1 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Run_OF_filter: pipe() failed"); goto exit; } Max_open(of_error[0]); Max_open(of_error[1]); DEBUG3("Run_OF_filter: fd of_fd[%d,%d], of_error[%d,%d]", of_fd[0], of_fd[1], of_error[0], of_error[1] ); /* set format */ Set_str_value(&job->info,FORMAT,"o"); /* set up file descriptors */ s = 0; if( Backwards_compatible_filter_DYN ) s = BK_of_filter_options_DYN; if( s == 0 ) s = OF_filter_options_DYN; if( s == 0 ) s = Filter_options_DYN; Check_max(&files,10); files.list[files.count++] = Cast_int_to_voidstar(of_fd[0]); /* stdin */ files.list[files.count++] = Cast_int_to_voidstar(output); /* stdout */ files.list[files.count++] = Cast_int_to_voidstar(of_error[1]); /* stderr */ if( (*of_pid = Make_passthrough( OF_Filter_DYN, s,&files, job, 0 ))<0){ Errorcode = JFAIL; logerr(LOG_INFO, "Run_OF_filter: could not create OF process"); goto exit; } files.count = 0; Free_line_list(&files); DEBUG3("Run_OF_filter: OF pid %d", *of_pid ); if( of_fd[0] > 0 && (close( of_fd[0] ) == -1 ) ){ Errorcode = JFAIL; logerr(LOG_INFO, "Run_OF_filter: X0 close(%d) failed", of_fd[0]); goto exit; } of_fd[0] = -1; if( of_error[1] > 0 && (close( of_error[1] ) == -1 ) ){ Errorcode = JFAIL; logerr(LOG_INFO, "Run_OF_filter: X1 close(%d) failed", of_error[1]); goto exit; } of_error[1] = -1; DEBUG3("Run_OF_filter: writing init to OF pid '%d', count %d", *of_pid, *outlen ); *of_stderr = of_error[0]; *of_stdin = of_fd[1]; } else { DEBUG3("Run_OF_filter: SIGCONT to to OF pid '%d'", *of_pid ); kill( *of_pid, SIGCONT ); } if( Suspend_OF_filter_DYN && !terminate_of ){ DEBUG3("Run_OF_filter: stopping OF pid '%d'", *of_pid ); Put_buf_str( Filter_stop, outbuf, outmax, outlen ); n = Write_outbuf_to_OF(job,"OF",*of_stdin, *outbuf, *outlen, *of_stderr, msgbuffer, msglen, send_job_rw_timeout, 0, Status_file_DYN ); if( n == 0 ){ n = Get_status_from_OF(job,"OF",*of_pid, *of_stderr, msgbuffer, msglen, send_job_rw_timeout, 1, Filter_poll_interval_DYN, Status_file_DYN ); } if( n != JSUSP ){ Errorcode = n; setstatus(job, "OF filter problems, error '%s'", Server_status(n)); goto exit; } setstatus(job, "OF filter suspended" ); } else { DEBUG3("Run_OF_filter: end OF pid '%d'", *of_pid ); n = Write_outbuf_to_OF(job,"OF",*of_stdin, *outbuf, *outlen, *of_stderr, msgbuffer, msglen, send_job_rw_timeout, 0, Status_file_DYN ); if( n ){ Errorcode = n; setstatus(job, "OF filter problems, error '%s'", Server_status(n)); goto exit; } close( *of_stdin ); *of_stdin = -1; n = Get_status_from_OF(job,"OF",*of_pid, *of_stderr, msgbuffer, msglen, send_job_rw_timeout, 0, 0, Status_file_DYN ); if( n ){ Errorcode = n; setstatus(job, "OF filter problems, error '%s'", Server_status(n)); goto exit; } close( *of_stderr ); *of_stderr = -1; /* now we get the exit status for the filter */ time_left = send_job_rw_timeout; while(1){ /* now we get the exit status for the filter */ n = Wait_for_pid( *of_pid, "OF", 0, time_left ); switch(n){ case JSUCC: break; case JTIMEOUT: /* get the timeout value */ if( send_job_rw_timeout > 0 && Status_file_DYN && !stat(Status_file_DYN, &statb) ){ int delta = time(0) - statb.st_mtime; /* OK, we need to wait a bit longer */ if( delta < send_job_rw_timeout ){ time_left = send_job_rw_timeout - delta; continue; } } default: Errorcode = n; setstatus(job, "%s filter exit status '%s'", "OF", Server_status(n)); goto exit; } setstatus(job, "%s filter finished", "OF" ); break; } *of_pid = -1; } return( 0 ); exit: return( -1 ); } /* * Print a banner * check for a small or large banner as necessary */ static void Print_banner( const char *name, char *pgm, struct job *job ) { char buffer[LARGEBUFFER]; int len, n; char *bl = 0; int tempfd; /* * print the banner */ if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Print_banner: at start open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } if( !pgm ) pgm = Banner_printer_DYN; DEBUG2( "Print_banner: name '%s', pgm '%s', sb=%d, Banner_line_DYN '%s'", name, pgm, Short_banner_DYN, Banner_line_DYN ); if( !pgm && !Short_banner_DYN ){ return; } if( pgm ){ /* we now need to create a banner */ setstatus(job, "creating banner"); tempfd = Make_temp_fd(0); n = Filter_file( Send_job_rw_timeout_DYN, -1, tempfd, "BANNER", pgm, Filter_options_DYN, job, 0, 1 ); if( n ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Print_banner: banner pgr '%s' exit status '%s'", pgm, Server_status(n)); } if( lseek(tempfd,0,SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Print_banner: fseek(%d) failed", tempfd); } len = Outlen; while( (n = ok_read(tempfd, buffer, sizeof(buffer))) > 0 ){ Put_buf_len(buffer, n, &Outbuf, &Outmax, &Outlen ); } if( (close(tempfd) == -1 ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Print_banner: Xa close(%d) failed", tempfd); } DEBUG4("Print_banner: BANNER '%s'", Outbuf+len); } else { struct line_list l; Init_line_list(&l); setstatus(job, "inserting short banner line"); Add_line_list(&l,Banner_line_DYN,0,0,0); Fix_dollars(&l,job,1,Filter_options_DYN); bl = safestrdup2(l.list[0],"\n",__FILE__,__LINE__); Put_buf_str( bl, &Outbuf, &Outmax, &Outlen ); Free_line_list(&l); if( bl ) free(bl); bl = 0; } if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Print_banner: at end open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } } /* * Write_outbuf_to_OF( * int of_fd, buffer, outlen - write to this * int of_error - read status from this * char *msg, int msgmax - status storage area * int timeout - timeout * nnn - wait this long * 0 - wait indefinitely * -1 - do not wait * poll for status * ) * We write the output buffer to the OF process, and then wait for it to * either exit or suspend itself. * JSUCC = 0 * JTIMEOUT - timeout * JWRERR - (-1 originally) - error reading or writing * JRDERR - (-1 originally) - error reading or writing */ static int Write_outbuf_to_OF( struct job *job, const char *title, int of_fd, char *buffer, int outlen, int of_error, char *msg, int msgmax, int timeout, int poll_for_status, char *status_file ) { time_t start_time, current_time; int msglen, return_status, count, elapsed, left; struct stat statb; char *s; DEBUG3( "Write_outbuf_to_OF: len %d, of_fd %d, of_error %d, timeout %d, poll_for_status %d", outlen, of_fd, of_error, timeout, poll_for_status ); start_time = time((void *)0); return_status = 0; if( outlen == 0 ) return return_status; if( of_fd >= 0 && fstat( of_fd, &statb ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Write_outbuf_to_OF: %s, of_fd %d closed!", title, of_fd ); } if( of_error > 0 && fstat( of_error, &statb ) ){ logerr(LOG_INFO, "Write_outbuf_to_OF: %s, of_error %d closed!", title, of_error ); of_error = -1; } if( of_error < 0 ){ return_status = Write_fd_len_timeout( timeout, of_fd, buffer, outlen ); DEBUG4("Write_outbuf_to_OF: Write_fd_len_timeout result %d", return_status ); } else if( poll_for_status ){ return_status = Write_fd_len_timeout( timeout, of_fd, buffer, outlen ); DEBUG4("Write_outbuf_to_OF: Write_fd_len_timeout result %d", return_status ); do { msglen = safestrlen(msg); if( msglen >= msgmax ){ setstatus(job, "%s filter msg - '%s'", title, msg ); msg[0] = 0; msglen = 0; } count = -1; /* we put a 1 second timeout here, just to make sure */ Set_block_io( of_error ); count = Read_fd_len_timeout( 1, of_error, msg+msglen, msgmax-msglen ); Set_nonblock_io( of_error ); if( count > 0 ){ msglen += count; msg[msglen] = 0; while( (s = safestrchr(msg,'\n')) ){ *s++ = 0; setstatus(job, "%s filter msg - '%s'", title, msg ); memmove(msg,s,safestrlen(s)+1); } } } while( count > 0 ); } else while( return_status == 0 && outlen > 0 ){ left = timeout; if( timeout > 0 ){ current_time = time((void *)0); elapsed = current_time - start_time; left = timeout - elapsed; if( left <= 0 ){ if( status_file && !stat(status_file, &statb) ){ int interval = current_time - statb.st_mtime; if( interval < timeout ){ start_time = statb.st_mtime; elapsed = current_time - start_time; left = timeout - elapsed; } else { return_status = JTIMEOUT; break; } } else { return_status = JTIMEOUT; break; } } } msglen = safestrlen(msg); if( msglen >= msgmax ){ setstatus(job, "%s filter msg - '%s'", title, msg ); msg[0] = 0; msglen = 0; } count = -1; /* number read into msg buffer */ DEBUG4("Write_outbuf_to_OF: writing %d", outlen ); return_status = Read_write_timeout( of_error, msg+msglen, msgmax-msglen, &count, of_fd, &buffer, &outlen, left ); DEBUG4("Write_outbuf_to_OF: return_status %d, count %d, '%s'", return_status, count, msg); if( DEBUGL4 ){ char smb[32]; plp_snprintf(smb,sizeof(smb), "%s",msg); logDebug("Write_outbuf_to_OF: writing '%s...'", smb ); } if( count > 0 ){ msglen += count; msg[msglen] = 0; s = msg; while( (s = safestrchr(msg,'\n')) ){ *s++ = 0; setstatus(job, "%s filter msg - '%s'", title, msg ); memmove(msg,s,safestrlen(s)+1); } } } if( return_status < 0 ) return_status = JWRERR; DEBUG3("Write_outbuf_to_OF: after write return_status %d, of_fd %d, of_error %d", return_status, of_fd, of_error ); /* read and see if there is any status coming back */ return( return_status ); } /* * int Get_status_from_OF( struct job *job, char *title, int of_pid, * int of_error, char *msg, int msgmax, * int timeout, int suspend, int max_wait ) * return: * 0 successful * JTIMEOUT - timeout */ int Get_status_from_OF( struct job *job, const char *title, int of_pid, int of_error, char *msg, int msgmax, int timeout, int suspend, int max_wait, char *status_file ) { time_t start_time, current_time; int m, msglen, return_status, count, elapsed, left, done; struct stat statb; char *s; start_time = time((void *)0); DEBUG3( "Get_status_from_OF: pid %d, of_error %d, timeout %d", of_pid, of_error, timeout ); return_status = 0; if( fstat( of_error, &statb ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Get_status_from_OF: %s, of_error %d closed!", title, of_error ); } done = 0; left = timeout; while( !done ){ if( timeout > 0 ){ current_time = time((void *)0); elapsed = current_time - start_time; left = timeout - elapsed; if( left <= 0 ){ if( status_file && !stat(status_file, &statb) ){ int interval = current_time - statb.st_mtime; if( interval < timeout ){ start_time = statb.st_mtime; elapsed = current_time - start_time; left = timeout - elapsed; } else { return_status = JTIMEOUT; break; } } else { return_status = JTIMEOUT; break; } } } DEBUG3("Get_status_from_OF: waiting for '%s', left %d secs for pid %d", suspend?"suspend":"exit", left, of_pid ); count = -1; m = 0; /* we see if we have output */ if( suspend ){ /* poll for process suspend status */ left = max_wait>0?max_wait:1; DEBUG3("Get_status_from_OF: polling interval %d", left ); return_status = Wait_for_pid( of_pid, title, suspend, left ); DEBUG4("Get_status_from_OF: return_status '%s'", Server_status(return_status)); /* we do a poll, just to see if the process is blocked because the * pipe is full. We may need to read the pipe to clear out the buffer * so it can exit. This is really an unusual condition, but it can happen. */ if( return_status != JTIMEOUT ){ done = 1; } DEBUG4("Get_status_from_OF: now reading, after suspend" ); do{ msglen = safestrlen(msg); if( msglen >= msgmax ){ setstatus(job, "%s filter msg - '%s'", title, msg ); msg[0] = 0; msglen = 0; } count = -1; Set_nonblock_io( of_error ); count = ok_read( of_error, msg+msglen, msgmax-msglen ); Set_block_io( of_error ); if( count > 0 ){ while( (s = safestrchr(msg,'\n')) ){ *s++ = 0; setstatus(job, "%s filter msg - '%s'", title, msg ); memmove(msg,s,safestrlen(s)+1); } } } while( count > 0 ); } else do { /* now we read the error output, just in case there is something there */ DEBUG4("Get_status_from_OF: now reading on fd %d, left %d", of_error, left ); msglen = safestrlen(msg); if( msglen >= msgmax ){ setstatus(job, "%s filter msg - '%s'", title, msg ); msg[0] = 0; msglen = 0; } Set_block_io( of_error ); count = Read_fd_len_timeout( left, of_error, msg+msglen, msgmax-msglen ); if( count > 0 ){ msglen += count; msg[msglen] = 0; s = msg; while( (s = safestrchr(msg,'\n')) ){ *s++ = 0; setstatus(job, "%s filter msg - '%s'", title, msg ); memmove(msg,s,safestrlen(s)+1); } } else if( count == 0 ){ done = 1; } } while( count > 0 ); } return(return_status); } /**************************************************************************** * int Wait_for_pid( int of_pid, char *name, int suspend, int timeout ) * of_pid = pid of the process * name = name for messages * suspend = 1 if you want to wait for suspend, now exit * timeout = length of time to wait - 0 is infinite, -1 is none * * returns: * JSUCC = 0 - successful error code exit * JSUSP - successful suspend * JSIGNAL - signal exit code * >0 - exit code * JTIMEOUT - EINTR error, probably a timeout * JCHILD - ECHILD error * JNOWAIT - nonblocking check, no status * ****************************************************************************/ int Wait_for_pid( int of_pid, const char *name, int suspend, int timeout ) { int pid, err, return_code; plp_status_t ps_status; DEBUG2("Wait_for_pid: name '%s', pid %d, suspend %d, timeout %d", name, of_pid, suspend, timeout ); errno = 0; memset(&ps_status,0,sizeof(ps_status)); if( timeout > 0 ){ Set_timeout_break( timeout ); pid = plp_waitpid(of_pid,&ps_status,suspend?WUNTRACED:0 ); err = errno; Clear_timeout(); } else if( timeout == 0 ){ pid = plp_waitpid(of_pid,&ps_status,suspend?WUNTRACED:0); err = errno; } else { pid = plp_waitpid(of_pid,&ps_status,(suspend?WUNTRACED:0)|WNOHANG); err = errno; } DEBUG2("Wait_for_pid: pid %d exit status '%s'", pid, Decode_status(&ps_status)); return_code = 0; if( pid > 0 ){ if( WIFSTOPPED(ps_status) ){ return_code = JSUSP; DEBUG1("Wait_for_pid: %s filter suspended", name ); } else if( WIFEXITED(ps_status) ){ return_code = WEXITSTATUS(ps_status); if( return_code > 0 && return_code < 32 ) return_code += JFAIL-1; DEBUG3( "Wait_for_pid: %s filter exited with status %d", name, return_code); } else if( WIFSIGNALED(ps_status) ){ int n; n = WTERMSIG(ps_status); logmsg(LOG_INFO, "Wait_for_pid: %s filter died with signal '%s'",name, Sigstr(n)); return_code = JSIGNAL; } else { return_code = JABORT; logmsg(LOG_INFO, "Wait_for_pid: %s filter did strange things",name); } } else if( pid < 0 ){ /* you got an error, and it was ECHILD or EINTR * if it was EINTR, you want to know */ if( err == EINTR ) return_code = JTIMEOUT; else return_code = JCHILD; } else { return_code = JNOWAIT; } DEBUG1("Wait_for_pid: returning '%s', exit status '%s'", Server_status(return_code), Decode_status(&ps_status) ); errno = err; return( return_code ); } /* moved here from lpd_jobs.c as it is now called also here and lpd_jobs.c * is only linked into the server, not the clients - brl*/ void Add_banner_to_job( struct job *job ) { const char *banner_name; char *tempfile; struct line_list *lp; int tempfd; Errorcode = 0; banner_name = Find_str_value(&job->info, BNRNAME ); if( banner_name == 0 ){ banner_name = Find_str_value( &job->info,LOGNAME); } if( banner_name == 0 ) banner_name = "ANONYMOUS"; Set_str_value(&job->info,BNRNAME,banner_name); banner_name = Find_str_value(&job->info, BNRNAME ); DEBUG1("Add_banner_to_job: banner name '%s'", banner_name ); if( !Banner_last_DYN ){ DEBUG1("Add_banner_to_job: banner at start"); Init_buf(&Outbuf, &Outmax, &Outlen ); Print_banner( banner_name, Banner_start_DYN, job ); tempfd = Make_temp_fd(&tempfile); if( Write_fd_len( tempfd, Outbuf, Outlen ) < 0 ){ logerr(LOG_INFO, "Add_banner_to_job: write to '%s' failed", tempfile ); Errorcode = JABORT; return; } close(tempfd); lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&job->datafiles,1); memmove( &job->datafiles.list[1], &job->datafiles.list[0], job->datafiles.count * sizeof(job->datafiles.list[0]) ); job->datafiles.list[0] = (void *)lp; ++job->datafiles.count; Set_str_value(lp,OPENNAME,tempfile); Set_str_value(lp,DFTRANSFERNAME,tempfile); Set_str_value(lp,"N","BANNER"); Set_str_value(lp,FORMAT,"f"); } if( Banner_last_DYN || Banner_end_DYN) { Init_buf(&Outbuf, &Outmax, &Outlen ); Print_banner( banner_name, Banner_end_DYN, job ); tempfd = Make_temp_fd(&tempfile); if( Write_fd_len( tempfd, Outbuf, Outlen ) < 0 ){ logerr(LOG_INFO, "Add_banner_to_job: write to '%s' failed", tempfile ); Errorcode = JABORT; return; } close(tempfd); lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count] = (void *)lp; ++job->datafiles.count; Set_str_value(lp,OPENNAME,tempfile); Set_str_value(lp,DFTRANSFERNAME,tempfile); Set_str_value(lp,"N","BANNER"); Set_str_value(lp,FORMAT,"f"); } if(DEBUGL3)Dump_job("Add_banner_to_job", job); } lprng-3.8.B/src/common/md5.c0000644000131400013140000002014511531672132012512 00000000000000/* * This code implements the MD5 message-digest algorithm. * The algorithm is due to Ron Rivest. This code was * written by Colin Plumb in 1993, no copyright is claimed. * This code is in the public domain; do with it what you wish. * * Equivalent code is available from RSA Data Security, Inc. * This code has been tested against that, and is equivalent, * except that you don't need to include two pages of legalese * with every copy. * * To compute the message digest of a chunk of bytes, declare an * MD5Context structure, pass it to MD5Init, call MD5Update as * needed on buffers full of bytes, and then call MD5Final, which * will fill a supplied 16-byte array with the digest. * * Changed 2007 by Bernhard R. Link for usage in LPRng (only * type names and such stuff), still in public domain */ #include #ifdef HAVE_ENDIAN_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include "md5.h" #ifdef __BYTE_ORDER #if __BYTE_ORDER == __LITTLE_ENDIAN #define LITTLE_ENDIAN_FOR_SURE 1 #endif #else #ifdef BYTE_ORDER #if BYTE_ORDER == LITTLE_ENDIAN #define LITTLE_ENDIAN_FOR_SURE 1 #endif #endif #endif #ifdef LITTLE_ENDIAN_FOR_SURE #define byteReverse(buf, len) /* Nothing */ #else static void byteReverse(unsigned char *buf, unsigned longs); /* * Note: this code is harmless on little-endian machines. */ static void byteReverse(unsigned char *buf, unsigned longs) { uint32_t t; do { t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | ((unsigned) buf[1] << 8 | buf[0]); *(uint32_t *) buf = t; buf += 4; } while (--longs); } #endif static void MD5Transform(uint32_t buf[4], uint32_t const in[16]); /* * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious * initialization constants. */ void MD5Init(struct MD5Context *ctx) { ctx->buf[0] = 0x67452301; ctx->buf[1] = 0xefcdab89; ctx->buf[2] = 0x98badcfe; ctx->buf[3] = 0x10325476; ctx->bits[0] = 0; ctx->bits[1] = 0; } /* * Update context to reflect the concatenation of another buffer full * of bytes. */ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) { register uint32_t t; /* Update bitcount */ t = ctx->bits[0]; if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++; /* Carry from low to high */ ctx->bits[1] += len >> 29; t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ /* Handle any leading odd-sized chunks */ if (t) { unsigned char *p = (unsigned char *) ctx->in + t; t = 64 - t; if (len < t) { memcpy(p, buf, len); return; } memcpy(p, buf, t); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += t; len -= t; } /* Process data in 64-byte chunks */ while (len >= 64) { memcpy(ctx->in, buf, 64); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); buf += 64; len -= 64; } /* Handle any remaining bytes of data. */ memcpy(ctx->in, buf, len); } /* * Final wrapup - pad to 64-byte boundary with the bit pattern * 1 0* (64-bit count of bits processed, MSB-first) */ void MD5Final(struct MD5Context *ctx, unsigned char* digest) { unsigned int count; unsigned char *p; /* Compute number of bytes mod 64 */ count = (ctx->bits[0] >> 3) & 0x3F; /* Set the first char of padding to 0x80. This is safe since there is always at least one byte free */ p = ctx->in + count; *p++ = 0x80; /* Bytes of padding needed to make 64 bytes */ count = 64 - 1 - count; /* Pad out to 56 mod 64 */ if (count < 8) { /* Two lots of padding: Pad the first block to 64 bytes */ memset(p, 0, count); byteReverse(ctx->in, 16); MD5Transform(ctx->buf, (uint32_t *) ctx->in); /* Now fill the next block with 56 bytes */ memset(ctx->in, 0, 56); } else { /* Pad block to 56 bytes */ memset(p, 0, count - 8); } byteReverse(ctx->in, 14); /* Append length in bits and transform */ ((uint32_t *) ctx->in)[14] = ctx->bits[0]; ((uint32_t *) ctx->in)[15] = ctx->bits[1]; MD5Transform(ctx->buf, (uint32_t *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); if (digest!=NULL) memcpy(digest, ctx->buf, 16); memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ /* #define F1(x, y, z) (x & y | ~x & z) */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) { register uint32_t a, b, c, d; a = buf[0]; b = buf[1]; c = buf[2]; d = buf[3]; MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); buf[0] += a; buf[1] += b; buf[2] += c; buf[3] += d; } lprng-3.8.B/src/common/sendjob.c0000644000131400013140000005450511531672132013460 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "accounting.h" #include "errorcodes.h" #include "fileopen.h" #include "getqueue.h" #include "user_auth.h" #include "linksupport.h" #include "sendjob.h" #include "sendauth.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * The protocol used to send a job to a remote RemoteHost_DYN consists of the * following: * * Client Server * \2RemotePrinter_DYNname\n - receive a job * \0 (ack) * \2count controlfilename\n * * \0 * \0 * \3count datafilename\n * * \0 * \0 * \3count datafilename\n * * \0 * \0 * * * 1. In order to abort the job transfer, client sends \1 * 2. Anything but a 0 ACK is an error indication * * NB: some spoolers require that the data files be sent first. * The same transfer protocol is followed, but the data files are * send first, followed by the control file. * * The Send_job() routine will try to transfer a control file * to the remote RemoteHost_DYN. It does so using the following algorithm. * * 1. makes a connection (connection timeout) * 2. sends the \2RemotePrinter_DYN and gets ACK (transfer timeout) * 3. sends the control file (transfer timeout) * 4. sends the data files (transfer timeout) * * int Send_job( * struct jobfile *job, - control file * int connect_timeout_len, - timeout on making connection * int connect_interval, - interval between retries * int max_connect_interval - maximum connection interval * int transfer_timeout - maximum time to send * * RETURNS: 0 if successful, non-zero if not **************************************************************************/ static int Send_control( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd ); static int Send_data_files( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd, char *final_filter ); int Send_job( struct job *job, struct job *logjob, int connect_timeout_len, int connect_interval, int max_connect_interval, int transfer_timeout, char *final_filter ) { int sock = -1; /* socket to use */ char *id = 0, *s; char *real_host = 0, *save_host = 0; int status = 0, err, errcount = 0, n, len; char msg[SMALLBUFFER]; char error[LARGEBUFFER], errmsg[SMALLBUFFER]; const struct security *security = 0; struct line_list info; /* fix up the control file */ Init_line_list(&info); if(DEBUGL1)Dump_job("Send_job- starting",job); Errorcode = 0; error[0] = 0; Set_str_value(&job->info,ERROR,0); Set_flag_value(&job->info,ERROR_TIME,0); /* send job to the LPD server for the RemotePrinter_DYN */ id = Find_str_value( &job->info,IDENTIFIER); if( id == 0 ) id = Find_str_value( &job->info,XXCFTRANSFERNAME); DEBUG3("Send_job: '%s'->%s@%s,connect(timeout %d,interval %d)", id, RemotePrinter_DYN, RemoteHost_DYN, connect_timeout_len, connect_interval ); /* determine authentication type to use */ security = Fix_send_auth(0,&info,job, error, sizeof(error) ); if( error[0] ){ status = JFAIL; Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); error[0] = 0; goto error; } if( final_filter && (security || Send_block_format_DYN) ){ status = JABORT; Set_str_value(&job->info,ERROR, "Cannot have user filter with secure or block format transfer"); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } setstatus(logjob, "sending job '%s' to %s@%s", id, RemotePrinter_DYN, RemoteHost_DYN ); retry_connect: error[0] = 0; Set_str_value(&job->info,ERROR,0); Set_flag_value(&job->info,ERROR_TIME,0); setstatus(logjob, "connecting to '%s', attempt %d", RemoteHost_DYN, errcount+1 ); if( (Is_server || errcount) && Network_connect_grace_DYN > 0 ){ plp_sleep( Network_connect_grace_DYN ); } errno = 0; errmsg[0] = 0; sock = Link_open_list( RemoteHost_DYN, &real_host, connect_timeout_len, 0, Unix_socket_path_DYN, errmsg, sizeof(errmsg) ); err = errno; DEBUG4("Send_job: socket %d", sock ); if( sock < 0 ){ ++errcount; status = LINK_OPEN_FAIL; msg[0] = 0; if( !Is_server ){ plp_snprintf( msg, sizeof(msg), "\nMake sure the remote host supports the LPD protocol"); if( geteuid() && getuid() ){ int v = safestrlen(msg); plp_snprintf( msg+v, sizeof(msg)-v, "\nand accepts connections from this host and from non-privileged (>1023) ports"); } } plp_snprintf( error, sizeof(error)-2, "cannot open connection to %s - %s%s", RemoteHost_DYN, errmsg[0]?errmsg:(err?Errormsg(err):"bad or missing hostname?"), msg ); if( Is_server && Retry_NOLINK_DYN ){ if( connect_interval > 0 ){ n = (connect_interval * (1 << (errcount - 1))); if( max_connect_interval && n > max_connect_interval ){ n = max_connect_interval; } if( n > 0 ){ setstatus(logjob, _("sleeping %d secs before retry, starting sleep"),n ); plp_sleep( n ); } } goto retry_connect; } setstatus(logjob, error ); goto error; } save_host = safestrdup(RemoteHost_DYN,__FILE__,__LINE__); Set_DYN(&RemoteHost_DYN, real_host ); if( real_host ) free( real_host ); setstatus(logjob, "connected to '%s'", RemoteHost_DYN ); if( security && security->client_connect ){ status = security->client_connect( job, &sock, transfer_timeout, error, sizeof(error), security, &info ); if( status ) goto error; } if( security && security->client_send ){ status = Send_auth_transfer( &sock, transfer_timeout, job, logjob, error, sizeof(error)-1, 0, security, &info ); } else if( Send_block_format_DYN ){ status = Send_block( &sock, job, logjob, transfer_timeout ); } else { status = Send_normal( &sock, job, logjob, transfer_timeout, 0, final_filter ); } DEBUG2("Send_job: after sending, status %d, error '%s'", status, error ); if( status ) goto error; setstatus(logjob, "done job '%s' transfer to %s@%s", id, RemotePrinter_DYN, RemoteHost_DYN ); error: if( sock >= 0 ) sock = Shutdown_or_close(sock); if( status ){ if( (s = Find_str_value(&job->info,ERROR )) ){ setstatus(logjob, "job '%s' transfer to %s@%s failed\n %s", id, RemotePrinter_DYN, RemoteHost_DYN, s ); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } DEBUG2("Send_job: sock is %d", sock); if( sock >= 0 ){ len = 0; msg[0] = 0; n = 0; while( len < (int)sizeof(msg)-1 && (n = Read_fd_len_timeout(Send_job_rw_timeout_DYN, sock,msg+len,sizeof(msg)-len-1)) > 0 ){ msg[len+n] = 0; DEBUG2("Send_job: read %d, '%s'", n, msg); while( (s = safestrchr(msg,'\n')) ){ *s++ = 0; setstatus(logjob, "error msg: '%s'", msg ); memmove(msg,s,safestrlen(s)+1); } len = safestrlen(msg); } DEBUG2("Send_job: read %d, '%s'", n, msg); if( len ) setstatus(logjob, "error msg: '%s'", msg ); } } if( sock >= 0 ) close(sock); sock = -1; if( save_host ){ Set_DYN(&RemoteHost_DYN,save_host); free(save_host); save_host = 0; } Free_line_list(&info); return( status ); } /*************************************************************************** * int Send_normal( * int sock, - socket to use * struct job *job, struct job *logjob, - control file * int transfer_timeout, - transfer timeout * ) - acknowlegement status * * 1. send the \2RemotePrinter_DYN\n string to the remote RemoteHost_DYN, wait for an ACK * * 2. if control file first, send the control file: * send \3count cfname\n * get back <0> ack * send 'count' file bytes * send <0> term * get back <0> ack * 3. for each data file * send the \4count dfname\n * Note: count is 0 if file is filter * get back <0> ack * send 'count' file bytes * Close socket and finish if filter * send <0> term * get back <0> ack * 4. If control file last, send the control file as in step 2. * * * If the block_fd parameter is non-zero, we write out the * control and data information to a file instead. * ***************************************************************************/ int Send_normal( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd, char *final_filter ) { char status = 0, *id, *transfername; char line[SMALLBUFFER]; char error[SMALLBUFFER]; int ack; DEBUG3("Send_normal: send_data_first %d, sock %d, block_fd %d", Send_data_first_DYN, *sock, block_fd ); id = Find_str_value(&job->info,IDENTIFIER); transfername = Find_str_value(&job->info,XXCFTRANSFERNAME); if( !block_fd ){ setstatus(logjob, "requesting printer %s@%s", RemotePrinter_DYN, RemoteHost_DYN ); plp_snprintf( line, sizeof(line), "%c%s\n", REQ_RECV, RemotePrinter_DYN ); ack = 0; if( (status = Link_send( RemoteHost_DYN, sock, transfer_timeout, line, safestrlen(line), &ack ) )){ char *v; if( (v = safestrchr(line,'\n')) ) *v = 0; if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending str '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), line, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending str '%s' to %s@%s", Link_err_str(status), line, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); return(status); } } if( !block_fd && Send_data_first_DYN ){ status = Send_data_files( sock, job, logjob, transfer_timeout, block_fd, final_filter ); if( !status ) status = Send_control( sock, job, logjob, transfer_timeout, block_fd ); } else { status = Send_control( sock, job, logjob, transfer_timeout, block_fd ); if( !status ) status = Send_data_files( sock, job, logjob, transfer_timeout, block_fd, final_filter ); } return(status); } static int Send_control( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd ) { char msg[SMALLBUFFER]; char error[SMALLBUFFER]; int status = 0, size, ack, err; char *cf = 0, *transfername = 0, *s; /* * get the total length of the control file */ if( !(cf = Find_str_value(&job->info,CF_OUT_IMAGE)) ){ Errorcode = JABORT; fatal(LOG_ERR, "Send_control: LOGIC ERROR! missing CF_OUT_IMAGE"); } size = safestrlen(cf); transfername = Find_str_value(&job->info,XXCFTRANSFERNAME); DEBUG3( "Send_control: '%s' is %d bytes, sock %d, block_fd %d, cf '%s'", transfername, size, *sock, block_fd, cf ); if( !block_fd ){ setstatus(logjob, "sending control file '%s' to %s@%s", transfername, RemotePrinter_DYN, RemoteHost_DYN ); } ack = 0; errno = 0; error[0] = 0; plp_snprintf( msg, sizeof(msg), "%c%d %s\n", CONTROL_FILE, size, transfername); if( !block_fd ){ if( (status = Link_send( RemoteHost_DYN, sock, transfer_timeout, msg, safestrlen(msg), &ack )) ){ if( (s = safestrchr(msg,'\n')) ) *s = 0; if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending str '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), msg, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending str '%s' to %s@%s", Link_err_str(status), msg, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); status = JFAIL; goto error; } } else { if( Write_fd_str( block_fd, msg ) < 0 ){ goto write_error; } } /* * send the control file */ errno = 0; if( block_fd == 0 ){ /* we include the 0 at the end */ ack = 0; if( (status = Link_send( RemoteHost_DYN, sock, transfer_timeout, cf,size+1,&ack )) ){ if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending control file '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), transfername, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending control file '%s' to %s@%s", Link_err_str(status), transfername, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); status = JFAIL; goto error; } DEBUG3( "Send_control: control file '%s' sent", transfername ); setstatus(logjob, "completed sending '%s' to %s@%s", transfername, RemotePrinter_DYN, RemoteHost_DYN ); } else { if( Write_fd_str( block_fd, cf ) < 0 ){ goto write_error; } } status = 0; goto error; write_error: err = errno; plp_snprintf(error,sizeof(error), "job '%s' write to temporary file failed '%s'", transfername, Errormsg( err ) ); Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); status = JFAIL; error: return(status); } static int Send_data_files( int *sock, struct job *job, struct job *logjob, int transfer_timeout, int block_fd, char *final_filter ) { int count, fd, err, status = 0, ack; double size; struct line_list *lp; const char *openname, *transfername, *id; char *s; char msg[SMALLBUFFER]; char error[SMALLBUFFER]; struct stat statb; DEBUG3( "Send_data_files: data file count '%d'", job->datafiles.count ); id = Find_str_value(&job->info,IDENTIFIER); if( id == 0 ) id = Find_str_value(&job->info,XXCFTRANSFERNAME); for( count = 0; count < job->datafiles.count; ++count ){ lp = (void *)job->datafiles.list[count]; if(DEBUGL3)Dump_line_list("Send_data_files - entries",lp); transfername = Find_str_value(lp,DFTRANSFERNAME); openname = Find_str_value(lp,OPENNAME); if( !openname ) openname = transfername; DEBUG3("Send_data_files: opening file '%s', transfername '%s'", openname, transfername ); /* * open file as user; we should be running as user */ size = 0; if( !strcmp(openname,"-") ){ openname = "(STDIN)"; fd = 0; size = 0; } else { fd = Checkread( openname, &statb ); if( fd < 0 ){ status = JFAILNORETRY; plp_snprintf(error,sizeof(error), "cannot open '%s' - '%s'", openname, Errormsg(errno) ); Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } if( statb.st_size == 0 ){ plp_snprintf(error,sizeof(error), "zero length file '%s'", transfername ); status = JABORT; Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } size = statb.st_size; } if( count == job->datafiles.count -1 && final_filter ){ size = 0; } DEBUG3( "Send_data_files: openname '%s', fd %d, size %0.0f", openname, fd, size ); /* * send the data file name line */ plp_snprintf( msg, sizeof(msg), "%c%0.0f %s\n", DATA_FILE, size, transfername ); if( block_fd == 0 ){ setstatus(logjob, "sending data file '%s' to %s@%s", transfername, RemotePrinter_DYN, RemoteHost_DYN ); DEBUG3("Send_data_files: data file msg '%s'", msg ); errno = 0; if( (status = Link_send( RemoteHost_DYN, sock, transfer_timeout, msg, safestrlen(msg), &ack )) ){ if( (s = safestrchr(msg,'\n')) ) *s = 0; if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending str '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), msg, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending str '%s' to %s@%s", Link_err_str(status), msg, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } /* * send the data files content */ DEBUG3("Send_data_files: transfering '%s', fd %d", openname, fd ); ack = 0; if( count == job->datafiles.count-1 && final_filter ){ status = Filter_file( transfer_timeout, fd, *sock, "UserFilter", final_filter, Filter_options_DYN, job, 0, 1 ); DEBUG3("Send_data_files: final_filter '%s' status %d", final_filter, status ); close(fd); fd = 0; } else { status = Link_copy( RemoteHost_DYN, sock, 0, transfer_timeout, openname, fd, size ); } /* special case - cannot read error code from other end */ if( fd == 0 ){ close(*sock); *sock = -1; } if( status || ( fd !=0 && (status = Link_send( RemoteHost_DYN,sock, transfer_timeout,"",1,&ack )) ) ){ if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending data file '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), transfername, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending data file '%s' to %s@%s", Link_err_str(status), transfername, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } setstatus(logjob, "completed sending '%s' to %s@%s", transfername, RemotePrinter_DYN, RemoteHost_DYN ); } else { double total; int len; if( Write_fd_str( block_fd, msg ) < 0 ){ goto write_error; } /* now we need to read the file and transfer it */ total = 0; while( total < size && (len = Read_fd_len_timeout(Send_job_rw_timeout_DYN, fd, msg, sizeof(msg))) > 0 ){ if( write( block_fd, msg, len ) < 0 ){ goto write_error; } total += len; } if( total != size ){ plp_snprintf(error,sizeof(error), "job '%s' did not copy all of '%s'", id, transfername ); status = JFAIL; Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); goto error; } } close(fd); fd = -1; } goto error; write_error: err = errno; plp_snprintf(error,sizeof(error), "job '%s' write to temporary file failed '%s'", id, Errormsg( err ) ); Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); status = JFAIL; error: return(status); } /*************************************************************************** * int Send_block( * char *RemoteHost_DYN, - RemoteHost_DYN name * char *RemotePrinter_DYN, - RemotePrinter_DYN name * char *dpathname *dpath - spool directory pathname * int *sock, - socket to use * struct job *job, struct job *logjob, - control file * int transfer_timeout, - transfer timeout * ) - acknowlegement status * * 1. Get a temporary file * 2. Generate the compressed data files - this has the format * \3count cfname\n * [count control file bytes] * \4count dfname\n * [count data file bytes] * * 3. send the \6RemotePrinter_DYN size\n * string to the remote RemoteHost_DYN, wait for an ACK * * 4. send the compressed data files * wait for an ACK * ***************************************************************************/ int Send_block( int *sock, struct job *job, struct job *logjob, int transfer_timeout ) { int tempfd; /* temp file for data transfer */ char msg[SMALLBUFFER]; /* buffer */ char error[SMALLBUFFER]; /* buffer */ struct stat statb; double size; /* ACME! The best... */ int status = 0; /* job status */ int ack; char *id, *transfername, *tempfile; error[0] = 0; id = Find_str_value(&job->info,IDENTIFIER); transfername = Find_str_value(&job->info,XXCFTRANSFERNAME); if( id == 0 ) id = transfername; tempfd = Make_temp_fd( &tempfile ); DEBUG1("Send_block: sending '%s' to '%s'", id, tempfile ); status = Send_normal( &tempfd, job, logjob, transfer_timeout, tempfd, 0 ); DEBUG1("Send_block: sendnormal of '%s' returned '%s'", id, Server_status(status) ); if( status ) return( status ); /* rewind the file */ if( lseek( tempfd, 0, SEEK_SET ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Send_files: lseek tempfd failed" ); } /* now we have the copy, we need to send the control message */ if( fstat( tempfd, &statb ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Send_files: fstat tempfd failed" ); } size = statb.st_size; /* now we know the size */ DEBUG3("Send_block: size %0.0f", size ); setstatus(logjob, "sending job '%s' to %s@%s, block transfer", id, RemotePrinter_DYN, RemoteHost_DYN ); plp_snprintf( msg, sizeof(msg), "%c%s %0.0f\n", REQ_BLOCK, RemotePrinter_DYN, size ); DEBUG3("Send_block: sending '%s'", msg ); status = Link_send( RemoteHost_DYN, sock, transfer_timeout, msg, safestrlen(msg), &ack ); DEBUG3("Send_block: status '%s'", Link_err_str(status) ); if( status ){ char *v; if( (v = safestrchr(msg,'\n')) ) *v = 0; if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending str '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), msg, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending str '%s' to %s@%s", Link_err_str(status), msg, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); return(status); } /* now we send the data file, followed by a 0 */ DEBUG3("Send_block: sending data" ); ack = 0; status = Link_copy( RemoteHost_DYN, sock, 0, transfer_timeout, transfername, tempfd, size ); DEBUG3("Send_block: status '%s'", Link_err_str(status) ); if( status == 0 ){ status = Link_send( RemoteHost_DYN,sock,transfer_timeout,"",1,&ack ); DEBUG3("Send_block: ack status '%s'", Link_err_str(status) ); } if( status ){ char *v; if( (v = safestrchr(msg,'\n')) ) *v = 0; if( ack ){ plp_snprintf(error,sizeof(error), "error '%s' with ack '%s'\n sending block file '%s' to %s@%s", Link_err_str(status), Ack_err_str(ack), id, RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf(error,sizeof(error), "error '%s'\n sending block file '%s' to %s@%s", Link_err_str(status), id, RemotePrinter_DYN, RemoteHost_DYN ); } Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); return(status); } else { setstatus(logjob, "completed sending '%s' to %s@%s", id, RemotePrinter_DYN, RemoteHost_DYN ); } close( tempfd ); tempfd = -1; return( status ); } lprng-3.8.B/src/common/globmatch.c0000644000131400013140000000565611531672131013776 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "globmatch.h" /**** ENDINCLUDE ****/ static int glob_pattern( const char *pattern, const char *str ) { int result = 1; int len, c, invert; char *glob; /* DEBUG4("glob_pattern: pattern '%s' to '%s'", pattern, str ); */ if( (glob = safestrpbrk( pattern, "*?[" )) ){ /* check the characters up to the glob length for a match */ len = glob - pattern; c = *glob; /* DEBUG4("glob_pattern: meta '%c', len %d", c, len ); */ if( (len == 0 || !safestrncasecmp( pattern, str, len )) ){ /* matched: pattern xxxx* to xxxx * now we have to do the remainder. We simply check for rest */ pattern += len+1; str += len; /* DEBUG4("glob_pattern: rest of pattern '%s', str '%s'", pattern, str ); */ /* check for trailing glob */ if( c == '?' ){ if( *str ){ result = glob_pattern( pattern, str+1 ); } else { result = 1; } } else if( c == '[' ){ /* now we check for the characters in the pattern * this can have the format N or N-M */ glob = safestrchr( pattern, ']' ); if( glob == 0 ){ return( 1 ); } len = glob - pattern; invert = c = 0; /* DEBUG4("globmatch: now case '%s', len %d", pattern, len ); */ if( len > 0 && (invert = (*pattern == '^')) ){ --len; ++pattern; } while( result && len > 0 ){ /* DEBUG4("globmatch: c '0x%x', pat '%c', str '%c'", c, *pattern, *str ); */ if( c && *pattern == '-' && len > 1 ){ /* we have preceeding, get end */ pattern++; --len; while( result && c <= *pattern ){ /* DEBUG4("globmatch: range c '%c', pat '%c', str '%c'", c, *pattern, *str ); */ result = (*str != c++); } pattern++; --len; c = 0; } else { c = *pattern++; --len; result = (*str != c); } } if( invert ) result = !result; /* DEBUG4("globmatch: after pattern result %d", result); */ if( result == 0 ){ pattern += len+1; ++str; /* at this point pattern is past */ result = glob_pattern( pattern, str ); } } else if( pattern[0] ){ while( *str && (result = glob_pattern( pattern, str )) ){ ++str; } } else { result = 0; } } } else { result = safestrcasecmp( pattern, str ); } return( result ); } int Globmatch( const char *pattern, const char *str ) { int result; /* try simple test first: string compare */ /* DEBUG4("Globmatch: pattern '%s' to '%s'", pattern, str ); */ if( pattern == 0 ) pattern = ""; if( str == 0 ) str = ""; result = glob_pattern( pattern, str ); DEBUG4("Globmatch: '%s' to '%s' result %d", pattern, str, result ); return( result ); } lprng-3.8.B/src/common/lpstat.c0000644000131400013140000004510311531672132013335 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * *************************************************************************** * MODULE: lpstat.c * PURPOSE: **************************************************************************/ /*************************************************************************** * SYNOPSIS * lpstat [-d] [-r] [-R] [-s] [-t] [-a [list * ] ] [-c [list] ] [-f [list] [-l] ] [-o [ * list] ] [-p [list] [-D] [-l] ] [-S [list * ] [-l] ] [-u [login- ID -list ] ] [-v [list] * ] * * lpstat * DESCRIPTION * lpstat sends a status request to lpd(8) * See lpstat for details on the way that status is gathered. * The lpstat version simulates the lpstat operation, * using the information returned by LPRng in response to a verbose query. * **************************************************************************** * */ #include "lp.h" #include "child.h" #include "getopt.h" #include "getprinter.h" #include "initialize.h" #include "linksupport.h" #include "sendreq.h" #include "user_auth.h" /**** ENDINCLUDE ****/ #undef EXTERN #undef DEFINE #define EXTERN #define DEFINE(X) X #include "lpstat.h" /**** ENDINCLUDE ****/ static int A_flag, P_flag, R_flag, S_flag, a_flag, c_flag, d_flag, f_flag, l_flag, n_flag, o_flag, p_flag, r_flag, s_flag, t_flag, u_flag, v_flag, flag_count, D_flag, Found_flag; static char *S_val, *a_val, *c_val, *f_val, *o_val, *p_val, *u_val, *v_val; static struct line_list S_list, f_list; int Rawformat; static void usage(void) { FPRINTF( STDERR, "usage: %s [-A] [-d] [-l] [-r] [-R] [-s] [-t] [-a [list]]\n" " [-c [list]] [-f [list]] [-o [list]]\n" " [-p [list]] [-P] [-S [list]] [list]\n" " [-u [login-ID-list]] [-v [list]] [-V] [-n] [-Tdbgflags]\n" " list is a list of print queues\n" " -A use authentication specified by AUTH environment variable\n" " -a [list] destination status *\n" " -c [list] class status *\n" " -d print default destination\n" " -f [list] forms status *\n" " -o [list] job or printer status *\n" " -n each -n increases number of status lines (default 1) *\n" " -N maximum number of status lines *\n" " -p [list] printer status *\n" " -P paper types - ignored\n" " -r scheduler status\n" " -s summary status information - short format\n" " -S [list] character set - ignored\n" " -t all status information - long format\n" " -u [joblist] job status information\n" " -v [list] printer mapping *\n" " -V verbose mode \n" " -Tdbgflags debug flags\n" " * - long status format produced\n", Name); { char buffer[128]; FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); } Parse_debug("=",-1); FPRINTF( STDOUT, "%s\n", Version ); exit(1); } /*************************************************************************** * main() * - top level of LPQ * ****************************************************************************/ int main(int argc, char *argv[], char *envp[]) { int i; struct line_list l, options, request_list; char *s; Init_line_list(&l); Init_line_list(&options); Init_line_list(&request_list); /* set signal handlers */ (void) plp_signal (SIGHUP, cleanup_HUP); (void) plp_signal (SIGINT, cleanup_INT); (void) plp_signal (SIGQUIT, cleanup_QUIT); (void) plp_signal (SIGTERM, cleanup_TERM); (void) signal(SIGCHLD, SIG_DFL); (void) signal(SIGPIPE, SIG_IGN); /* * set up the user state */ Status_line_count = 1; #ifndef NODEBUG Debug = 0; #endif Displayformat = REQ_DLONG; Initialize(argc, argv, envp, 'T' ); Setup_configuration(); Get_parms(argc, argv ); /* scan input args */ if( A_flag && !getenv( "AUTH" ) ){ FPRINTF(STDERR, _("authentication requested (-A option) and AUTH environment variable not set") ); usage(); } /* set up configuration */ Get_printer(); Fix_Rm_Rp_info(0,0); Get_all_printcap_entries(); /* check on printing scheduler is running */ if( t_flag ){ All_printers = 1; r_flag = d_flag = p_flag = o_flag = 1; s_flag = 0; } if( s_flag ){ /* a_flag = 1; */ r_flag = 1; d_flag = 1; v_flag = 1; All_printers = 1; } if( All_printers ){ Merge_line_list( &request_list, &All_line_list,0,0,0); } Merge_line_list( &request_list, &Printer_list,0,0,0); Check_max(&options,2); if( options.count ){ for( i = options.count; i > 0 ; --i ){ options.list[i] = options.list[i-1]; } options.list[0] = safestrdup(Logname_DYN,__FILE__,__LINE__); ++options.count; } options.list[options.count] = 0; if( Found_flag == 0 ){ if( request_list.count == 0 ){ Split(&request_list,Printer_DYN,", ",1,0,1,1,0,0); } o_flag = 1; flag_count = 1; } if(DEBUGL1)Dump_line_list("lpstat - printer request list", &request_list); if(DEBUGL1)Dump_line_list("lpstat - options", &options); if( r_flag ){ Write_fd_str(1,_("scheduler is running\n")); } if( d_flag ){ if( Printer_DYN == 0 ){ Write_fd_str(1,_("no system default destination\n")); } else { safefprintf(1, _("system default destination: %s\n"), Printer_DYN); } } if( v_flag ){ for( i = 0; i < request_list.count; ++i ){ Set_DYN(&Printer_DYN,request_list.list[i] ); Fix_Rm_Rp_info(0,0); safefprintf(1, _("system for %s: %s\n"), Printer_DYN, RemoteHost_DYN); } } /* see if additional status required */ Free_line_list( &Printer_list ); for( i = 0; i < request_list.count; ++i ){ s = request_list.list[i]; Set_DYN(&Printer_DYN,s ); Show_status(0); } Free_line_list( &Printer_list ); if( flag_count ){ for( i = 0; i < request_list.count; ++i ){ s = request_list.list[i]; Set_DYN(&Printer_DYN,s ); Show_status(1); } } DEBUG1("lpstat: done"); Remove_tempfiles(); DEBUG1("lpstat: tempfiles removed"); Errorcode = 0; DEBUG1("lpstat: cleaning up"); return(0); } static void Show_status(int display_format) { int fd; DEBUG1("Show_status: start"); /* set up configuration */ Fix_Rm_Rp_info(0,0); if( Check_for_rg_group( Logname_DYN ) ){ if( safefprintf(1, _(" Printer: %s - cannot use printer, not in privileged group\n"), Printer_DYN ) < 0 ) cleanup(0); return; } if( A_flag ){ Set_DYN(&Auth_DYN, getenv("AUTH")); } if( Direct_DYN && Lp_device_DYN ){ if( safefprintf(1, _(" Printer: %s - direct connection to device '%s'\n"), Printer_DYN, Lp_device_DYN ) < 0 ) cleanup(0); return; } fd = Send_request( 'Q', Displayformat, 0, Connect_timeout_DYN, Send_query_rw_timeout_DYN, 1 ); if( fd >= 0 ){ /* shutdown( fd, 1 ); */ Read_status_info( RemoteHost_DYN, fd, 1, Send_query_rw_timeout_DYN, display_format, Status_line_count ); close(fd); fd = -1; } DEBUG1("Show_status: end"); } /*************************************************************************** *int Read_status_info( int ack, int fd, int timeout ); * ack = ack character from remote site * sock = fd to read status from * char *host = host we are reading from * int output = output fd * We read the input in blocks, split up into lines. * We run the status through the SNPRINTF() routine, which will * rip out any unprintable characters. This will prevent magic escape * string attacks by users putting codes in job names, etc. ***************************************************************************/ int Read_status_info( char *host, int sock, int output, int timeout, int display_format, int status_line_count ) { int i, j, len, n, status, count, index_list, same; char buffer[SMALLBUFFER], header[SMALLBUFFER]; char *s, *t; struct line_list l; int look_for_pr = 0; Init_line_list(&l); header[0] = 0; status = count = 0; /* long status - trim lines */ DEBUG1("Read_status_info: output %d, timeout %d, dspfmt %d", output, timeout, display_format ); DEBUG1("Read_status_info: status_line_count %d", status_line_count ); buffer[0] = 0; do { DEBUG1("Read_status_info: look_for_pr %d, in buffer already '%s'", look_for_pr, buffer ); if( DEBUGL2 )Dump_line_list("Read_status_info - starting list", &l ); count = safestrlen(buffer); n = sizeof(buffer)-count-1; status = 1; if( n > 0 ){ status = Link_read( host, &sock, timeout, buffer+count, &n ); DEBUG1("Read_status_info: Link_read status %d, read %d", status, n ); } if( status || n <= 0 ){ status = 1; buffer[count] = 0; } else { buffer[count+n] = 0; } DEBUG1("Read_status_info: got '%s'", buffer ); /* now we have to split line up */ if( (s = safestrrchr(buffer,'\n')) ){ *s++ = 0; /* add the lines */ Split(&l,buffer,Line_ends,0,0,0,0,0,0); memmove(buffer,s,safestrlen(s)+1); } if( DEBUGL2 )Dump_line_list("Read_status_info - status after splitting", &l ); if( status ){ if( buffer[0] ){ Add_line_list(&l,buffer,0,0,0); buffer[0] = 0; } Check_max(&l,1); l.list[l.count++] = 0; } index_list = 0; again: DEBUG2("Read_status_info: look_for_pr '%d'", look_for_pr ); if( DEBUGL2 )Dump_line_list("Read_status_info - starting, Printer_list", &Printer_list); while( look_for_pr && index_list < l.count ){ s = l.list[index_list]; if( s == 0 || isspace(cval(s)) || !(t = strstr(s,"Printer:")) || Find_exists_value(&Printer_list,t,0) ){ ++index_list; } else { DEBUG2("Read_status_info: printer found [%d] '%s', total %d", index_list, s, l.count ); look_for_pr = 0; } } while( index_list < l.count && (s = l.list[index_list]) ){ DEBUG2("Read_status_info: checking [%d] '%s', total %d", index_list, s, l.count ); if( s && !isspace(cval(s)) && (t = strstr(s,"Printer:")) ){ DEBUG2("Read_status_info: printer heading '%s'", t ); if( Find_exists_value(&Printer_list,t,0) ){ DEBUG2("Read_status_info: already done '%s'", t ); ++index_list; look_for_pr = 1; goto again; } Add_line_list(&Printer_list,t,0,1,0); /* parse the printer line */ if( (t = strchr(t, ':')) ){ ++t; while( isspace(cval(t)) ) ++t; Set_DYN(&Printer_DYN,t ); for( t = Printer_DYN; !ISNULL(t) && !isspace(cval(t)); ++t ); if( isspace(cval(t)) ) *t = 0; } if( display_format == 0 ){ int err; int nospool, noprint; nospool = (strstr( s, "(spooling disabled)") != 0); noprint = (strstr( s, "(printing disabled)") != 0); /* Write_fd_str( output, "ANALYZE " ); if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); */ if( a_flag ){ err = safefprintf(output, nospool? _("%s not accepting requests since %s -\n\tunknown reason\n") : _("%s accepting requests since %s\n"), Printer_DYN, Time_str(0,0)); if( err < 0 ) return(1); } if( p_flag ){ err = safefprintf(output, noprint? _("printer %s unknown state. disabled since %s. available\n"): _("printer %s unknown state. enabled since %s. available\n"), Printer_DYN, Pretty_time(0)); if( err < 0 ) return(1); } if( p_flag && D_flag ){ err = safefprintf(output, _("\tDescription: %s@%s\n"), RemotePrinter_DYN, RemoteHost_DYN); if( err < 0 ) return(1); } } else { if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); } ++index_list; continue; } if( display_format == 0 ){ ++index_list; continue; } if( status_line_count > 0 ){ /* * starting at line_index, we take this as the header. * then we check to see if there are at least status_line_count there. * if there are, we will increment status_line_count until we get to * the end of the reading (0 string value) or end of list. */ header[0] = 0; strncpy( header, s, sizeof(header)-1); header[sizeof(header)-1] = 0; if( (s = strchr(header,':')) ){ *++s = 0; } len = safestrlen(header); /* find the last status_line_count lines */ same = 1; for( i = index_list+1; i < l.count ; ++i ){ same = !safestrncmp(l.list[i],header,len); DEBUG2("Read_status_info: header '%s', len %d, to '%s', same %d", header, len, l.list[i], same ); if( !same ){ break; } } /* if they are all the same, then we save for next pass */ /* we print the i - status_line count to i - 1 lines */ j = i - status_line_count; if( index_list < j ) index_list = j; DEBUG2("Read_status_info: header '%s', index_list %d, last %d, same %d", header, index_list, i, same ); if( same ) break; while( index_list < i ){ DEBUG2("Read_status_info: writing [%d] '%s'", index_list, l.list[index_list]); if( Write_fd_str( output, l.list[index_list] ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); ++index_list; } } else { if( Write_fd_str( output, s ) < 0 || Write_fd_str( output, "\n" ) < 0 ) return(1); ++index_list; } } DEBUG2("Read_status_info: at end index_list %d, count %d", index_list, l.count ); for( i = 0; i < l.count && i < index_list; ++i ){ if( l.list[i] ) free( l.list[i] ); l.list[i] = 0; } for( i = 0; index_list < l.count ; ++i, ++index_list ){ l.list[i] = l.list[index_list]; } l.count = i; } while( status == 0 ); Free_line_list(&l); DEBUG1("Read_status_info: done" ); return(0); } static int Add_val( char **var, char *val ) { int c = 0; if( val && cval(val) != '-' ){ c = 1; if( *var ){ *var = safeextend3(*var,",",val,__FILE__,__LINE__); } else { *var = safestrdup(val,__FILE__,__LINE__); } } return(c); } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ void Get_parms(int argc, char *argv[] ) { int i; char *name, *s; if( argv[0] && (name = strrchr( argv[0], '/' )) ) { ++name; } else { name = argv[0]; } Name = name; /* SYNOPSIS lpstat [-A] [ -d ] [ -r ] [ -R ] [ -s ] [ -t ] [ -a [list] ] [ -c [list] ] [ -f [list] [ -l ] ] [ -o [list] ] [ -p [list] [ -D] [ -l ] ] [ -P ] [ -S [list] [ -l ] ] [ -u [login-ID-list] ] [ -v [list] ] [-n linecount] [-Tdebug] */ flag_count = 0; for( i = 1; i < argc; ++i ){ s = argv[i]; if( cval(s) == '-' ){ Found_flag = 1; switch( cval(s+1) ){ case 'd': d_flag = 1; if(cval(s+2)) usage(); break; case 'D': D_flag = 1; if(cval(s+2)) usage(); break; case 'r': r_flag = 1; if(cval(s+2)) usage(); break; case 'A': A_flag = 1; if(cval(s+2)) usage(); break; case 'R': R_flag = 1; if(cval(s+2)) usage(); break; case 's': s_flag = 1; if(cval(s+2)) usage(); break; case 't': ++flag_count; t_flag = 1; if(cval(s+2)) usage(); break; case 'l': l_flag = 1; if(cval(s+2)) usage(); break; case 'n': n_flag += 1; if(cval(s+2)) usage(); break; case 'N': n_flag = -1; if(cval(s+2)) usage(); break; case 'P': P_flag = 1; if(cval(s+2)) usage(); break; case 'a': a_flag = 1; if( cval(s+2) ) Add_val(&a_val,s+2); else { i += Add_val(&a_val,argv[i+1]); } break; case 'c': ++flag_count; c_flag = 1; if( cval(s+2) ) Add_val(&c_val,s+2); else { i += Add_val(&c_val,argv[i+1]); } break; case 'f': ++flag_count; f_flag = 1; if( cval(s+2) ) Add_val(&f_val,s+2); else { i += Add_val(&f_val,argv[i+1]); } break; case 'o': ++flag_count; o_flag = 1; if( cval(s+2) ) Add_val(&o_val,s+2); else { i += Add_val(&o_val,argv[i+1]); } break; case 'p': ++flag_count; p_flag = 1; if( cval(s+2) ) Add_val(&p_val,s+2); else { i += Add_val(&p_val,argv[i+1]); } break; case 'S': ++flag_count; S_flag = 1; if( cval(s+2) ) Add_val(&S_val,s+2); else { i += Add_val(&S_val,argv[i+1]); } break; case 'u': ++flag_count; u_flag = 1; if( cval(s+2) ) Add_val(&u_val,s+2); else { i += Add_val(&u_val,argv[i+1]); } break; case 'v': v_flag = 1; if( cval(s+2) ) Add_val(&v_val,s+2); else { i += Add_val(&v_val,argv[i+1]); } break; case 'V': Verbose = 1; break; case 'T': if(!cval(s+2)) usage(); Parse_debug( s+2, 1 ); break; default: usage(); break; } } else { break; } if(DEBUGL1){ LOGDEBUG("A_flag %d, D_flag %d, d_flag %d, r_flag %d, R_flag %d, s_flag %d, t_flag %d, l_flag %d, P_flag %d", A_flag, D_flag, d_flag, r_flag, R_flag, s_flag, t_flag, l_flag, P_flag ); LOGDEBUG("a_flag %d, a_val '%s'", a_flag, a_val ); LOGDEBUG("c_flag %d, c_val '%s'", c_flag, c_val ); LOGDEBUG("f_flag %d, f_val '%s'", f_flag, f_val ); LOGDEBUG("o_flag %d, o_val '%s'", o_flag, o_val ); LOGDEBUG("p_flag %d, p_val '%s'", p_flag, p_val ); LOGDEBUG("S_flag %d, S_val '%s'", S_flag, S_val ); LOGDEBUG("u_flag %d, u_val '%s'", u_flag, u_val ); LOGDEBUG("v_flag %d, v_val '%s'", v_flag, v_val ); LOGDEBUG("n_flag %d", n_flag ); } } for( ; i < argc; ++i ){ Add_line_list( &Printer_list, argv[i], 0, 1, 1 ); } #undef SX #define SX(X,Y,Z) \ Split(&Z,((X)&&!(Y))?"all":Y,", ",1,0,1,1,0,0); SX(a_flag,a_val,Printer_list); SX(c_flag,c_val,Printer_list); SX(f_flag,f_val,f_list); SX(o_flag,o_val,Printer_list); SX(p_flag,p_val,Printer_list); SX(S_flag,S_val,S_list); SX(u_flag,u_val,Printer_list); SX(v_flag,v_val,Printer_list); #undef SX if( n_flag ){ if( n_flag < 0 ){ Status_line_count = -1; } else { Status_line_count = (1 << n_flag); } } if( Verbose ) { FPRINTF( STDOUT, "%s\n", Version ); if( Verbose > 1 ) Printlist( Copyright, 1 ); } for( i = 0; !All_printers && i < Printer_list.count; ++i ){ s = Printer_list.list[i]; All_printers = !safestrcasecmp(s,"all"); } if(DEBUGL1){ LOGDEBUG("All_printers %d, D_flag %d, d_flag %d, r_flag %d, R_flag %d, s_flag %d, t_flag %d, l_flag %d, P_flag %d", All_printers, D_flag, d_flag, r_flag, R_flag, s_flag, t_flag, l_flag, P_flag ); LOGDEBUG("a_flag %d, a_val '%s'", a_flag, a_val ); LOGDEBUG("c_flag %d, c_val '%s'", c_flag, c_val ); LOGDEBUG("f_flag %d, f_val '%s'", f_flag, f_val ); LOGDEBUG("o_flag %d, o_val '%s'", o_flag, o_val ); LOGDEBUG("p_flag %d, p_val '%s'", p_flag, p_val ); LOGDEBUG("S_flag %d, S_val '%s'", S_flag, S_val ); LOGDEBUG("u_flag %d, u_val '%s'", u_flag, u_val ); LOGDEBUG("v_flag %d, v_val '%s'", v_flag, v_val ); Dump_line_list("lpstat - Printer_list", &Printer_list); } } lprng-3.8.B/src/common/sendreq.c0000644000131400013140000001377011531672132013474 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "child.h" #include "fileopen.h" #include "getqueue.h" #include "linksupport.h" #include "readstatus.h" #include "user_auth.h" #include "sendreq.h" #include "sendauth.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * The protocol used to send requests to a remote host consists of the * following: * * Client Server * - short format * \Xprintername option option\n - request * status\n * .... * status\n * * * The requestor: * 1. makes a connection (connection timeout) * 2. sends the \3printername options line * 3. reads from the connection until nothing left * * int Send_request( char *printer, * name of printer * * char *host, * name of remote host * * int class, * 'Q'= LPQ, 'C'= LPC, M = lprm * * int format, * X value for request * * char **options, * options to send * * int connnect_timeout, * timeout on connection * * int transfer_timeout, * timeout on transfer * * int output ) * output fd * **************************************************************************/ /*************************************************************************** * Send_request * 1. Open connection to remote host * 2. Send a line of the form: * \Xprinter * 3. Read from the connection until closed and echo on fd 1 ***************************************************************************/ int Send_request( int class, /* 'Q'= LPQ, 'C'= LPC, M = lprm */ int format, /* X for option */ char **options, /* options to send */ int connnect_timeout, /* timeout on connection */ int transfer_timeout, /* timeout on transfer */ int output /* output on this FD */ ) { char errormsg[LARGEBUFFER], errmsg[SMALLBUFFER]; char *cmd = 0; int status = -1, sock = -1, err; char *real_host = 0; char *save_host = 0; const struct security *security = 0; struct line_list info; Init_line_list(&info); errormsg[0] = 0; DEBUG1("Send_request: printer '%s', host '%s', format %d", RemotePrinter_DYN, RemoteHost_DYN, format ); DEBUG1("Send_request: connnect_timeout %d, transfer_timeout %d", connnect_timeout, transfer_timeout ); security = Fix_send_auth(0,&info, 0, errormsg, sizeof(errormsg) ); DEBUG1("Send_request: security %s", security?security->name:0 ); if( security ){ DEBUG1("Send_request: security name '%s', tag '%s'", security->name, security->config_tag ); } if( errormsg[0] ){ goto error; } if( islower( class ) ) class = toupper(class); if( Remote_support_DYN ) uppercase( Remote_support_DYN ); if( islower(class) ) class = toupper(class); if( safestrchr( Remote_support_DYN, class ) == 0 ){ const char *m = "unknown"; switch( class ){ case 'R': m = "lpr"; break; case 'M': m = "lprm"; break; case 'Q': m = "lpq"; break; case 'V': m = "lpq -v"; break; case 'C': m = "lpc"; break; } DEBUG1("Send_request: no remote support for %c - '%s' operation", class, m ); if( !Is_server ){ plp_snprintf(errormsg,sizeof(errormsg), _("no network support for '%s' operation"), m); } status = 0; goto error; } cmd = safestrdup2(" ",RemotePrinter_DYN,__FILE__,__LINE__); cmd[0] = format; if( options ){ for( ; options && *options; ++options ){ cmd = safeextend3(cmd," ",*options, __FILE__,__LINE__ ); } } DEBUG1("Send_request: command '%s'", cmd ); cmd = safeextend2(cmd,"\n", __FILE__,__LINE__ ); errno = 0; errmsg[0] = 0; sock = Link_open_list( RemoteHost_DYN, &real_host, connnect_timeout, 0, Unix_socket_path_DYN , errmsg, sizeof(errmsg) ); err = errno; if( sock < 0 ){ plp_snprintf( errormsg, sizeof(errormsg)-2, "cannot open connection - %s", errmsg[0]?errmsg:( err?Errormsg(err):"bad or missing hostname" ) ); if( !Is_server ){ int v = safestrlen(errormsg); plp_snprintf( errormsg+v, sizeof(errormsg)-v, "\nMake sure the remote host supports the LPD protocol"); if( geteuid() && getuid() ){ v = safestrlen(errormsg); plp_snprintf( errormsg+v, sizeof(errormsg)-v, "\nand accepts connections from this host and from non-privileged (>1023) ports"); } } goto error; } DEBUG1("Send_request: socket %d, real host '%s'", sock, real_host ); save_host = safestrdup(RemoteHost_DYN,__FILE__,__LINE__); Set_DYN(&RemoteHost_DYN, real_host ); if( real_host ) free( real_host ); real_host = 0; if( security && security->client_connect ){ DEBUG1("Send_request: security '%s', using connect", security->name ); status = security->client_connect( 0, &sock, transfer_timeout, errormsg, sizeof(errormsg), security, &info ); DEBUG1("Send_request: connect status %d, error '%s'", status, errormsg ); if( status ) goto error; } /* now send the command line */ if( security && security->client_send ){ status = Send_auth_transfer( &sock, transfer_timeout, 0, 0, errormsg, sizeof(errormsg), cmd, security, &info ); } else { status = Link_send( RemoteHost_DYN, &sock, transfer_timeout, cmd, safestrlen(cmd), 0 ); if( status ){ plp_snprintf(errormsg,sizeof(errormsg), "%s",Link_err_str(status)); close(sock); sock = -1; goto error; } } error: if( status || errormsg[0] ){ char line[SMALLBUFFER]; plp_snprintf( line,sizeof(line), "Printer '%s@%s' - ", RemotePrinter_DYN, RemoteHost_DYN ); if( Write_fd_str( output, line ) < 0 || Write_fd_str( output, errormsg ) < 0 || Write_fd_str( output, "\n" ) < 0 ) cleanup(0); } if( save_host ){ Set_DYN(&RemoteHost_DYN,save_host); free(save_host); save_host = 0; } if( cmd ) free(cmd); cmd = 0; Free_line_list(&info); return( sock ); } lprng-3.8.B/src/common/lpc.c0000644000131400013140000003701711531672131012610 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * SYNOPSIS * lpc [ -PPrinter] [-S Server] [-U username ][-V] [-D debug] [command] * commands: * * status [printer] - show printer status (default is all printers) * msg printer .... - printer status message * start [printer] - start printing * stop [printer] - stop printing * up [printer] - start printing and spooling * down [printer] - stop printing and spooling * enable [printer] - enable spooling * disable [printer] - disable spooling * abort [printer] - stop printing, kill server * kill [printer] - stop printing, kill server, restart printer * flush [printer] - flush cached status * * topq printer (user [@host] | host | jobnumer)* * hold printer (all | user [@host] | host | jobnumer)* * release printer (all | user [@host] | host | jobnumer)* * * lprm printer [ user [@host] | host | jobnumber ] * * lpq printer [ user [@host] | host | jobnumber ] * * lpd [pr | pr@host] - PID of LPD server * active [pr |pr@host] - check to see if server accepting connections * client [all | pr ] - show client configuration and printcap info * server [all |pr ] - show server configuration and printcap info * defaultq - show default queue for LPD server\n\ * defaults - show default configuration values\n\ * lang - show current i18n language selection and support\n\ * * DESCRIPTION * lpc sends a request to lpd(8) * and reports the status of the command **************************************************************************** * * Implementation Notes * Patrick Powell Wed Jun 28 21:28:40 PDT 1995 * * The LPC program is an extremely simplified front end to the * LPC functionality in the server. The commands send to the LPD * server have the following format: * * \6printer user command options * * If no printer is specified, the printer is the default from the * environment variable, etc. * */ #include "lp.h" #include "initialize.h" #include "getprinter.h" #include "sendreq.h" #include "child.h" #include "control.h" #include "getopt.h" #include "errorcodes.h" #include "user_auth.h" /**** ENDINCLUDE ****/ /*************************************************************************** * main() * - top level of LPP Lite. * ****************************************************************************/ #undef EXTERN #undef DEFINE #define EXTERN #define DEFINE(X) X #include "lpc.h" static void usage(void); static void use_msg(void); static void doaction( struct line_list *args ); static char *Username_JOB; int main(int argc, char *argv[], char *envp[]) { char *s; int i; char msg[ LINEBUFFER ]; struct line_list args; #if 0 DEBUG1("%s",5); LOGDEBUG("%s",5); fatal(LOGINFO, "%s",5); logerr(LOGINFO, "%s",5); #endif /* set signal handlers */ (void) plp_signal (SIGHUP, cleanup_HUP); (void) plp_signal (SIGINT, cleanup_INT); (void) plp_signal (SIGQUIT, cleanup_QUIT); (void) plp_signal (SIGTERM, cleanup_TERM); (void) signal( SIGPIPE, SIG_IGN ); (void) signal( SIGCHLD, SIG_DFL); /* * set up the user state */ #ifndef NODEBUG Debug = 0; #endif Init_line_list(&args); Initialize(argc, argv, envp, 'D' ); Setup_configuration(); /* scan the argument list for a 'Debug' value */ Get_parms(argc, argv); /* scan input args */ if( Auth && !getenv( "AUTH" ) ){ FPRINTF(STDERR, _("authentication requested (-A option) and AUTH environment variable not set") ); usage(); } DEBUG1("lpc: Printer '%s', Optind '%d', argc '%d'", Printer_DYN, Optind, argc ); if(DEBUGL1){ int ii; for( ii = Optind; ii < argc; ++ii ){ LOGDEBUG( " [%d] '%s'", ii, argv[ii] ); } } if( Username_JOB && OriginalRUID ){ struct line_list user_list; char *str, *t; struct passwd *pw; int found; uid_t uid; DEBUG2("lpc: checking '%s' for -U perms", Allow_user_setting_DYN ); Init_line_list(&user_list); Split( &user_list, Allow_user_setting_DYN,File_sep,0,0,0,0,0,0); found = 0; for( i = 0; !found && i < user_list.count; ++i ){ str = user_list.list[i]; DEBUG2("lpc: checking '%s'", str ); uid = strtol( str, &t, 10 ); if( str == t || *t ){ /* try getpasswd */ pw = getpwnam( str ); if( pw ){ uid = pw->pw_uid; } } DEBUG2( "lpc: uid '%ld'", (long)uid ); found = ( uid == OriginalRUID ); DEBUG2( "lpc: found '%d'", found ); } if( !found ){ DEBUG1( "%s", "-U (username) can only be used by ROOT" ); Username_JOB = 0; } } if( Username_JOB ){ Set_DYN(&Logname_DYN, Username_JOB); } if( Optind < argc ){ for( i = Optind; argv[i]; ++i ){ Add_line_list(&args,argv[i],0,0,0); } Check_max(&args,2); args.list[args.count] = 0; doaction( &args ); } else while(1){ FPRINTF( STDOUT, "lpc>" ); if( fgets( msg, sizeof(msg), stdin ) == 0 ) break; if( (s = safestrchr( msg, '\n' )) ) *s = 0; DEBUG1("lpc: '%s'", msg ); Free_line_list(&args); Split(&args,msg,Whitespace,0,0,0,0,0,0); Check_max(&args,2); args.list[args.count] = 0; if(DEBUGL1)Dump_line_list("lpc - args", &args ); if( args.count == 0 ) continue; s = args.list[0]; if( safestrcasecmp(s,"exit") == 0 || safestrcasecmp(s,_("exit")) == 0 || s[0] == 'q' || s[0] == 'Q' ){ break; } doaction(&args); } Free_line_list(&args); Errorcode = 0; Is_server = 0; cleanup(0); } void doaction( struct line_list *args ) { int action, fd, n, argspos, pcinfo_header; struct line_list l; char msg[SMALLBUFFER]; char *s, *t, *w, *printcap; Init_line_list(&l); s = t = w = printcap = 0; pcinfo_header = 0; if( args->count == 0 ) return; action = Get_controlword( args->list[0] ); if(DEBUGL1)Dump_line_list("doaction - args", args ); if( action == 0 ){ use_msg(); return; } if( args->count > 1 ){ Set_DYN(&Printer_DYN,args->list[1]); Fix_Rm_Rp_info(0,0); DEBUG1("doaction: Printer '%s', RemotePrinter '%s', RemoteHost '%s'", Printer_DYN, RemotePrinter_DYN, RemoteHost_DYN ); if( (s = safestrchr(args->list[1],'@')) ) *s = 0; } else if( Printer_DYN == 0 ){ /* get the printer name */ Get_printer(); Fix_Rm_Rp_info(0,0); } else { Fix_Rm_Rp_info(0,0); } if( ISNULL(RemotePrinter_DYN) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - cannot get status from device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Direct_DYN && Lp_device_DYN ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - direct connection to device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Auth ){ Set_DYN(&Auth_DYN, getenv("AUTH")); } if( Server ){ DEBUG1("doaction: overriding Remotehost with '%s'", Server ); Set_DYN(&RemoteHost_DYN, Server ); } DEBUG1("lpc: RemotePrinter_DYN '%s', RemoteHost_DYN '%s'", RemotePrinter_DYN, RemoteHost_DYN ); if( action == OP_DEFAULTS ){ Dump_default_parms( 1, ".defaults", Pc_var_list ); } else if( action == OP_LANG ){ FPRINTF( STDOUT, _("Locale information directory '%s'\n"), LOCALEDIR ); if( (s = getenv("LANG")) ){ FPRINTF( STDOUT, _("LANG environment variable '%s'\n"), s ); t = _(""); if( t && *t ){ FPRINTF( STDOUT, _("gettext translation information '%s'\n"), t ); } else { Write_fd_str(1,_("No translation available\n")); } FPRINTF(STDERR, "Translation of '%s' is '%s'\n","TRANSLATION TEST", _("TRANSLATION TEST")); } else { FPRINTF( STDOUT, "LANG environment variable not set\n" ); } } else if( action == OP_CLIENT || action == OP_SERVER ){ if( action == OP_SERVER ){ Is_server = 1; Setup_configuration(); Get_printer(); } Dump_default_parms( 1, ".defaults", Pc_var_list ); Free_line_list(&l); Merge_line_list(&l,&Config_line_list, 0, 0, 0); Escape_colons( &l ); s = Join_line_list_with_sep(&l,"\n :"); Expand_percent( &s ); if( s ){ if( Write_fd_str( 1, ".config\n :" ) < 0 ) cleanup(0); if( Write_fd_str( 1, s ) < 0 ) cleanup(0); Write_fd_str( 1, "\n" ); free(s); s = 0; } else { if( Write_fd_str( 1, ".config\n" ) < 0 ) cleanup(0); } Free_line_list(&l); if( args->count > 1 ){ for( argspos = 1; argspos < args->count; ++ argspos ){ if( !safestrcasecmp(args->list[argspos], "all") || !safestrcasecmp(args->list[argspos], _("all") ) ){ Show_all_printcap_entries(); } else { Set_DYN(&Printer_DYN,args->list[argspos]); if( Write_fd_str( 1,"\n") < 0 ) cleanup(0); if( Write_fd_str( 1,_("# Printcap Information\n")) < 0 ) cleanup(0); Show_formatted_info(); } } } else if( !safestrcasecmp( Printer_DYN, "all" ) || !safestrcasecmp( Printer_DYN, _("all") ) ){ Show_all_printcap_entries(); } else { if( Write_fd_str( 1,"\n") < 0 ) cleanup(0); if( Write_fd_str( 1,_("# Printcap Information\n")) < 0 ) cleanup(0); Show_formatted_info(); } } else if( action == OP_LPQ || action == OP_LPRM ){ pid_t pid, result; plp_status_t status; if( args->count == 1 && Printer_DYN ){ plp_snprintf(msg,sizeof(msg), "-P%s", Printer_DYN ); Add_line_list(args,msg,0,0,0); Check_max(args,1); args->list[args->count] = 0; } else if( args->count > 1 ){ s = args->list[1]; if( safestrcasecmp(s,"all") || safestrcasecmp(s,_("all")) ){ plp_snprintf(msg,sizeof(msg), "-P%s", s ); } else { strcpy(msg, "-a" ); } if( s ) free(s); args->list[1] = safestrdup(msg,__FILE__,__LINE__); } if(DEBUGL1)Dump_line_list("ARGS",args); if( (pid = dofork(0)) == 0 ){ /* we are going to close a security loophole */ Full_user_perms(); /* this would now be the same as executing LPQ as user */ close_on_exec(3); execvp( args->list[0],args->list ); DIEMSG( _("execvp failed - '%s'"), Errormsg(errno) ); exit(0); } else if( pid < 0 ) { DIEMSG( _("fork failed - '%s'"), Errormsg(errno) ); } while( (result = plp_waitpid(pid,&status,0)) != pid ){ int err = errno; DEBUG1("lpc: waitpid(%ld) returned %ld, err '%s'", (long)pid, (long)result, Errormsg(err) ); if( err == EINTR ) continue; Errorcode = JABORT; logerr_die(LOG_ERR, _("doaction: waitpid(%ld) failed"), (long)pid); } DEBUG1("lpc: system pid %ld, exit status %s", (long)result, Decode_status( &status ) ); } else { /* * rearrange the options so that you have * the user name and other elements first */ Add_line_list(&l, Logname_DYN, 0, 0, 0 ); Add_line_list(&l, args->list[0], 0, 0, 0); Remove_line_list(args, 0); if( args->count > 0 ) { Add_line_list(&l, RemotePrinter_DYN, 0, 0, 0 ); Remove_line_list(args, 0); } Merge_line_list(&l, args, 0, 0, 0 ); Check_max(&l, 1 ); l.list[l.count] = 0; fd = Send_request( 'C', REQ_CONTROL, l.list, Connect_timeout_DYN, Send_query_rw_timeout_DYN, 1 ); if( fd > 0 ){ shutdown( fd, 1 ); while( (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN,fd, msg, sizeof(msg))) > 0 ){ if( (write(1,msg,n)) < 0 ) cleanup(0); } } close(fd); } Free_line_list(&l); } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ char LPC_optstr[] /* LPC options */ = "AaD:P:S:VU:"; /* scan the input arguments, setting up values */ void Get_parms(int argc, char *argv[] ) { int option; while ((option = Getopt (argc, argv, LPC_optstr )) != EOF) { switch (option) { case 'A': Auth = 1; break; case 'a': Set_DYN(&Printer_DYN,"all"); break; case 'D': /* debug has already been done */ Parse_debug( Optarg, 1 ); break; case 'P': if( Optarg == 0 ) usage(); Set_DYN(&Printer_DYN,Optarg); break; case 'V': ++Verbose; break; case 'S': Server = Optarg; break; case 'U': Username_JOB = Optarg; break; default: usage(); } } if( Verbose ) { FPRINTF( STDOUT, "%s\n", Version ); if( Verbose > 1 ){ char *s, *t; if( (s = getenv("LANG")) ){ FPRINTF( STDOUT, _("LANG environment variable '%s'\n"), s ); t = _(""); if( t && *t ){ FPRINTF( STDOUT, _("gettext translation information '%s'\n"), t ); } else { FPRINTF( STDOUT, "%s", _("No translation available\n")); } } else { FPRINTF( STDOUT, "LANG environment variable not set\n" ); } Printlist( Copyright, 2 ); } } } static void use_msg(void) { FPRINTF( STDERR, _("usage: %s [-a][-Ddebuglevel][-Pprinter][-Shost][-Uusername][-V] [command]\n" " with no command, reads from STDIN\n" " -a - alias for -Pall\n" " -Ddebuglevel - debug level\n" " -Pprinter - printer\n" " -Pprinter@host - printer on lpd server on host\n" " -Shost - connect to lpd server on host\n" " -Uuser - identify command as coming from user\n" " -V - increase information verbosity\n" " commands:\n" " active (printer[@host]) - check for active server\n" " abort (printer[@host] | all) - stop server\n" " class printer[@host] (class | off) - show/set class printing\n" " disable (printer[@host] | all) - disable queueing\n" " debug (printer[@host] | all) debugparms - set debug level for printer\n" " down (printer[@host] | all) - disable printing and queueing\n" " enable (printer[@host] | all) - enable queueing\n" " flush (printer[@host] | all) - flush cached status\n" " hold (printer[@host] | all) (name[@host] | job | all)* - hold job\n" " holdall (printer[@host] | all) - hold all jobs on\n" " kill (printer[@host] | all) - stop and restart server\n" " lpd (printer[@host]) - get LPD PID \n" " lpq (printer[@host] | all) (name[@host] | job | all)* - invoke LPQ\n" " lprm (printer[@host] | all) (name[@host]|host|job| all)* - invoke LPRM\n" " msg printer message text - set status message\n" " move printer (user|jobid)* target - move jobs to new queue\n" " noholdall (printer[@host] | all) - hold all jobs off\n" " printcap (printer[@host] | all) - report printcap values\n" " quit - exit LPC\n" " redirect (printer[@host] | all) (printer@host | off )* - redirect jobs\n" " redo (printer[@host] | all) (name[@host] | job | all)* - reprint jobs\n" " release (printer[@host] | all) (name[@host] | job | all)* - release jobs\n" " reread - LPD reread database information\n" " start (printer[@host] | all) - start printing\n" " status (printer[@host] | all) - status of printers\n" " stop (printer[@host] | all) - stop printing\n" " topq (printer[@host] | all) (name[@host] | job | all)* - reorder jobs\n" " up (printer[@host] | all) - enable printing and queueing\n" " diagnostic:\n" " defaultq - show default queue for LPD server\n" " defaults - show default configuration values\n" " lang - show current i18n (iNTERNATIONALIZATIONn) support\n" " client (printer | all) - client config and printcap information\n" " server (printer | all) - server config and printcap\n"), Name ); } void usage(void) { use_msg(); Parse_debug("=",-1); FPRINTF( STDOUT, "%s\n", Version ); { char buffer[128]; FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); } exit(1); } lprng-3.8.B/src/common/sendauth.c0000644000131400013140000002720011531672132013637 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "user_auth.h" #include "sendjob.h" #include "permission.h" #include "getqueue.h" #include "errorcodes.h" #include "linksupport.h" #include "krb5_auth.h" #include "fileopen.h" #include "child.h" #include "gethostinfo.h" #include "sendauth.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * Patrick Powell Mon Apr 17 05:43:48 PDT 1995 * * The protocol used to send a secure job consists of the following * following: * * Client Server * \REQ_SECUREprintername C/F user\n - receive a command * 0 1 2 * \REQ_SECUREprintername C/F user controlfile\n - receive a job * 0 1 2 * * 1. Get a temporary file * 2. Generate the compressed data files - this has the format * Authentication * \n * \3count cfname\n * [count control file bytes] * \4count dfname\n * [count data file bytes] * * 3. send the \REQ_SECRemotePrinter_DYN user@RemoteHost_DYN file size\n * string to the remote RemoteHost_DYN, wait for an ACK * * 4. send the compressed data files - this has the format * wait for an ACK ***************************************************************************/ static void Put_in_auth( int tempfd, const char *key, char *value ); /* * Send_auth_transfer * 1. we send the command line and wait for ACK of 0 * \REQ_SEQUREprinter C/F sender_id authtype [jobsize] * 2. if authtype == kerberos we do kerberos * - send a file to the remote end * - get back a file * 3. if authtype == pgp we do pgp * - same as kerberos * 3. if otherwise, we start a process with command line options * fd 0 - sock * fd 1 - for reports * fd 2 - for errors * /filter -C -P printer -n sender_id -A authtype -R remote_id -Ttempfile * The tempfile will be sent to the remote end and status * written back on fd 2 * - we save this information * - reopen the file and put error messages in it. * RETURN: * 0 - no error * !=0 - error */ int Send_auth_transfer( int *sock, int transfer_timeout, struct job *job, struct job *logjob, char *error, int errlen, char *cmd, const struct security *security, struct line_list *info ) { struct stat statb; int ack, len, n, fd; /* ACME! The best... */ int status = JFAIL; /* job status */ char *secure, *destination, *from, *client, *s; char *tempfile; char buffer[SMALLBUFFER]; errno = 0; secure = 0; fd = Make_temp_fd(&tempfile); if( cmd && (s = safestrrchr(cmd,'\n')) ) *s = 0; DEBUG1("Send_auth_transfer: cmd '%s'", cmd ); if(DEBUGL1)Dump_line_list("Send_auth_transfer: info ", info ); destination = Find_str_value(info, DESTINATION ); from = Find_str_value(info, FROM ); client = Find_str_value(info, CLIENT ); if( safestrcmp(security->config_tag, "kerberos") ){ Put_in_auth(fd,DESTINATION,destination); if( Is_server ) Put_in_auth(fd,SERVER,from); Put_in_auth(fd,CLIENT,client); if( cmd ){ Put_in_auth(fd,INPUT,cmd); } } else { if( cmd && (Write_fd_str(fd,cmd) < 0 || Write_fd_str(fd,"\n") < 0) ){ plp_snprintf(error, errlen, "Send_auth_transfer: '%s' write failed - %s", tempfile, Errormsg(errno) ); goto error; } if( Is_server && (Write_fd_str(fd,client) < 0 || Write_fd_str(fd,"\n") < 0) ){ plp_snprintf(error, errlen, "Send_auth_transfer: '%s' write failed - %s", tempfile, Errormsg(errno) ); goto error; } } if( Write_fd_str(fd,"\n") < 0 ){ plp_snprintf(error, errlen, "Send_auth_transfer: '%s' write failed - %s", tempfile, Errormsg(errno) ); goto error; } s = Find_str_value(info, CMD ); if( job ){ status = Send_normal( &fd, job, logjob, transfer_timeout, fd, 0); if( status ) return( status ); errno = 0; if( stat(tempfile,&statb) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Send_auth_transfer: stat '%s' failed", tempfile); } plp_snprintf( buffer,sizeof(buffer), " %0.0f",(double)(statb.st_size) ); secure = safestrdup3(s,buffer,"\n",__FILE__,__LINE__); } else { secure = safestrdup2(s,"\n",__FILE__,__LINE__); } close( fd ); fd = -1; /* send the message */ DEBUG3("Send_auth_transfer: sending '%s'", secure ); status = Link_send( RemoteHost_DYN, sock, transfer_timeout, secure, safestrlen(secure), &ack ); DEBUG3("Send_auth_transfer: status '%s'", Link_err_str(status) ); if( status ){ /* open output file */ if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ Errorcode = JABORT; logerr_die(LOG_INFO, "Send_auth_transfer: open '%s' for write failed", tempfile); } /* we turn off IO from the socket */ shutdown(*sock,1); if( (s = safestrchr(secure,'\n')) ) *s = 0; plp_snprintf( error, errlen, "error '%s' sending '%s' to %s@%s\n", Link_err_str(status), secure, RemotePrinter_DYN, RemoteHost_DYN ); Write_fd_str( fd, error ); error[0] = 0; DEBUG2("Send_auth_transfer: starting read"); len = 0; while( (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN, *sock,buffer+len,sizeof(buffer)-1-len)) > 0 ){ buffer[n+len] = 0; DEBUG4("Send_auth_transfer: read '%s'", buffer); while( (s = strchr(buffer,'\n')) ){ *s++ = 0; DEBUG2("Send_auth_transfer: doing '%s'", buffer); plp_snprintf(error,errlen, "%s\n", buffer ); if( Write_fd_str(fd,error) < 0 ){ Errorcode = JABORT; logerr(LOG_INFO, "Send_auth_transfer: write '%s' failed", tempfile ); goto error; } memmove(buffer,s,safestrlen(s)+1); } len = safestrlen(buffer); } if( buffer[0] ){ DEBUG2("Send_auth_transfer: doing '%s'", buffer); plp_snprintf(error,errlen, "%s\n", buffer ); if( Write_fd_str(fd,error) < 0 ){ Errorcode = JABORT; logerr(LOG_INFO, "Send_auth_transfer: write '%s' failed", tempfile ); goto error; } } close( fd ); fd = -1; error[0] = 0; goto error; } /* * now we do the protocol dependent exchange */ status = security->client_send( sock, transfer_timeout, tempfile, error, errlen, security, info ); error: DEBUG3("Send_auth_transfer: sock %d, exit status %d, error '%s'", *sock, status, error ); /* we are going to put the returned error status in the temp file * as the device to read from */ if( secure ) free(secure); secure = 0; if( error[0] ){ if( job ){ setstatus(logjob, "Send_auth_transfer: %s", error ); Set_str_value(&job->info,ERROR,error); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Send_auth_transfer: cannot open '%s'", tempfile ); } Write_fd_str(fd,error); close( fd ); fd = -1; error[0] = 0; } if( *sock >= 0 ){ if( (fd = Checkread(tempfile,&statb)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Send_auth_transfer: cannot open '%s'", tempfile ); } if( dup2( fd, *sock ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Send_auth_transfer: dup2(%d,%d)", fd, *sock ); } if( fd != *sock ) close(fd); fd = -1; } Free_line_list(info); DEBUG3("Send_auth_transfer: exit status %d, error '%s'", status, error ); return( status ); } /*************************************************************************** * * struct security *Fix_send_auth( char *name, struct line_list *info * char *error, int errlen ) * * Find the information about the encrypt type and then make up the string * to send to the server requesting the encryption **************************************************************************/ const struct security *Fix_send_auth( char *name, struct line_list *info, struct job *job, char *error, int errlen ) { const struct security *security = 0; char buffer[SMALLBUFFER], *from, *client, *destination; const char *tag, *server_tag, *key; if( name == 0 ){ if( Is_server ){ name = Auth_forward_DYN; } else { name = Auth_DYN; } } DEBUG1("Fix_send_auth: name '%s'", name ); if( name ){ security = FindSecurity(name); if( !security ){ plp_snprintf(error, errlen, "Fix_send_auth: '%s' security not supported", name ); goto error; } else { DEBUG1("Fix_send_auth: name '%s' matches '%s'", name, security->name ); } } else { DEBUG1("Fix_send_auth: no security" ); return( 0 ); } /* check to see if we use unix_socket */ if( security->auth_flags & IP_SOCKET_ONLY ){ Set_DYN( &Unix_socket_path_DYN, 0 ); } if( !(tag = security->config_tag) ) tag = security->name; plp_snprintf(buffer,sizeof(buffer), "%s_", tag ); Find_default_tags( info, Pc_var_list, buffer ); Find_tags( info, &Config_line_list, buffer ); Find_tags( info, &PC_entry_line_list, buffer ); Expand_hash_values( info ); if(DEBUGL1)Dump_line_list("Fix_send_auth: found info", info ); if( !(tag = security->config_tag) ) tag = security->name; if( !(server_tag = security->server_tag) ) server_tag = tag; if( Is_server ){ /* forwarding */ key = "F"; from = Find_str_value(info,ID); if(!from)from = Find_str_value(info,"server_principal"); if( from == 0 && safestrcmp(tag,"kerberos") && safestrcmp(tag,"none") ){ plp_snprintf(error, errlen, "Fix_send_auth: '%s' security missing '%s_id' info", tag, tag ); goto error; } Set_str_value(info,FROM,from); if( job ){ client = Find_str_value(&job->info,AUTHUSER); Set_str_value(info,CLIENT,client); } else { client = (char *)Perm_check.authuser; } if( client == 0 && !(client = Find_str_value(info,"default_client_name")) && safestrcmp(tag,"none") ){ plp_snprintf(error, errlen, "Fix_send_auth: security '%s' missing authenticated client", tag ); goto error; } Set_str_value(info,CLIENT,client); destination = Find_str_value(info,FORWARD_ID); if(!destination)destination = Find_str_value(info,"forward_principal"); if( destination == 0 && safestrcmp(tag, "kerberos") && safestrcmp(tag, "none")){ plp_snprintf(error, errlen, "Fix_send_auth: '%s' security missing '%s_forward_id' info", tag, tag ); goto error; } } else { /* from client */ key = "C"; from = Logname_DYN; Set_str_value(info,FROM,from); client = Logname_DYN; Set_str_value(info,CLIENT,client); destination = Find_str_value(info,ID); if(!destination)destination = Find_str_value(info,"server_principal"); if( destination == 0 && safestrcmp(tag, "kerberos") && safestrcmp(tag, "none") ){ plp_snprintf(error, errlen, "Fix_send_auth: '%s' security missing destination '%s_id' info", tag, tag ); goto error; } } Set_str_value(info,DESTINATION,destination); DEBUG1("Fix_send_auth: pr '%s', key '%s', from '%s', name '%s', tag '%s'", RemotePrinter_DYN,key, from, server_tag, tag); plp_snprintf( buffer, sizeof(buffer), "%c%s %s %s %s", REQ_SECURE,RemotePrinter_DYN,key, from, server_tag ); Set_str_value(info,CMD,buffer); DEBUG1("Fix_send_auth: sending '%s'", buffer ); error: if( error[0] ) security = 0; DEBUG1("Fix_send_auth: error '%s'", error ); if(DEBUGL1)Dump_line_list("Fix_send_auth: info", info ); return(security); } void Put_in_auth( int tempfd, const char *key, char *value ) { char *v = Escape(value,1); DEBUG1("Put_in_auth: fd %d, key '%s' value '%s', v '%s'", tempfd, key, value, v ); if( Write_fd_str(tempfd,key) < 0 || Write_fd_str(tempfd,"=") < 0 || Write_fd_str(tempfd,v) < 0 || Write_fd_str(tempfd,"\n") < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Put_in_auth: cannot write to file" ); } if( v ) free(v); v = 0; } lprng-3.8.B/src/common/getqueue.c0000644000131400013140000017226311531672131013661 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * Commentary * Patrick Powell Thu Apr 27 21:48:38 PDT 1995 * * The spool directory contains files and other information associated * with jobs. Job files have names of the form cfXNNNhostname. * * The Scan_queue routine will scan a spool directory, looking for new * or missing control files. If one is found, it will add it to * the control file list. It will then sort the list of file names. * * In order to prevent strange things with pointers, you should not store * pointers to this list, but use indexes instead. ***************************************************************************/ #include "lp.h" #include "child.h" #include "errorcodes.h" #include "fileopen.h" #include "linelist.h" #include "getprinter.h" #include "gethostinfo.h" #include "getqueue.h" #include "globmatch.h" #include "permission.h" #include "lockfile.h" #include "merge.h" #if defined(USER_INCLUDE) # include USER_INCLUDE #else # if defined(ORDER_ROUTINE) # error No 'USER_INCLUDE' file with ORDER_ROUTINE function prototypes specified You need an include file with function prototypes # endif #endif /**** ENDINCLUDE ****/ /* prototypes of functions only used internally */ static void Append_Z_value( struct job *job, char *s ); static void Set_job_ticket_datafile_info( struct job *job ); static int ordercomp( const void *left, const void *right, const void *orderp); /* * We make the following assumption: * a job consists of a job ticket file and a set of data files. * data files without a job ticket file or a job ticket file * without a data files (unless marked as 'incoming') will be * considered as a bad job. */ int Scan_queue( struct line_list *spool_control, struct line_list *sort_order, int *pprintable, int *pheld, int *pmove, int only_queue_process, int *perr, int *pdone, const char *remove_prefix, const char *remove_suffix ) { DIR *dir; /* directory */ struct dirent *d; /* directory entry */ char *job_ticket_name; int c, printable, held, move, error, done, p, h, m, e, dn; int remove_prefix_len = safestrlen( remove_prefix ); int remove_suffix_len = safestrlen( remove_suffix ); struct job job; c = printable = held = move = error = done = 0; Init_job( &job ); if( pprintable ) *pprintable = 0; if( pheld ) *pheld = 0; if( pmove ) *pmove = 0; if( perr ) *perr = 0; if( pdone ) *pdone = 0; Free_line_list(sort_order); if( !(dir = opendir( "." )) ){ logerr(LOG_INFO, "Scan_queue: cannot open '.'" ); return( 1 ); } job_ticket_name = 0; while( (d = readdir(dir)) ){ job_ticket_name = d->d_name; DEBUG5("Scan_queue: found file '%s'", job_ticket_name ); if( (remove_prefix_len && !strncmp( job_ticket_name, remove_prefix, remove_prefix_len ) ) || (remove_suffix_len && !strcmp( job_ticket_name+strlen(job_ticket_name)-remove_suffix_len, remove_suffix )) ){ DEBUG1("Scan_queue: removing file '%s'", job_ticket_name ); unlink( job_ticket_name ); continue; } else if( !( (cval(job_ticket_name+0) == 'h') && (cval(job_ticket_name+1) == 'f') && isalpha(cval(job_ticket_name+2)) && isdigit(cval(job_ticket_name+3)) ) ){ continue; } DEBUG2("Scan_queue: processing file '%s'", job_ticket_name ); Free_job( &job ); /* read the hf file and get the information */ Get_job_ticket_file( 0, &job, job_ticket_name ); if(DEBUGL3)Dump_line_list("Scan_queue: hf", &job.info ); if( job.info.count == 0 ){ continue; } Job_printable(&job,spool_control, &p,&h,&m,&e,&dn); if( p ) ++printable; if( h ) ++held; if( m ) ++move; if( e ) ++error; if( dn ) ++done; /* now generate the sort key */ DEBUG4("Scan_queue: p %d, m %d, e %d, dn %d, only_queue_process %d", p, m, e, dn, only_queue_process ); if( sort_order ){ if( !only_queue_process || (p || m || e || dn) ){ if(DEBUGL4)Dump_job("Scan_queue - before Make_sort_key",&job); Make_sort_key( &job ); DEBUG5("Scan_queue: sort key '%s'",job.sort_key); Set_str_value(sort_order,job.sort_key,job_ticket_name); } } } closedir(dir); Free_job(&job); if(DEBUGL5){ LOGDEBUG("Scan_queue: final values" ); Dump_line_list_sub(SORT_KEY,sort_order); } if( pprintable ) *pprintable = printable; if( pheld ) *pheld = held; if( pmove ) *pmove = move; if( perr ) *perr = error; if( pdone ) *pdone = done; DEBUG3("Scan_queue: final printable %d, held %d, move %d, error %d, done %d", printable, held, move, error, done ); return(0); } /* * char *Get_fd_image( int fd, char *file ) * Get an image of a file from an fd */ char *Get_fd_image( int fd, off_t maxsize ) { char *s = 0; struct stat statb; char buffer[LARGEBUFFER]; int n; off_t len; DEBUG3("Get_fd_image: fd %d", fd ); if( lseek(fd, 0, SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Get_fd_image: lseek failed" ); } if( maxsize && fstat(fd, &statb) == 0 && maxsize< statb.st_size/1024 ){ lseek(fd, -maxsize*1024, SEEK_END); } len = 0; while( (n = ok_read(fd,buffer,sizeof(buffer))) > 0 ){ s = realloc_or_die(s,len+n+1,__FILE__,__LINE__); memcpy(s+len,buffer,n); len += n; s[len] = 0; } if(DEBUGL3){ plp_snprintf(buffer,32, "%s",s); logDebug("Get_fd_image: len %d '%s'", s?safestrlen(s):0, buffer ); } return(s); } /* * char *Get_file_image( char *dir, char *file ) * Get an image of a file */ char *Get_file_image( const char *file, off_t maxsize ) { char *s = 0; struct stat statb; int fd; if( file == 0 ) return(0); DEBUG3("Get_file_image: '%s', maxsize %ld", file, (long)maxsize ); if( (fd = Checkread( file, &statb )) >= 0 ){ s = Get_fd_image( fd, maxsize ); close(fd); } return(s); } /* * char *Get_fd_image_and_split * Get an image of a file */ int Get_fd_image_and_split( int fd, int maxsize, int clean, struct line_list *l, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, char **return_image ) { char *s = 0; if( return_image ) *return_image = 0; s = Get_fd_image( fd, maxsize ); if( s == 0 ) return 1; if( clean ) Clean_meta(s); Split( l, s, sep, sort, keysep, uniq, trim, nocomments ,0); if( return_image ){ *return_image = s; } else { if( s ) free(s); s = 0; } return(0); } /* * char *Get_file_image_and_split * Get an image of a file */ int Get_file_image_and_split( const char *file, int maxsize, int clean, struct line_list *l, const char *sep, int sort, const char *keysep, int uniq, int trim, int nocomments, char **return_image ) { char *s = 0; if( return_image ) *return_image = 0; if( !ISNULL(file) ) s = Get_file_image( file, maxsize ); if( s == 0 ) return 1; if( clean ) Clean_meta(s); Split( l, s, sep, sort, keysep, uniq, trim, nocomments ,0); if( return_image ){ *return_image = s; } else { if( s ) free(s); s = 0; } return(0); } /* * Set up a job data structure with information from the * file images * - Check_for_hold - * checks to see if the job is held by class or by * command * Setup_job - gets the job information and updates it * from the spool queue and control information */ void Check_for_hold( struct job *job, struct line_list *spool_control ) { int held, i; /* get the hold class of the job */ held = Get_hold_class(&job->info,spool_control); Set_flag_value(&job->info,HOLD_CLASS,held); /* see if we need to hold this job by time */ if( !Find_exists_value(&job->info,HOLD_TIME,Hash_value_sep) ){ if( Find_flag_value(spool_control,HOLD_TIME) ){ i = time((void *)0); } else { i = 0; } Set_flag_value( &job->info, HOLD_TIME, i ); } held = Find_flag_value(&job->info,HOLD_TIME); Set_flag_value(&job->info,HELD,held); } /* Get_hold_class( spool_control, job ) * check to see if the spool class and the job class are compatible * returns: non-zero if held, 0 if not held * i.e.- cmpare(spoolclass,jobclass) */ int Get_hold_class( struct line_list *info, struct line_list *sq ) { int held, i; char *s, *t; struct line_list l; Init_line_list(&l); held = 0; if( (s = Clsses(sq)) && (t = Find_str_value(info,CLASS)) ){ held = 1; Free_line_list(&l); Split(&l,s,File_sep,0,0,0,0,0,0); for( i = 0; held && i < l.count; ++i ){ held = Globmatch( l.list[i], t ); } Free_line_list(&l); } return(held); } /* * Extract the control file and data file information from the * control file image * * Note: we also handle HP extensions here. * * 1. 4-Digit Job Numbers * ---------------------- * * HP preserves the System V-style 4-digit sequence number, or job number, in * file names and attributes, while BSD uses 3-digit job numbers. * * * 2. Control and Data File Naming Conventions * ------------------------------------------- * * Control files are named in the following format: * * cA * * is the 4-digit sequence number (aka job number). * is the originating host name. * * The data file naming sequence format is: * * dA through dZ followed by... * da through dz followed by... * eA through eZ followed by... * ea through ez ... etc. ... * * * So the first data file name in a request begins with "dA", the second with * "dB", the 27th with "da", the 28th with "db", and so forth. * * * 3. HP-Specific BSD Job Attributes (Control File Lines) * ------------------------------------------------------ * * The following control file lines are extensions of RFC-1179: * * R * * Write to the named login's terminal when the job is complete. This is * an alternate to the RFC-1179-style e-mail completion notification. * This notification is selected via the lp "-w" option. * * A * * Specifies the System V-style priority of the request, a single digit * from 0-7. * * N B * * Note that this line begins with an "N", a space, and then a "B". The * argument is the banner page title requested via the lp "-t" option. If * that option was not given then the argument is null. * * N O * * Note that this line begins with an "N", a space, and then an "O". The * argument contains the System V-style "-o" options specified in the lp * command line. The option names appear without a leading "-o". The * first option name begins in the fourth character of the line; each * option is separated by a blank. If no "-o" options were given then the * argument is null. * */ void Append_Z_value( struct job *job, char *s ) { char *t; /* check for empty string */ if( !s || !*s ) return; t = Find_str_value(&job->info,"Z"); if( t && *t ){ t = safestrdup3(t,",",s,__FILE__,__LINE__); Set_str_value(&job->info,"Z",t); if( t ) free(t); t = 0; } else { Set_str_value(&job->info,"Z",s); } } int Set_job_ticket_from_cf_info( struct job *job, char *cf_file_image, int read_cf_file ) { char *s; int i, c, n, copies = 0, last_format = 0; struct line_list cf_line_list; struct line_list *datafile = 0; char buffer[SMALLBUFFER], *t; const char *file_found, *priority; char *names = 0; int returnstatus = 0; int hpformat; Init_line_list(&cf_line_list); names = 0; hpformat = Find_flag_value(&job->info,HPFORMAT); if( read_cf_file ){ s = Find_str_value(&job->info,OPENNAME); DEBUG3("Set_job_ticket_from_cf_info: control file '%s', hpformat '%d'", s, hpformat ); if( s && Get_file_image_and_split(s,0,0, &cf_line_list, Line_ends,0,0,0,0,0,0) ){ DEBUG3("Set_job_ticket_from_cf_info: missing or empty control file '%s'", s ); plp_snprintf(buffer,sizeof(buffer), "no control file %s - %s", s, Errormsg(errno) ); Set_str_value(&job->info,ERROR,buffer); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); returnstatus = 1; goto done; } } if( cf_file_image ){ Split( &cf_line_list, cf_file_image, Line_ends, 0, 0, 0, 0, 0 ,0); } Free_listof_line_list( &job->datafiles ); file_found = 0; datafile = malloc_or_die(sizeof(datafile[0]),__FILE__,__LINE__); memset(datafile,0,sizeof(datafile[0])); for( i = 0; i < cf_line_list.count; ++i ){ s = cf_line_list.list[i]; Clean_meta(s); c = cval(s); DEBUG3("Set_job_ticket_from_cf_info: doing line '%s'", s ); if( islower(c) ){ t = s; while( (t = strpbrk(t," \t")) ) *t++ = '_'; if( file_found && (safestrcmp(file_found,s+1) || last_format != c) ){ Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *)datafile; copies = 0; file_found = 0; datafile = malloc_or_die(sizeof(datafile[0]),__FILE__,__LINE__); memset(datafile,0,sizeof(datafile[0])); } last_format = c; buffer[0] = c; buffer[1] = 0; Set_str_value(datafile,FORMAT,buffer); ++copies; Set_flag_value(datafile,COPIES,copies); Set_str_value(datafile,OTRANSFERNAME,s+1); file_found = Find_str_value(datafile,OTRANSFERNAME); DEBUG4("Set_job_ticket_from_cf_info: doing file '%s', format '%c', copies %d", file_found, last_format, copies ); } else if( c == 'N' ){ if( hpformat && cval(s+1) == ' '){ /* this is an HP Format option */ /* N B -> 'T' line */ /* N Ooption option option-> prefix to Z */ c = cval(s+2); if( c == 'B' ){ if( s[3] ) Set_str_value(&job->info,"T",s+3); } else if( c == 'O' ){ s = s+3; if( safestrlen(s) ){ for( t = s; (t = strpbrk(t," ")); ++t ){ *t = ','; } Append_Z_value(job,s); } } continue; } /* if we have a file name AND an 'N' for it, then set up a new file */ if( file_found && (t = Find_str_value(datafile,"N")) /* && safestrcmp(t,s+1) */ ){ Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *)datafile; copies = 0; file_found = 0; datafile = malloc_or_die(sizeof(datafile[0]),__FILE__,__LINE__); memset(datafile,0,sizeof(datafile[0])); } Set_str_value(datafile,"N",s+1); if( !names ){ names = safestrdup(s+1,__FILE__,__LINE__); } else { names = safeextend3(names,",",s+1,__FILE__,__LINE__); } } else if( c == 'U' ){ /* Set_str_value(datafile,"U",s+1)*/ ; } else { /* * HP UX has some VERY odd problems */ if( hpformat && c == 'Z' ){ /* Multiple Z lines */ Append_Z_value( job, s+1 ); } else if( hpformat && c == 'R' ){ /* Uses R and not M */ Set_str_value(&job->info,"M",s+1); } else if( hpformat && c == 'A' ){ /* Uses Annn for priority */ n = strtol( s+1,0,10); if( n >= 0 && n <=10){ c = n + 'A'; buffer[0] = n + 'A'; buffer[1] = 0; Set_str_value(&job->info,PRIORITY,buffer); } } else if( isupper(c) ){ buffer[0] = c; buffer[1] = 0; DEBUG4("Set_job_ticket_from_cf_info: control '%s'='%s'", buffer, s+1 ); Set_str_value(&job->info,buffer,s+1); } } } if( file_found ){ Check_max(&job->datafiles,1); job->datafiles.list[job->datafiles.count++] = (void *)datafile; datafile = 0; } Set_str_value(&job->info,FILENAMES,names); /* * now fix up priority using * ignore requested user priority * ignore_requested_user_priority=0 * do not set priority from class name * break_classname_priority_link=0 */ priority = 0; if( !Ignore_requested_user_priority_DYN && !Break_classname_priority_link_DYN ) priority = Find_str_value( &job->info,CLASS); if( ISNULL(priority) ) priority = Default_priority_DYN; if( ISNULL(priority) ) priority = "A"; buffer[0] = toupper(cval(priority)); buffer[1] = 0; if( cval(buffer) < 'A' || cval(buffer) > 'Z' ){ priority = "A"; } else { priority = buffer; } Set_str_value(&job->info,PRIORITY,priority); priority = Find_str_value(&job->info,PRIORITY); if( !Find_str_value(&job->info,CLASS) ){ Set_str_value(&job->info,CLASS,priority); } done: if( datafile ) Free_line_list( datafile ); if( datafile ) free(datafile); datafile=0; if( names ) free(names); names=0; Free_line_list( &cf_line_list ); if(DEBUGL4)Dump_job("Set_job_ticket_from_cf_info - final",job); return(returnstatus); } /* * Set the job ticket file datafile information in the HFDATAFILES line * This is the information that is PERMANENT, i.e. - after the * job has been transferred. * We also generate a DATAFILES line which has the format * permanent_name[=currentname] * i.e. - we have a mapping between the file names in the * HFDATAFILES line and the current file names they go by. */ void Set_job_ticket_datafile_info( struct job *job ) { int linecount, i, len; char *s, *t, *dataline, *datafiles; struct line_list *lp; struct line_list dups; datafiles = dataline = 0; Init_line_list(&dups); for( linecount = 0; linecount < job->datafiles.count; ++linecount ){ lp = (void *)job->datafiles.list[linecount]; if(DEBUGL4)Dump_line_list("Set_job_ticket_datafile_info - info", lp ); for( i = 0; i < lp->count; ++i ){ s = lp->list[i]; if( !strncmp(s,"openname", 8 ) ) continue; if( !strncmp(s,"otransfername", 13 ) ) continue; dataline = safeextend3(dataline, s, "\002",__FILE__,__LINE__); } t = Find_str_value(lp,OPENNAME); s = Find_str_value(lp,DFTRANSFERNAME); if( !ISNULL(s) && !Find_flag_value(&dups,s) ){ if( t ){ datafiles = safeextend5(datafiles,s, "=", t, " ",__FILE__,__LINE__); } else { datafiles = safeextend3(datafiles, s, " ",__FILE__,__LINE__); } Set_flag_value(&dups,s,1); } len = strlen(dataline); if( len ){ dataline[len-1] = '\001'; } } Set_str_value(&job->info,HFDATAFILES,dataline); Set_str_value(&job->info,DATAFILES,datafiles); if( dataline ) free(dataline); dataline = 0; if( datafiles ) free(datafiles); datafiles = 0; } char *Make_job_ticket_image( struct job *job ) { char *outstr, *s; int i; int len = safestrlen(OPENNAME); outstr = 0; Set_job_ticket_datafile_info( job ); for( i = 0; i < job->info.count; ++i ){ s = job->info.list[i]; if( !ISNULL(s) && !safestrpbrk(s,Line_ends) && safestrncasecmp(OPENNAME,s,len) ){ outstr = safeextend3(outstr,s,"\n",__FILE__,__LINE__); } } return( outstr ); } /* * Write a job ticket file */ int Set_job_ticket_file( struct job *job, struct line_list *perm_check, int opened_fd ) { char *job_ticket_name, *outstr; int status; int fd = opened_fd; struct stat statb; status = 0; outstr = 0; Set_job_ticket_datafile_info( job ); if(DEBUGL4)Dump_job("Set_job_ticket_file - init",job); Set_str_value(&job->info,UPDATE_TIME,Time_str(0,0)); outstr = Make_job_ticket_image( job ); DEBUG4("Set_job_ticket_file: '%s'", outstr ); if( !(job_ticket_name = Find_str_value(&job->info,HF_NAME)) ){ Errorcode = JABORT; fatal(LOG_ERR, "Set_job_ticket_file: LOGIC ERROR- no HF_NAME in job information - %s", outstr); } if( opened_fd <= 0 ){ if( (fd = Checkwrite( job_ticket_name, &statb, O_RDWR, 0, 0 )) < 0 ){ logerr(LOG_INFO, "Set_job_ticket_file: cannot open '%s'", job_ticket_name ); } else if( Do_lock(fd, 1 ) ){ logerr(LOG_INFO, "Set_job_ticket_file: cannot lcok '%s'", job_ticket_name ); close(fd); fd = -1; } } if( fd > 0 ){ if( lseek( fd, 0, SEEK_SET ) == -1 ){ logerr_die(LOG_ERR, "Set_job_ticket_file: lseek failed" ); } if( ftruncate( fd, 0 ) ){ logerr_die(LOG_ERR, "Set_job_ticket_file: ftruncate failed" ); } if( Write_fd_str(fd, outstr) < 0 ){ logerr(LOG_INFO, "Set_job_ticket_file: write to '%s' failed", job_ticket_name ); status = 1; } if( opened_fd <= 0 ){ close(fd); fd = -1; } } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN ); } /* we do this when we have a logger */ if( status == 0 && Logger_fd > 0 ){ char *t, *u; if( perm_check ){ u = Join_line_list( perm_check, "\n" ); t = Escape(u,1); outstr = safeextend5(outstr,"\n",LPC,"=",u,__FILE__,__LINE__); if(u) free(u); u = 0; if(t) free(t); t = 0; } send_to_logger(-1, -1, job,UPDATE,outstr); } if( outstr ) free( outstr ); outstr = 0; return( status ); } /* * Get_job_ticket_file( struct job *job, char *job_ticket_name ) * * get job ticket file contents and initialize job->info hash with them */ void Get_job_ticket_file( int *lock_fd, struct job *job, char *job_ticket_name ) { char *s; struct stat statb; int fd = -1; if( (s = safestrchr(job_ticket_name, '=')) ){ job_ticket_name = s+1; } DEBUG1("Get_job_ticket_file: checking on '%s'", job_ticket_name ); if( lock_fd ) fd = *lock_fd; if( fd <= 0 ){ if( (fd = Checkwrite( job_ticket_name, &statb, O_RDWR, 0, 0 )) > 0 && !Do_lock(fd, 1 ) ){ Get_fd_image_and_split( fd, 0, 0, &job->info, Line_ends, 1, Option_value_sep,1,1,1,0); if( lock_fd ){ *lock_fd = fd; fd = -1; } } if( fd > 0 ) close(fd); fd = -1; } else { Get_fd_image_and_split( fd, 0, 0, &job->info, Line_ends, 1, Option_value_sep,1,1,1,0); } if( job->info.count ) { struct line_list cf_line_list, *datafile; int i; char *s; Init_line_list(&cf_line_list); if( (s = Find_str_value(&job->info,HFDATAFILES)) ){ Split(&cf_line_list,s,"\001",0,0,0,0,0,0); } Free_listof_line_list( &job->datafiles ); Check_max(&job->datafiles,cf_line_list.count); for( i = 0; i < cf_line_list.count; ++i ){ s = cf_line_list.list[i]; DEBUG3("Get_job_ticket_file: doing line '%s'", s ); datafile = malloc_or_die(sizeof(datafile[0]),__FILE__,__LINE__); memset(datafile,0,sizeof(datafile[0])); job->datafiles.list[job->datafiles.count++] = (void *)datafile; Split(datafile,s,"\002",1,Option_value_sep,1,1,1,0); } Free_line_list( &cf_line_list ); } if(DEBUGL2)Dump_job("Get_job_ticket_file",job); } /* * Get Spool Control Information * - simply read the file */ void Get_spool_control( const char *file, struct line_list *info ) { Free_line_list(info); DEBUG2("Get_spool_control: file '%s'", file ); Get_file_image_and_split( file, 0, 0, info,Line_ends,1,Option_value_sep,1,1,1,0); if(DEBUGL4)Dump_line_list("Get_spool_control- info", info ); } /* * Set Spool Control Information * - simply write the file */ void Set_spool_control( struct line_list *perm_check, const char *file, struct line_list *info ) { char *s, *t, *tempfile; struct line_list l; int fd; s = t = tempfile = 0; Init_line_list(&l); fd = Make_temp_fd( &tempfile ); DEBUG2("Set_spool_control: file '%s', tempfile '%s'", file, tempfile ); if(DEBUGL4)Dump_line_list("Set_spool_control- info", info ); s = Join_line_list(info,"\n"); if( Write_fd_str(fd, s) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Set_spool_control: cannot write tempfile '%s'", tempfile ); } close(fd); if( rename( tempfile, file ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Set_spool_control: rename of '%s' to '%s' failed", tempfile, file ); } /* force and update of the cached status */ if( Lpq_status_file_DYN ){ /* do not check to see if this works */ unlink(Lpq_status_file_DYN); } if( Logger_fd ){ /* log the spool control file changes */ t = Escape(s,1); Set_str_value(&l,QUEUE,t); if(s) free(s); s = 0; if(t) free(t); t = 0; if( perm_check ){ s = Join_line_list( perm_check, "\n" ); t = Escape(s,1); Set_str_value(&l,LPC,t); if(s) free(s); s = 0; if(t) free(t); t = 0; } t = Join_line_list( &l, "\n"); send_to_logger(-1,-1,0,QUEUE,t); } Free_line_list(&l); if(s) free(s); s = 0; if(t) free(t); t = 0; } void intval( const char *key, struct line_list *list, struct job *job ) { int i = Find_flag_value(list,key); int len = safestrlen(job->sort_key); plp_snprintf(job->sort_key+len,sizeof(job->sort_key)-len, "|%s.0x%08x",key,i&0xffffffff); DEBUG5("intval: '%s'", job->sort_key ); } void revintval( const char *key, struct line_list *list, struct job *job ) { int i = Find_flag_value(list,key); int len = safestrlen(job->sort_key); plp_snprintf(job->sort_key+len,sizeof(job->sort_key)-len, "|%s.0x%08x",key,(~i)&0xffffffff); DEBUG5("revintval: '%s'", job->sort_key ); } void strzval( const char *key, struct line_list *list, struct job *job ) { char *s = Find_str_value(list,key); int len = safestrlen(job->sort_key); plp_snprintf(job->sort_key+len,sizeof(job->sort_key)-len, "|%s.%d",key,s!=0); DEBUG5("strzval: '%s'", job->sort_key ); } void strnzval( const char *key, struct line_list *list, struct job *job ) { char *s = Find_str_value(list,key); int len = safestrlen(job->sort_key); plp_snprintf(job->sort_key+len,sizeof(job->sort_key)-len, "|%s.%d",key,(s==0 || *s == 0)); DEBUG5("strnzval: '%s'", job->sort_key ); } void strval( const char *key, struct line_list *list, struct job *job, int reverse ) { char *s = Find_str_value(list,key); int len = safestrlen(job->sort_key); int c = 0; if(s) c = cval(s); if( reverse ) c = -c; c = 0xFF & (-c); plp_snprintf(job->sort_key+len,sizeof(job->sort_key)-len, "|%s.%02x",key,c); DEBUG5("strval: '%s'", job->sort_key ); } /* * Make_sort_key * Make a sort key from the image information */ void Make_sort_key( struct job *job ) { job->sort_key[0] = 0; if( Order_routine_DYN ){ #if defined(ORDER_ROUTINE) extern char *ORDER_ROUTINE( struct job *job ); ORDER_ROUTINE( &job ); #else Errorcode = JABORT; fatal(LOG_ERR, "Make_sort_key: order_routine requested and ORDER_ROUTINE undefined"); #endif } else { /* first key is REMOVE_TIME - remove jobs come last */ intval(REMOVE_TIME,&job->info,job); #if 0 /* first key is DONE_TIME - done jobs come last */ intval(DONE_TIME,&job->info,job); intval(INCOMING_TIME,&job->info,job); /* next key is ERROR - error jobs jobs come before removed */ intval(ERROR_TIME,&job->info,job); #endif /* next key is HOLD - before the error jobs */ intval(HOLD_CLASS,&job->info,job); intval(HOLD_TIME,&job->info,job); /* next key is MOVE - before the held jobs */ strnzval(MOVE,&job->info,job); /* now by priority */ if( Ignore_requested_user_priority_DYN == 0 ){ strval(PRIORITY,&job->info,job,Reverse_priority_order_DYN); } /* now we do TOPQ */ revintval(PRIORITY_TIME,&job->info,job); /* now we do FirstIn, FirstOut */ intval(JOB_TIME,&job->info,job); intval(JOB_TIME_USEC,&job->info,job); /* now we do by job number if two at same time (very unlikely) */ intval(NUMBER,&job->info,job); } } /* * Set up printer * 1. reset configuration information * 2. check the printer name * 3. get the printcap information * 4. set the configuration variables * 5. If run on the server, then check for the Lp_device_DYN * being set. If it is set, then clear the RemotePrinter_DYN * and RemoteHost_DYN. */ int Setup_printer( char *prname, char *error, int errlen, int subserver ) { char *s; int status = 0; char name[SMALLBUFFER]; struct stat statb; DEBUG3( "Setup_printer: checking printer '%s'", prname ); /* reset the configuration information, just in case * this is a subserver or being used to get status */ safestrncpy(name,prname); if( error ) error[0] = 0; if( (s = Is_clean_name( name )) ){ plp_snprintf( error, errlen, "printer '%s' has illegal char at '%s' in name", name, s ); status = 1; goto error; } lowercase(name); if( !subserver && Status_fd > 0 ){ close( Status_fd ); Status_fd = -1; } Set_DYN(&Printer_DYN,name); Fix_Rm_Rp_info(0,0); if( Spool_dir_DYN == 0 || *Spool_dir_DYN == 0 || stat(Spool_dir_DYN, &statb) ){ plp_snprintf( error, errlen, "spool queue for '%s' does not exist on server %s\n" "check for correct printer name or you may need to run\n" "'checkpc -f' to create queue", name, FQDNHost_FQDN ); status = 2; goto error; } if( chdir( Spool_dir_DYN ) < 0 ){ plp_snprintf( error, errlen, "printer '%s', chdir to '%s' failed '%s'", name, Spool_dir_DYN, Errormsg( errno ) ); status = 2; goto error; } /* * get the override information from the control/spooling * directory */ Get_spool_control( Queue_control_file_DYN, &Spool_control ); if( Perm_filters_line_list.count ){ Free_line_list(&Perm_line_list); Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); Filterprintcap( &Perm_line_list, &Perm_filters_line_list, Printer_DYN ); } DEBUG1("Setup_printer: printer now '%s', spool dir '%s'", Printer_DYN, Spool_dir_DYN ); if(DEBUGL3){ Dump_parms("Setup_printer - vars",Pc_var_list); Dump_line_list("Setup_printer - spool control", &Spool_control ); } error: DEBUG3("Setup_printer: status '%d', error '%s'", status, error ); return( status ); } /************************************************************************** * Read_pid( int fd ) * - Read the pid from a file **************************************************************************/ pid_t Read_pid( int fd ) { char str[LINEBUFFER]; long n; if( lseek( fd, 0, SEEK_SET ) == -1 ){ logerr_die(LOG_ERR, "Read_pid: lseek failed" ); } str[0] = 0; if( (n = read( fd, str, sizeof(str)-1 ) ) < 0 ){ logerr_die(LOG_ERR, "Read_pid: read failed" ); } str[n] = 0; n = atol( str ); DEBUG3( "Read_pid: %ld", n ); return( n ); } pid_t Read_pid_from_file( const char *filename ) { struct stat statb; pid_t pid = -1; int fd; fd = Checkread( filename, &statb ); if( fd >= 0 ) { pid = Read_pid( fd); close( fd ); } return pid; } /************************************************************************** * Write_pid( int fd ) * - Write the pid to a file **************************************************************************/ int Write_pid( int fd, int pid, char *str ) { char line[LINEBUFFER]; if( lseek( fd, 0, SEEK_SET ) == -1 ){ logerr(LOG_ERR, "Write_pid: lseek failed" ); return -1; } if( ftruncate( fd, 0 ) ){ logerr(LOG_ERR, "Write_pid: ftruncate failed" ); return -1; } if( str == 0 ){ plp_snprintf( line, sizeof(line), "%d\n", pid ); } else { plp_snprintf( line, sizeof(line), "%s\n", str ); } DEBUG3( "Write_pid: pid %d, str '%s'", pid, str ); if( Write_fd_str( fd, line ) < 0 ){ logerr(LOG_ERR, "Write_pid: write failed" ); return -1; } return 0; } /*************************************************************************** * int Patselect( struct line_list *tokens, struct line_list *cf ); * check to see that the token value matches one of the following * in the control file: * token is INTEGER: then matches the job number * token is string: then matches either the user name or host name * then try glob matching job ID * return: * 0 if match found * nonzero if not match found ***************************************************************************/ int Patselect( struct line_list *token, struct line_list *cf, int starting ) { int match = 1; int i, n, val; char *key, *s, *end; if(DEBUGL3)Dump_line_list("Patselect- tokens", token ); if(DEBUGL3)Dump_line_list("Patselect- info", cf ); for( i = starting; match && i < token->count; ++i ){ key = token->list[i]; DEBUG3("Patselect: key '%s'", key ); /* handle wildcard match */ if( !(match = safestrcasecmp( key, "all" ))){ break; } end = key; val = strtol( key, &end, 10 ); if( *end == 0 ){ n = Find_decimal_value(cf,NUMBER); /* we check job number */ DEBUG3("Patselect: job number check '%d' to job %d", val, n ); match = (val != n); } else { /* now we check to see if we have a name match */ if( (s = Find_str_value(cf,LOGNAME)) && !(match = Globmatch(key,s)) ){ break; } if( (s = Find_str_value(cf,IDENTIFIER)) && !(match = Globmatch(key,s)) ){ break; } } } DEBUG3("Patselect: returning %d", match); return(match); } /*************************************************************************** * char * Check_format( int type, char *name, struct control_file *job ) * Check to see that the file name has the correct format * name[0] == 'c' or 'd' (type) * name[1] = 'f' * name[2] = A-Za-z * name[3-5] = NNN * name[6-end] = only alphanumeric and ., _, or - chars * RETURNS: 0 if OK, error message (string) if not * * Summary of HP's Extensions to RFC-1179 * 1. 4-Digit Job Numbers * ---------------------- * HP preserves the System V-style 4-digit sequence number, or job number, in * file names and attributes, while BSD uses 3-digit job numbers. * 2. Control and Data File Naming Conventions * ------------------------------------------- * Control files are named in the following format: * cA * is the 4-digit sequence number (aka job number). * is the originating host name. * The data file naming sequence format is: * dA through dZ followed by... * da through dz followed by... * eA through eZ followed by... * ea through ez ... etc. ... * So the first data file name in a request begins with "dA", the second with * "dB", the 27th with "da", the 28th with "db", and so forth. ***************************************************************************/ int Check_format( int type, const char *name, struct job *job ) { int n, c, hpformat; const char *s; char *t; char msg[SMALLBUFFER]; DEBUG4("Check_format: type %d, name '%s'", type, name ); msg[0] = 0; hpformat = 0; n = cval(name); switch( type ){ case DATA_FILE: if( n != 'd' ){ plp_snprintf(msg, sizeof(msg), "data file does not start with 'd' - '%s'", name ); goto error; } break; case CONTROL_FILE: if( n != 'c' ){ plp_snprintf(msg, sizeof(msg), "control file does not start with 'c' - '%s'", name ); goto error; } break; default: plp_snprintf(msg, sizeof(msg), "bad file type '%c' - '%s' ", type, name ); goto error; } /* check for second letter */ n = cval(name+1); if( n == 'A' ){ /* HP format */ hpformat = 1; } else if( n != 'f' ){ plp_snprintf(msg, sizeof(msg), "second letter must be f not '%c' - '%s' ", n, name ); goto error; } else { n = cval(name+2); if( !isalpha( n ) ){ plp_snprintf(msg, sizeof(msg), "third letter must be letter not '%c' - '%s' ", n, name ); goto error; } } if( type == CONTROL_FILE ){ plp_snprintf(msg,sizeof(msg), "%c",n); Set_str_value(&job->info,PRIORITY,msg); msg[0] = 0; } /* we now enter the wonderful world of 'conventions' cfAnnnHostname ^^^^ starts with letter (number len = 0, 1, 2, 3) cfAnnnIPV4.Add.ress (number len = 4, 5, ... ) ^^^^ starts with number or is a 3com type thing cfAnnnnnnHostName (len = 6) ^^^^ starts with letter cfAnnnnnnIPV4.Add.ress (len = 7, ... ) ^^^^ starts with number */ if( hpformat ){ /* we have four digits */ safestrncpy(msg,&name[2]); t = 0; n = strtol(msg,&t,10); } else { safestrncpy(msg,&name[3]); for( t = msg; isdigit(cval(t)); ++t ); c = t - msg; switch( c ){ case 0: case 1: case 2: case 3: break; case 4: case 5: c = 3; break; default: if( cval(msg+6) == '.' ) c = 3; else c = 6; break; } /* get the number */ t = &msg[c]; c = *t; *t = 0; n = strtol(msg,0,10); *t = c; } DEBUG1("Check_format: name '%s', number %d, file '%s'", name, n, t ); if( Find_str_value( &job->info,NUMBER) ){ c = Find_decimal_value( &job->info,NUMBER); if( c != n ){ plp_snprintf(msg, sizeof(msg), "job numbers differ '%s', old %d and new %d", name, c, n ); goto error; } } else { Fix_job_number( job, n ); } Clean_name(t); if( (s = Find_str_value( &job->info,FILE_HOSTNAME)) ){ if( safestrcasecmp(s,t) ){ plp_snprintf(msg, sizeof(msg), "bad hostname '%s' - '%s' ", t, name ); goto error; } } else { Set_str_value(&job->info,FILE_HOSTNAME,t); } /* clear out error message */ msg[0] = 0; error: if( hpformat ){ Set_flag_value(&job->info,HPFORMAT,hpformat); } if( msg[0] ){ DEBUG1("Check_format: %s", msg ); Set_str_value(&job->info,FORMAT_ERROR,msg); } return( msg[0] != 0 ); } char *Frwarding(struct line_list *l) { return( Find_str_value(l,FORWARDING) ); } int Pr_disabled(struct line_list *l) { return( Find_flag_value(l,PRINTING_DISABLED) ); } int Sp_disabled(struct line_list *l) { return( Find_flag_value(l,SPOOLING_DISABLED) ); } int Pr_aborted(struct line_list *l) { return( Find_flag_value(l,PRINTING_ABORTED) ); } int Hld_all(struct line_list *l) { return( Find_flag_value(l,HOLD_ALL) ); } char *Clsses(struct line_list *l) { return( Find_str_value(l,CLASS) ); } char *Cntrol_debug(struct line_list *l) { return( Find_str_value(l,DEBUG) ); } char *Srver_order(struct line_list *l) { return( Find_str_value(l,SERVER_ORDER) ); } /* * Job datastructure management */ void Init_job( struct job *job ) { memset(job,0,sizeof(job[0]) ); } void Free_job( struct job *job ) { Free_line_list( &job->info ); Free_listof_line_list( &job->datafiles ); Free_line_list( &job->destination ); } void Copy_job( struct job *dest, struct job *src ) { Merge_line_list( &dest->info, &src->info, 0,0,0 ); Merge_listof_line_list( &dest->datafiles, &src->datafiles); Merge_line_list( &dest->destination, &src->destination, 0,0,0 ); } /************************************************************************** * static int Fix_job_number(); * - fixes the job number range and value **************************************************************************/ char *Fix_job_number( struct job *job, int n ) { char buffer[SMALLBUFFER]; int len = 3, max = 1000; if( n == 0 ){ n = Find_decimal_value( &job->info, NUMBER ); } if( Long_number_DYN && !Backwards_compatible_DYN ){ len = 6; max = 1000000; } plp_snprintf(buffer,sizeof(buffer), "%0*d",len, n % max ); Set_str_value(&job->info,NUMBER,buffer); return( Find_str_value(&job->info,NUMBER) ); } /************************************************************************ * Make_identifier - add an identifier field to the job * the identifier has the format name@host%id * It is put in the 'A' field on the name. * ************************************************************************/ char *Make_identifier( struct job *job ) { const char *user, *host; char *s, *id; char number[32]; int n; if( !(s = Find_str_value( &job->info,IDENTIFIER )) ){ if( !(user = Find_str_value( &job->info,"P" ))){ user = "nobody"; } if( !(host= Find_str_value( &job->info,"H" ))){ host = "unknown"; } n = Find_decimal_value( &job->info,NUMBER ); plp_snprintf(number,sizeof(number), "%d",n); if( (s = safestrchr( host, '.' )) ) *s = 0; id = safestrdup5(user,"@",host,"+",number,__FILE__,__LINE__); if( s ) *s = '.'; Set_str_value(&job->info,IDENTIFIER,id); if( id ) free(id); id = 0; s = Find_str_value(&job->info,IDENTIFIER); } return(s); } void Dump_job( const char *title, struct job *job ) { int i; struct line_list *lp; if( title ) LOGDEBUG( "*** Job %s *** - 0x%lx", title, Cast_ptr_to_long(job)); Dump_line_list_sub( "info",&job->info); LOGDEBUG(" datafiles - count %d", job->datafiles.count ); for( i = 0; i < job->datafiles.count; ++i ){ char buffer[SMALLBUFFER]; plp_snprintf(buffer,sizeof(buffer), " datafile[%d]", i ); lp = (void *)job->datafiles.list[i]; Dump_line_list_sub(buffer,lp); } Dump_line_list_sub( "destination",&job->destination); if( title ) LOGDEBUG( "*** end ***" ); } void Job_printable( struct job *job, struct line_list *spool_control, int *pprintable, int *pheld, int *pmove, int *perr, int *pdone ) { char *s; char buffer[SMALLBUFFER]; char destbuffer[SMALLBUFFER]; struct stat statb; int n, printable = 0, held = 0, move = 0, error = 0, done = 0,destination, destinations; if(DEBUGL4)Dump_job("Job_printable - job info",job); if(DEBUGL4)Dump_line_list("Job_printable - spool control",spool_control); buffer[0] = 0; if( job->info.count == 0 ){ plp_snprintf(buffer,sizeof(buffer), "removed" ); } else if( Find_flag_value(&job->info,INCOMING_TIME) ){ int pid = Find_flag_value(&job->info,INCOMING_PID); if( !pid || kill( pid, 0 ) ){ plp_snprintf(buffer,sizeof(buffer), "incoming (orphan)" ); } else { plp_snprintf(buffer,sizeof(buffer), "incoming" ); } } else if( (error = Find_flag_value(&job->info,ERROR_TIME)) ){ plp_snprintf(buffer,sizeof(buffer), "error" ); } else if( Find_flag_value(&job->info,HOLD_TIME) ){ plp_snprintf(buffer,sizeof(buffer), "hold" ); held = 1; } else if( (done = Find_flag_value(&job->info,DONE_TIME)) ){ plp_snprintf(buffer,sizeof(buffer), "done" ); } else if( (n = Find_flag_value(&job->info,SERVER)) && kill( n, 0 ) == 0 ){ int delta; time_t now = time((void *)0); time_t last_change = Find_flag_value(&job->info,START_TIME); if( !ISNULL(Status_file_DYN) && !stat( Status_file_DYN, &statb ) && last_change < statb.st_mtime ){ last_change = statb.st_mtime; } if( !ISNULL(Log_file_DYN) && !stat( Log_file_DYN, &statb ) && last_change < statb.st_mtime ){ last_change = statb.st_mtime; } delta = now - last_change; if( Stalled_time_DYN && delta > Stalled_time_DYN ){ plp_snprintf( buffer, sizeof(buffer), "stalled(%dsec)", delta ); } else { n = Find_flag_value(&job->info,ATTEMPT); plp_snprintf(buffer,sizeof(buffer), "active" ); if( n > 0 ){ plp_snprintf( buffer, sizeof(buffer), "active(attempt-%d)", n+1 ); } } printable = 1; } else if((s = Find_str_value(&job->info,MOVE)) ){ plp_snprintf(buffer,sizeof(buffer), "moved->%s", s ); move = 1; } else if( Get_hold_class(&job->info, spool_control ) ){ plp_snprintf(buffer,sizeof(buffer), "holdclass" ); held = 1; } else { printable = 1; } if( (destinations = Find_flag_value(&job->info,DESTINATIONS)) ){ printable = 0; for( destination = 0; destination < destinations; ++destination ){ Get_destination(job,destination); if(DEBUGL4)Dump_job("Job_destination_printable - job",job); destbuffer[0] = 0; if( Find_flag_value(&job->destination,ERROR_TIME) ){ plp_snprintf(destbuffer,sizeof(destbuffer), "error" ); } else if( Find_flag_value(&job->destination,HOLD_TIME) ){ plp_snprintf(destbuffer,sizeof(destbuffer), "hold" ); held += 1; } else if( Find_flag_value(&job->destination,DONE_TIME) ){ plp_snprintf(destbuffer,sizeof(destbuffer), "done" ); } else if( (n = Find_flag_value(&job->destination,SERVER)) && kill( n, 0 ) == 0 ){ int delta; n = Find_flag_value(&job->destination,START_TIME); delta = time((void *)0) - n; if( Stalled_time_DYN && delta > Stalled_time_DYN ){ plp_snprintf( destbuffer, sizeof(destbuffer), "stalled(%dsec)", delta ); } else { n = Find_flag_value(&job->destination,ATTEMPT); plp_snprintf(destbuffer,sizeof(destbuffer), "active" ); if( n > 0 ){ plp_snprintf( destbuffer, sizeof(destbuffer), "active(attempt-%d)", n+1 ); } } printable += 1; } else if((s = Find_str_value(&job->destination,MOVE)) ){ plp_snprintf(destbuffer,sizeof(destbuffer), "moved->%s", s ); move += 1; } else if( Get_hold_class(&job->destination, spool_control ) ){ plp_snprintf(destbuffer,sizeof(destbuffer), "holdclass" ); held += 1; } else { printable += 1; } Set_str_value(&job->destination,PRSTATUS,destbuffer); Set_flag_value(&job->destination,PRINTABLE,printable); Set_flag_value(&job->destination,HELD,held); Update_destination(job); } } Set_str_value(&job->info,PRSTATUS,buffer); Set_flag_value(&job->info,PRINTABLE,printable); Set_flag_value(&job->info,HELD,held); if( pprintable ) *pprintable = printable; if( pheld ) *pheld = held; if( pmove ) *pmove = move; if( perr ) *perr = error; if( pdone ) *pdone = done; DEBUG3("Job_printable: printable %d, held %d, move '%d', error '%d', done '%d', status '%s'", printable, held, move, error, done, buffer ); } int Server_active( char *file ) { struct stat statb; int serverpid = 0; int fd = Checkread( file, &statb ); if( fd >= 0 ){ serverpid = Read_pid( fd ); close(fd); DEBUG5("Server_active: checking file %s, serverpid %d", file, serverpid ); if( serverpid > 0 && kill(serverpid,0) ){ serverpid = 0; } } DEBUG3("Server_active: file %s, serverpid %d", file, serverpid ); return( serverpid ); } /* * Destination Information * The destination information is stored in the control file * as lines of the form: * NNN=..... where NNN is the destination number * .... is the escaped destination information * During normal printing or other activity, the destination information * is unpacked into the job->destination line list. */ /* * Update_destination updates the information with the values in the * job->destination line list. */ void Update_destination( struct job *job ) { char *s, *t, buffer[SMALLBUFFER]; int id; id = Find_flag_value(&job->destination,DESTINATION); plp_snprintf(buffer,sizeof(buffer), "DEST%d",id); s = Join_line_list(&job->destination,"\n"); t = Escape(s,1); Set_str_value(&job->info,buffer,t); free(s); free(t); if(DEBUGL4)Dump_job("Update_destination",job); } /* * Get_destination puts the requested information into the * job->destination structure if it is available. * returns: 1 if not found, 0 if found; */ int Get_destination( struct job *job, int n ) { char buffer[SMALLBUFFER]; char *s; int result = 1; plp_snprintf(buffer,sizeof(buffer), "DEST%d", n ); Free_line_list(&job->destination); if( (s = Find_str_value(&job->info,buffer)) ){ s = safestrdup(s,__FILE__,__LINE__); Unescape(s); Split(&job->destination,s,Line_ends,1,Option_value_sep,1,1,1,0); if(s) free( s ); s = 0; result = 0; } return( result ); } /* * Get_destination_by_name puts the requested information into the * job->destination structure if it is available. * returns: 1 if not found, 0 if found; */ int Get_destination_by_name( struct job *job, char *name ) { int result = 1; char *s; Free_line_list(&job->destination); if( name && (s = Find_str_value(&job->info,name)) ){ s = safestrdup(s,__FILE__,__LINE__); Unescape(s); Split(&job->destination,s,Line_ends,1,Option_value_sep,1,1,1,0); if(s) free( s ); s = 0; result = 0; } return( result ); } /* * Trim_status_file - trim a status file to an acceptible length */ int Trim_status_file( int status_fd, char *file, int max, int min ) { int tempfd, status; char buffer[LARGEBUFFER]; struct stat statb; char *tempfile, *s; int count; tempfd = status = -1; DEBUG1("Trim_status_file: file '%s' max %d, min %d", file, max, min); /* if the file does not exist, do not create it */ if( ISNULL(file) ) return( status_fd ); if( stat( file, &statb ) == 0 ){ DEBUG1("Trim_status_file: '%s' max %d, min %d, size %ld", file, max, min, (long)(statb.st_size) ); if( max > 0 && statb.st_size/1024 > max ){ status = Checkwrite( file, &statb,O_RDWR,0,0); tempfd = Make_temp_fd(&tempfile); if( min > max || min == 0 ){ min = max/4; } if( min == 0 ) min = 1; DEBUG1("Trim_status_file: trimming to %d K", min); lseek( status, 0, SEEK_SET ); lseek( status, -min*1024, SEEK_END ); while( (count = ok_read( status, buffer, sizeof(buffer) - 1 ) ) > 0 ){ buffer[count] = 0; if( (s = safestrchr(buffer,'\n')) ){ *s++ = 0; Write_fd_str( tempfd, s ); break; } } while( (count = ok_read( status, buffer, sizeof(buffer) ) ) > 0 ){ if( write( tempfd, buffer, count) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Trim_status_file: cannot write tempfile" ); } } lseek( tempfd, 0, SEEK_SET ); lseek( status, 0, SEEK_SET ); ftruncate( status, 0 ); while( (count = ok_read( tempfd, buffer, sizeof(buffer) ) ) > 0 ){ if( write( status, buffer, count) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Trim_status_file: cannot write tempfile" ); } } unlink(tempfile); close(status); } close( tempfd ); if( status_fd > 0 ) close( status_fd ); status_fd = Checkwrite( file, &statb,0,0,0); } return( status_fd ); } /******************************************************************** * BSD and LPRng order * We use these values to determine the order of jobs in the file * The order of the characters determines the order of the options * in the control file. A * puts all unspecified options there ********************************************************************/ static char BSD_order[] = "HPJCLIMWT1234" ; static char LPRng_order[] = "HPJCLIMWT1234*" ; char *Fix_datafile_infox( struct job *job, const char *number, const char *suffix, const char *xlate_format, int update_df_names ) { int i, copies, linecount, count, jobcopies, copy, group, offset; char *s, *Nline, *transfername, *dataline; struct line_list *lp, outfiles; char prefix[8]; char fmt[2]; Init_line_list(&outfiles); transfername = dataline = Nline = 0; if(DEBUGL4)Dump_job("Fix_datafile_info - starting", job ); /* now we find the number of different data files */ count = 0; /* we look through the data file list, looking for jobs with the name * OTRANSFERNAME. If we find a new one, we create the correct form * of the job datafile */ for( linecount = 0; linecount < job->datafiles.count; ++linecount ){ char *openname; lp = (void *)job->datafiles.list[linecount]; transfername = Find_str_value(lp,OTRANSFERNAME); if( ! transfername ) transfername = Find_str_value(lp,DFTRANSFERNAME); Set_str_value(lp,NTRANSFERNAME,transfername); openname = Find_str_value(lp,OPENNAME); if( ISNULL(openname) ) Set_str_value(lp,OPENNAME,transfername); if( !(s = Find_casekey_str_value(&outfiles,transfername,Hash_value_sep)) ){ /* we add the entry */ offset = count % 52; group = count / 52; ++count; if( (group >= 52) ){ fatal(LOG_INFO, "Fix_datafile_info: too many data files"); } plp_snprintf(prefix,sizeof(prefix), "d%c%c", ("fghijklmnopqrstuvwxyzabcde" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" )[group], ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz")[offset] ); s = safestrdup3(prefix,number,suffix,__FILE__,__LINE__); if( transfername ) Set_casekey_str_value(&outfiles,transfername,s); Set_str_value(lp,NTRANSFERNAME,s); if(s) free(s); s = 0; } else { Set_str_value(lp,NTRANSFERNAME,s); } } Free_line_list(&outfiles); Set_decimal_value(&job->info,DATAFILE_COUNT,count); if(DEBUGL4)Dump_job("Fix_datafile_info - after finding duplicates", job ); jobcopies = Find_flag_value(&job->info,COPIES); if( !jobcopies ) jobcopies = 1; fmt[0] = 'f'; fmt[1] = 0; DEBUG4("Fix_datafile_info: jobcopies %d", jobcopies ); for(copy = 0; copy < jobcopies; ++copy ){ for( linecount = 0; linecount < job->datafiles.count; ++linecount ){ lp = (void *)job->datafiles.list[linecount]; if(DEBUGL5)Dump_line_list("Fix_datafile_info - info", lp ); transfername = Find_str_value(lp,NTRANSFERNAME); Nline = Find_str_value(lp,"N"); fmt[0] = 'f'; if( (s = Find_str_value(lp,FORMAT)) ){ fmt[0] = *s; } if( xlate_format ){ int l = safestrlen(xlate_format); for( i = 0; i+1 < l; i+= 2 ){ if( (xlate_format[i] == fmt[0]) || (xlate_format[i] == '*') ){ fmt[0] = xlate_format[i+1]; break; } } } copies = Find_flag_value(lp,COPIES); if( copies == 0 ) copies = 1; for(i = 0; i < copies; ++i ){ if( Nline && !Nline_after_file_DYN ){ dataline = safeextend4(dataline,"N",Nline,"\n",__FILE__,__LINE__); } dataline = safeextend4(dataline,fmt,transfername,"\n",__FILE__,__LINE__); if( Nline && Nline_after_file_DYN ){ dataline = safeextend4(dataline,"N",Nline,"\n",__FILE__,__LINE__); } } DEBUG4("Fix_datafile_info: file [%d], dataline '%s'", linecount, dataline); } } DEBUG4("Fix_datafile_info: adding remove lines" ); for( linecount = 0; linecount < job->datafiles.count; ++linecount ){ lp = (void *)job->datafiles.list[linecount]; if(DEBUGL4)Dump_line_list("Fix_datafile_info - info", lp ); transfername = Find_str_value(lp,NTRANSFERNAME); if( update_df_names ){ transfername = Find_str_value(lp,NTRANSFERNAME); Set_str_value(lp,DFTRANSFERNAME,transfername); Set_str_value(lp,OTRANSFERNAME,0); } if( !Find_casekey_str_value(&outfiles,transfername,Hash_value_sep) ){ dataline = safeextend4(dataline,"U",transfername,"\n",__FILE__,__LINE__); Set_casekey_str_value(&outfiles,transfername,"YES"); } DEBUG4("Fix_datafile_info: file [%d], dataline '%s'", linecount, dataline); Set_str_value(lp,NTRANSFERNAME,0); } Free_line_list(&outfiles); return(dataline); } int ordercomp( const void *left, const void *right, const void *orderp) { const char *lpos, *rpos, *wildcard, *order; int cmp; order = (const char *)orderp; /* blank lines always come last */ if( (wildcard = safestrchr( order, '*' )) ){ wildcard = order + safestrlen(order); } lpos = *((const char **)left); if( lpos == 0 || *lpos == 0 ){ lpos = order+safestrlen(order); } else if( !(lpos = safestrchr( order, *lpos )) ){ lpos = wildcard; } rpos = *((const char **)right); if( rpos == 0 || *rpos == 0 ){ rpos = order+safestrlen(order); } else if( !(rpos = safestrchr( order, *rpos )) ){ rpos = wildcard; } cmp = lpos - rpos; DEBUG4("ordercomp '%s' to '%s' -> %d", *((const char **)left), *((const char **)right), cmp ); return( cmp ); } struct maxlen{ int c, len; } maxclen[] = { { 'A', 131 }, { 'C', 31 }, { 'D', 1024 }, { 'H', 31 }, { 'I', 31 }, { 'J', 99 }, { 'L', 31 }, { 'N', 131 }, { 'M', 131 }, { 'N', 131 }, { 'P', 31 }, { 'Q', 131 }, { 'R', 131 }, { 'S', 131 }, { 'T', 79 }, { 'U', 131 }, { 'W', 31 }, { 'Z', 1024 }, { '1', 131 }, { '2', 131 }, { '3', 131 }, { '4', 131 }, {0,0} }; /******************************************************************** * int Fix_control( struct job *job, char *filexter, * char *xlate_format, char *update_df_names ) * fix the order of lines in the control file so that they * are in the order of the letters in the order string. * Lines are checked for metacharacters and other trashy stuff * that might have crept in by user efforts * * job - control file area in memory * order - order of options * * order string: Letter - relative position in file * * matches any character not in string * can have only one wildcard in string * Berkeley- HPJCLIMWT1234 * PLP- HPJCLIMWT1234* * * RETURNS: 0 if fixed correctly * non-zero if there is something wrong with this file and it should * be rejected out of hand * * Fix up the control file, setting the various entries * to be compatible with transfer to the remote location * 1. info will have fromhost, priority, and number information * if not, you will need to add it. * ************************************************************************/ void Fix_control( struct job *job, char *filter, char *xlate_format, int update_df_names ) { char *s, *t; const char *file_hostname, *number, *priority, *order; char buffer[SMALLBUFFER], pr[2]; int tempfd, tempfc; int i, n, j, cccc, wildcard, len; struct line_list controlfile; Init_line_list(&controlfile); if(DEBUGL3) Dump_job( "Fix_control: starting", job ); /* we set the control file with the single letter values in the job ticket file */ for( i = 0; i < job->info.count; ++i ){ int c; s = job->info.list[i]; if( s && (c = s[0]) && isupper(c) && c != 'N' && c != 'U' && s[1] == '=' ){ /* remove banner from control file */ if( c == 'L' && Suppress_header_DYN && !Always_banner_DYN ) continue; s[1] = 0; Set_str_value(&controlfile,s,s+2); s[1] = '='; } } if(DEBUGL3) Dump_line_list( "Fix_control: control file", &controlfile ); n = j = 0; n = Find_decimal_value( &job->info,NUMBER); j = Find_decimal_value( &job->info,SEQUENCE); number = Fix_job_number(job, n+j); if( !(priority = Find_str_value( &job->destination,PRIORITY)) && !(priority = Find_str_value( &job->info,PRIORITY)) && !(priority = Default_priority_DYN) ){ priority = "A"; } pr[0] = *priority; pr[1] = 0; file_hostname = Find_str_value(&job->info,FILE_HOSTNAME); if( !file_hostname ){ file_hostname = Find_str_value(&job->info,FROMHOST); if( file_hostname == 0 || *file_hostname == 0 ){ file_hostname = FQDNHost_FQDN; } Set_str_value(&job->info,FILE_HOSTNAME,file_hostname); file_hostname = Find_str_value(&job->info,FILE_HOSTNAME); } t = 0; if( (Backwards_compatible_DYN || Use_shorthost_DYN) && (t = safestrchr( file_hostname, '.' )) ){ *t = 0; } /* fix control file name */ s = safestrdup4("cf",pr,number,file_hostname,__FILE__,__LINE__); Set_str_value(&job->info,XXCFTRANSFERNAME,s); if(s) free(s); s = 0; if(t) *t = '.'; /* fix control file contents */ s = Make_identifier( job ); if( job->destination.count == 0 ){ Set_str_value(&controlfile,IDENTIFIER,s); } else { s = Find_str_value(&job->destination,IDENTIFIER); cccc = Find_flag_value(&job->destination,COPIES); n = Find_flag_value(&job->destination,COPY_DONE); if( cccc > 1 ){ plp_snprintf(buffer,sizeof(buffer), "C%d",n+1); s = safestrdup2(s,buffer,__FILE__,__LINE__); Set_str_value(&controlfile,IDENTIFIER,s); if(s) free(s); s = 0; } else { Set_str_value(&controlfile,IDENTIFIER,s); } } if( !Find_str_value(&controlfile,DATE) ){ Set_str_value(&controlfile,DATE, Time_str( 0, 0 ) ); } if( (Use_queuename_DYN || Force_queuename_DYN) && !Find_str_value(&controlfile,QUEUENAME) ){ s = Force_queuename_DYN; if( s == 0 ) s = Queue_name_DYN; if( s == 0 ) s = Printer_DYN; Set_str_value(&controlfile,QUEUENAME, s ); } /* fix up the control file lines overrided by routing */ buffer[1] = 0; for( i = 0; i < job->destination.count; ++i ){ s = job->destination.list[i]; cccc = cval(s); if( isupper(cccc) && cval(s+1) == '=' ){ buffer[0] = cccc; Set_str_value( &controlfile,buffer,s+2 ); } } order = Control_file_line_order_DYN; if( !order && Backwards_compatible_DYN ){ order = BSD_order; } else if( !order ){ order = LPRng_order; } wildcard = (safestrchr( order,'*') != 0); /* * remove any line not required and fix up line metacharacters */ buffer[1] = 0; for( i = 0; i < controlfile.count; ){ /* get line and first character on line */ s = controlfile.list[i]; cccc = *s; buffer[0] = cccc; /* remove any non-listed options */ if( (!isupper(cccc) && !isdigit(cccc)) || (!safestrchr(order, cccc) && !wildcard) ){ Set_str_value( &controlfile,buffer,0); } else { if( Backwards_compatible_DYN ){ for( j = 0; maxclen[j].c && cccc != maxclen[j].c ; ++j ); if( (len = maxclen[j].len) && safestrlen(s+1) > len ){ s[len+1] = 0; } } ++i; } } /* * we check to see if order is correct - we need to check to * see if allowed options in file first. */ if(DEBUGL3)Dump_line_list( "Fix_control: before sorting", &controlfile ); n = Mergesort( controlfile.list, controlfile.count, sizeof( char *), ordercomp, order ); if( n ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Fix_control: Mergesort failed" ); } if(DEBUGL3) Dump_job( "Fix_control: after sorting", job ); for( i = 0; i < controlfile.count; ++i ){ s = controlfile.list[i]; memmove(s+1,s+2,safestrlen(s+2)+1); } s = 0; { char *datalines; char *temp = Join_line_list(&controlfile,"\n"); DEBUG3( "Fix_control: control info '%s'", temp ); datalines = Fix_datafile_infox( job, number, file_hostname, xlate_format, update_df_names ); DEBUG3( "Fix_control: data info '%s'", datalines ); temp = safeextend2(temp,datalines,__FILE__,__LINE__); Set_str_value(&job->info,CF_OUT_IMAGE,temp); if( temp ) free(temp); temp = 0; if( datalines ) free(datalines); datalines = 0; } if( filter ){ char *f_name = 0, *c_name = 0; DEBUG3("Fix_control: filter '%s'", filter ); tempfd = Make_temp_fd( &f_name ); tempfc = Make_temp_fd( &c_name ); s = Find_str_value(&job->info,CF_OUT_IMAGE ); if( Write_fd_str( tempfc, s ) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Fix_control: write to tempfile failed" ); } if( lseek( tempfc, 0, SEEK_SET ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Fix_control: lseek failed" ); } if( (n = Filter_file( Send_query_rw_timeout_DYN, tempfc, tempfd, "CONTROL_FILTER", filter, Filter_options_DYN, job, 0, 1 )) ){ Errorcode = n; logerr_die(LOG_ERR, "Fix_control: control filter failed with status '%s'", Server_status(n) ); } s = 0; if( n < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Fix_control: read from tempfd failed" ); } s = Get_fd_image( tempfd, 0 ); if( s == 0 || *s == 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Fix_control: zero length control filter output" ); } DEBUG4("Fix_control: control filter output '%s'", s); Set_str_value(&job->info,CF_OUT_IMAGE,s); if(s) free(s); s = 0; if( f_name ) unlink(f_name); f_name = 0; if( c_name ) unlink(c_name); c_name = 0; close( tempfc ); tempfc = -1; close( tempfd ); tempfd = -1; } } /* * Buffer management * Set up and put values into an output buffer for * transmission at a later time */ void Init_buf(char **buf, int *max, int *len) { DEBUG4("Init_buf: buf 0x%lx, max %d, len %d", Cast_ptr_to_long(*buf), *max, *len ); if( *max <= 0 ) *max = LARGEBUFFER; if( *buf == 0 ) *buf = realloc_or_die( *buf, *max+1,__FILE__,__LINE__); *len = 0; (*buf)[0] = 0; } void Put_buf_len( const char *s, int cnt, char **buf, int *max, int *len ) { DEBUG4("Put_buf_len: starting- buf 0x%lx, max %d, len %d, adding %d", Cast_ptr_to_long(*buf), *max, *len, cnt ); if( s == 0 || cnt <= 0 ) return; if( *max - *len <= cnt ){ *max += ((LARGEBUFFER + cnt )/1024)*1024; *buf = realloc_or_die( *buf, *max+1,__FILE__,__LINE__); DEBUG4("Put_buf_len: update- buf 0x%lx, max %d, len %d", Cast_ptr_to_long(*buf), *max, *len); } memcpy( *buf+*len, s, cnt ); *len += cnt; (*buf)[*len] = 0; } void Put_buf_str( const char *s, char **buf, int *max, int *len ) { if( s && *s ) Put_buf_len( s, safestrlen(s), buf, max, len ); } lprng-3.8.B/src/common/sendmail.c0000644000131400013140000001023711531672132013622 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: sendmail.c,v 1.74 2004/09/24 20:19:59 papowell Exp $"; #include "lp.h" #include "errorcodes.h" #include "fileopen.h" #include "getqueue.h" #include "sendmail.h" #include "child.h" /**** ENDINCLUDE ****/ /* * sendmail --- tell people about job completion * 1. fork a sendmail process * 2. if successful, send the good news * 3. if unsuccessful, send the bad news */ void Sendmail_to_user( int retval, struct job *job ) { char buffer[SMALLBUFFER], msg[SMALLBUFFER]; int n, tempfd; char *id, *mailname, *opname, *s; /* * check to see if the user really wanted * "your file was printed ok" message */ id = Find_str_value(&job->info,IDENTIFIER); if(!id) id = Find_str_value(&job->info,XXCFTRANSFERNAME); mailname = Find_str_value(&job->info,MAILNAME); opname = Mail_operator_on_error_DYN; DEBUG2("Sendmail_to_user: user '%s', operator '%s', sendmail '%s'", mailname, opname, Sendmail_DYN ); /* We will let the sendmail script or program check for correct formats This allows the most hideous things to be done to mail messages but we know that this is a loophole if( !safestrchr( mailname,'%') && !safestrchr(mailname,'@') ) mailname = 0; if( !safestrchr( opname,'%') && !safestrchr(opname,'@') ) opname = 0; */ if( retval == JSUCC ) opname = 0; if( Sendmail_DYN == 0 ) return; if( !Sendmail_to_user_DYN ) mailname = 0; if( mailname == 0 && opname == 0 ) return; tempfd = Make_temp_fd( 0 ); DEBUG2("Sendmail_to_user: user '%s', operator '%s'", mailname, opname ); msg[0] = 0; if( mailname ){ plp_snprintf( msg, sizeof(msg), "'%s'", mailname ); plp_snprintf( buffer, sizeof(buffer), "To: %s\n", mailname ); if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; } if( opname ){ n = safestrlen(msg); plp_snprintf( msg+n, sizeof(msg)-n, "%s'%s'",n?" and ":"", opname ); plp_snprintf(buffer,sizeof(buffer), "%s: %s\n", mailname?"CC":"To", opname ); if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; } setstatus( job, "sending mail to %s", msg ); plp_snprintf(buffer,sizeof(buffer), "From: %s@%s\n", Mail_from_DYN ? Mail_from_DYN : Printer_DYN, FQDNHost_FQDN ); if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; plp_snprintf(buffer,sizeof(buffer), "Subject: %s@%s job %s\n\n", Printer_DYN, FQDNHost_FQDN, id ); if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; /* now do the message */ plp_snprintf(buffer,sizeof(buffer), _("printer %s job %s"), Printer_DYN, id ); if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; switch( retval) { case JSUCC: plp_snprintf(buffer,sizeof(buffer), _(" was successful.\n")); break; case JFAIL: plp_snprintf(buffer,sizeof(buffer), _(" failed, and retry count was exceeded.\n") ); break; case JABORT: plp_snprintf(buffer,sizeof(buffer), _(" failed and could not be retried.\n") ); break; default: plp_snprintf(buffer,sizeof(buffer), _(" died a horrible death.\n")); break; } if( Write_fd_str( tempfd, buffer ) < 0 ) goto wr_error; /* * get the last status of the spooler */ if( (s = Get_file_image( Queue_status_file_DYN, Max_status_size_DYN )) ){ if( Write_fd_str( tempfd, "\nStatus:\n\n" ) < 0 || Write_fd_str( tempfd, s ) < 0 ) goto wr_error; if(s) free(s); s = 0; } if( (s = Get_file_image( Status_file_DYN, Max_status_size_DYN )) ){ if( Write_fd_str( tempfd, "\nFilter Status:\n\n" ) < 0 || Write_fd_str( tempfd, s ) < 0 ) goto wr_error; if(s) free(s); s = 0; } if( lseek( tempfd, 0, SEEK_SET ) == -1 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Sendmail_to_user: seek failed"); } n = Filter_file( Send_job_rw_timeout_DYN, tempfd, -1, "MAIL", Sendmail_DYN, 0, job, 0, 0 ); if( n ){ Errorcode = JABORT; logerr(LOG_ERR, "Sendmail_to_user: '%s' failed '%s'", Sendmail_DYN, Server_status(n) ); } return; wr_error: Errorcode = JABORT; logerr_die(LOG_ERR, "Sendmail_to_user: write failed"); } lprng-3.8.B/src/common/openprinter.c0000644000131400013140000001551511531672132014377 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errorcodes.h" #include "fileopen.h" #include "linksupport.h" #include "lockfile.h" #include "stty.h" #include "openprinter.h" /*************************************************************************** * int Printer_open: opens the Printer_DYN ***************************************************************************/ /* * int Printer_open( * lp_device - open this device * char error, int errlen - record errors * int max_attempts - max attempts to open device or socket * int interval, - interval between attempts * int max_interval, - maximum interval * int grace, - minimum time between attempts * int connect_timeout - time to wait for connection success * int *pid - if we have a filter program, return pid * returns: * file descriptor */ int Printer_open( char *lp_device, int *status_fd, struct job *job, int max_attempts, int interval, int max_interval, int grace, int connect_tmout, int *filterpid, int *poll_for_status ) { int attempt, err = 0, n, device_fd, c, in[2], pid, readable, mask; struct stat statb; time_t tm; char tm_str[32], errmsg[SMALLBUFFER]; char *host, *port, *filter; struct line_list args; int errlen = sizeof(errmsg); errmsg[0] = 0; Init_line_list(&args); host = port = filter = 0; *filterpid = 0; DEBUG1( "Printer_open: device '%s', max_attempts %d, grace %d, interval %d, max_interval %d", lp_device, max_attempts, grace, interval, max_interval ); time( &tm ); tm_str[0] = 0; if( lp_device == 0 ){ fatal(LOG_ERR, "Printer_open: printer '%s' missing lp_device value", Printer_DYN ); } *status_fd = device_fd = -1; *poll_for_status = 0; /* we repeat until we get the device or exceed maximum attempts */ for( attempt = 0; device_fd < 0 && (max_attempts <= 0 || attempt < max_attempts); ++attempt ){ errmsg[0] = 0; if( grace ) plp_sleep(grace); c = lp_device[0]; switch( c ){ case '|': #if !defined(HAVE_SOCKETPAIR) fatal(LOG_ERR, "Printer_open: requires socketpair() system call for output device to be filter"); #else if( socketpair( AF_UNIX, SOCK_STREAM, 0, in ) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Printer_open: socketpair() for filter input failed"); } #endif Max_open(in[0]); Max_open(in[1]); DEBUG3("Printer_open: fd in[%d,%d]", in[0], in[1] ); /* set up file descriptors */ Free_line_list(&args); Check_max(&args,10); args.list[args.count++] = Cast_int_to_voidstar(in[0]); /* stdin */ args.list[args.count++] = Cast_int_to_voidstar(in[0]); /* stdout */ args.list[args.count++] = Cast_int_to_voidstar(in[0]); /* stderr */ if( (pid = Make_passthrough( lp_device, Filter_options_DYN, &args, job, 0 )) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Printer_open: could not create LP_FILTER process"); } args.count = 0; Free_line_list(&args); *filterpid = pid; device_fd = in[1]; *status_fd = in[1]; if( (close( in[0] ) == -1 ) ){ logerr_die(LOG_INFO, "Printer_open: close(%d) failed", in[0]); } break; case '/': DEBUG3( "Printer_open: Is_server %d, DaemonUID %ld, DaemonGID %ld, UID %ld, EUID %ld, GID %ld, EGID %ld", Is_server, (long)DaemonUID, (long)DaemonGID, (long)getuid(), (long)geteuid(), (long)getgid(), (long)getegid() ); device_fd = Checkwrite_timeout( connect_tmout, lp_device, &statb, (Read_write_DYN || Lock_it_DYN) ?(O_RDWR):(O_APPEND|O_WRONLY), 0, Nonblocking_open_DYN ); err = errno; if( device_fd > 0 ){ if( Lock_it_DYN ){ int status; /* * lock the device so that multiple servers can * use it */ status = 0; if( isatty( device_fd ) ){ status = LockDevice( device_fd, 0 ); } else if( S_ISREG(statb.st_mode ) ){ status = Do_lock( device_fd, 0 ); } if( status < 0 ){ err = errno; setstatus( job, "lock '%s' failed - %s", lp_device, Errormsg(errno) ); close( device_fd ); device_fd = -1; } } if( device_fd > 0 && isatty( device_fd ) ){ Do_stty( device_fd ); } *status_fd = device_fd; } break; default: if( safestrchr( lp_device, '%' ) ){ /* we have a host%port form */ host = lp_device; } else { Errorcode = JABORT; fatal(LOG_ERR, "Printer_open: printer '%s', bad 'lp' entry '%s'", Printer_DYN, lp_device ); } DEBUG1( "Printer_open: doing link open '%s'", lp_device ); setstatus(job, "opening TCP/IP connection to %s", host ); *status_fd = device_fd = Link_open( host, connect_tmout, 0, 0, errmsg, errlen ); err = errno; break; } if( device_fd < 0 ){ DEBUG1( "Printer_open: open '%s' failed, max_attempts %d, attempt %d '%s'", lp_device, max_attempts, attempt, Errormsg(err) ); if( max_attempts && attempt <= max_attempts ){ n = 8; if( attempt < n ) n = attempt; n = interval*( 1 << n ); if( max_interval > 0 && n > max_interval ) n = max_interval; setstatus( job, "cannot open '%s' - '%s', attempt %d, sleeping %d", lp_device, errmsg[0]?errmsg:Errormsg( err), attempt+1, n ); if( n > 0 ){ plp_sleep(n); } } else { setstatus( job, "cannot open '%s' - '%s', attempt %d", lp_device, errmsg[0]?errmsg:Errormsg( err), attempt+1 ); } } } if( device_fd >= 0 ){ int fd = *status_fd; if( fstat( fd, &statb ) < 0 ) { logerr_die(LOG_INFO, "Printer_open: fstat() on status_fd %d failed", fd); } /* we can only read status from a device, fifo, or socket */ if( (mask = fcntl( fd, F_GETFL, 0 )) == -1 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Printer_open: cannot fcntl fd %d", fd ); } DEBUG2( "Printer_open: status_fd %d fcntl 0%o", fd, mask ); mask &= O_ACCMODE; /* first, check to see if we have RD or RW */ readable = 1; switch( mask ){ case O_WRONLY: readable = 0; if( fd == device_fd ){ *status_fd = -1; } else { Errorcode = JABORT; fatal(LOG_ERR, "Printer_open: LOGIC ERROR: status_fd %d WRITE ONLY", fd ); } break; } /* we handle the case where we have a device like a parallel port * or a USB port which does NOT support 'select()' * AND where there may be some really strange status at the end * of the printing operation * AND we cannot close the connection UNTIL we get the status * This is really silly but we need to handle it. Note that the * IFHP filter has to do exactly the same thing... Sigh... */ if( readable && S_ISCHR(statb.st_mode) && !isatty(device_fd) ){ *poll_for_status = 1; } } DEBUG1 ("Printer_open: '%s' is fd %d", lp_device, device_fd); return( device_fd ); } lprng-3.8.B/src/common/lpbanner.c0000644000131400013140000007342011531672131013631 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include #include "portable.h" #include "plp_snprintf.h" /*************************************************************************** * Filter template and frontend. * * A filter is invoked with the following parameters, * which can be in any order, and perhaps some missing. * * filtername arguments \ <- from PRINTCAP entry * -PPrinter -wwidth -llength -xwidth -ylength [-c] \ * -Kcontrolfilename -Lbnrname \ * [-iindent] \ * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ * -Fformat -Tdebug [affile] * * 1. Parameters can be in different order than the above. * 2. Optional parameters can be missing * 3. Values specified for the width, length, etc., are from PRINTCAP * or from the overridding user specified options. * * This program provides a common front end for most of the necessary * grunt work. This falls into the following classes: * 1. Parameter extraction. * 2. Suspension when used as the "of" filter. * 3. Termination and accounting * The front end will extract parameters, then call the filter() * routine, which is responsible for carrying out the required filter * actions. filter() is invoked with the printer device on fd 1, * and error log on fd 2. * The "halt string", which is a sequence of characters that * should cause the filter to suspend itself, is passed to filter. * When these characters are detected, the "suspend_ofilter()" routine should be * called. * * On successful termination, the accounting file will be updated. * * The filter() routine should return 0 (success), 1 (retry) or 2 (abort). * * Parameter Extraction * The main() routine will extract parameters * whose values are placed in the appropriate variables. This is done * by using the ParmTable[], which has entries for each valid letter * parmeter, such as the letter flag, the type of variable, * and the address of the variable. * The following variables are provided as a default set. * -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \ * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ * -Fformat [affile] * VARIABLE FLAG TYPE PURPOSE / PRINTCAP ENTRTY * name name of filter char* argv[0], program identification * width -wwidth int PW, width in chars * length -llength int PL, length in lines * xwidth -xwidth int PX, width in pixels * xlength -xlength int PY, length in pixels * literal -c int if set, ignore control chars * controlfile -kcontrolfile char* control file name * bnrname -Lbnrname char* banner name * indent -iindent int indent amount (depends on device) * zopts -Zoptions char* extra options for printer * comment -Scomment char* printer name in comment field * class -Cclass char* classname * job -Jjob char* jobname * accntname -Raccntname char* account for billing purposes * login -nlogin char* login name * host -hhost char* host name * format -Fformat char* format * special -snumber int Special Variable for passing flags * accntfile file char* AF, accounting file * * debug - sets debug level * verbose - echo to a log file * * * DEBUGGING: a simple minded debugging version can be enabled by * compiling with the -DDEBUG option. */ static const char *name; /* name of filter */ static int debug, verbose, width = 80, length = 66, xwidth, ylength, literal, indent; static char *zopts, *class, *job, *login, *accntname, *host; static char *printer, *accntfile, *format; static char *controlfile; static char *bnrname, *comment; static int special; static char *queuename, *errorfile; #define GLYPHSIZE 15 struct glyph{ int ch, x, y; /* baseline location relative to x and y position */ char bits[GLYPHSIZE]; }; struct font{ int height; /* height from top to bottom */ int width; /* width in pixels */ int above; /* max height above baseline */ const struct glyph *glyph; /* glyphs */ }; static void banner( void ); static void getargs( int argc, char *argv[], char *envp[] ); /* VARARGS2 */ #ifdef HAVE_STDARGS static void safefprintf (int fd, const char *format,...) PRINTFATTR(2,3) ; #else static void safefprintf (); #endif int main( int argc, char *argv[], char *envp[] ) { /* set umask to safe level */ umask( 0077 ); getargs( argc, argv, envp ); /* * Turn off SIGPIPE */ (void)signal( SIGPIPE, SIG_IGN ); (void)signal( SIGCHLD, SIG_DFL ); banner(); return(0); } static void getargs( int argc, char *argv[], char *envp[] ) { int i, c; /* argument index */ char *arg, *optargv; /* argument */ if( (name = argv[0]) == 0 ) name = "FILTER"; for( i = 1; i < argc && (arg = argv[i])[0] == '-'; ++i ){ if( (c = arg[1]) == 0 ){ FPRINTF( STDERR, "missing option flag"); i = argc; break; } if( c == 'c' ){ literal = 1; continue; } optargv = &arg[2]; if( arg[2] == 0 ){ optargv = argv[++i]; if( optargv == 0 ){ FPRINTF( STDERR, "missing option '%c' value", c ); i = argc; break; } } switch(c){ case 'C': class = optargv; break; case 'T': debug = atoi( optargv ); break; case 'F': format = optargv; break; case 'J': job = optargv; break; case 'K': controlfile = optargv; break; case 'L': bnrname = optargv; break; case 'P': printer = optargv; break; case 'Q': queuename = optargv; break; case 'R': accntname = optargv; break; case 'S': comment = optargv; break; case 'Z': zopts = optargv; break; case 'h': host = optargv; break; case 'i': indent = atoi( optargv ); break; case 'l': length = atoi( optargv ); break; case 'n': login = optargv; break; case 's': special = atoi( optargv ); break; case 'v': verbose = atoi( optargv ); break; case 'w': width = atoi( optargv ); break; case 'x': xwidth = atoi( optargv ); break; case 'y': ylength = atoi( optargv ); break; case 'E': errorfile = optargv; break; default: break; } } if( i < argc ){ accntfile = argv[i]; } if( errorfile ){ int fd; fd = open( errorfile, O_APPEND | O_WRONLY, 0600 ); if( fd < 0 ){ FPRINTF( STDERR, "cannot open error log file '%s'", errorfile ); } else { FPRINTF( STDERR, "using error log file '%s'", errorfile ); if( fd != 2 ){ dup2(fd, 2 ); close(fd); } } } if( verbose || debug ){ FPRINTF(STDERR, "%s command: verbose %d, debug %d ", name, verbose, debug ); for( i = 0; i < argc; ++i ){ FPRINTF(STDERR, "%s ", argv[i] ); } FPRINTF( STDERR, "\n" ); } if( debug ){ FPRINTF(STDERR, "FILTER decoded options: " ); FPRINTF(STDERR,"login '%s'\n", login? login : "null" ); FPRINTF(STDERR,"host '%s'\n", host? host : "null" ); FPRINTF(STDERR,"class '%s'\n", class? class : "null" ); FPRINTF(STDERR,"format '%s'\n", format? format : "null" ); FPRINTF(STDERR,"job '%s'\n", job? job : "null" ); FPRINTF(STDERR,"printer '%s'\n", printer? printer : "null" ); FPRINTF(STDERR,"queuename '%s'\n", queuename? queuename : "null" ); FPRINTF(STDERR,"accntname '%s'\n", accntname? accntname : "null" ); FPRINTF(STDERR,"zopts '%s'\n", zopts? zopts : "null" ); FPRINTF(STDERR,"literal, %d\n", literal); FPRINTF(STDERR,"indent, %d\n", indent); FPRINTF(STDERR,"length, %d\n", length); FPRINTF(STDERR,"width, %d\n", width); FPRINTF(STDERR,"xwidth, %d\n", xwidth); FPRINTF(STDERR,"ylength, %d\n", ylength); FPRINTF(STDERR,"accntfile '%s'\n", accntfile? accntfile : "null" ); FPRINTF(STDERR,"errorfile '%s'\n", errorfile? errorfile : "null" ); FPRINTF(STDERR, "FILTER environment: " ); for( i = 0; (arg = envp[i]); ++i ){ FPRINTF(STDERR,"%s\n", arg ); } FPRINTF(STDERR, "RUID: %d, EUID: %d\n", (int)getuid(), (int)geteuid() ); } } /*************************************************************************** Commentary Patrick Powell Wed Jun 7 19:42:01 PDT 1995 The font information is provided as entries in a data structure. The struct font{} entry specifies the character heights and widths, as well as the number of lines needed to display the characters. The struct glyph{} array is the set of glyphs for each character. { X__11___, X__11___, X__11___, X__11___, X__11___, X_______, X_______, X__11___, cX_11___}, / * ! * / ^ lower left corner, i.e. - on baseline - x = 0, y = 8 { X_______, X_______, X_______, X_111_1_, X1___11_, X1____1_, X1____1_, X1___11_, cX111_1_, X_____1_, X1____1_, X_1111__}, / * g * / ^ lower left corner, i.e. - on baseline - x = 0, y = 8 ***************************************************************************/ #define X_______ 0 #define X______1 01 #define X_____1_ 02 #define X____1__ 04 #define X____11_ 06 #define X___1___ 010 #define X___1__1 011 #define X___1_1_ 012 #define X___11__ 014 #define X__1____ 020 #define X__1__1_ 022 #define X__1_1__ 024 #define X__11___ 030 #define X__111__ 034 #define X__111_1 035 #define X__1111_ 036 #define X__11111 037 #define X_1_____ 040 #define X_1____1 041 #define X_1___1_ 042 #define X_1__1__ 044 #define X_1_1___ 050 #define X_1_1__1 051 #define X_1_1_1_ 052 #define X_11____ 060 #define X_11_11_ 066 #define X_111___ 070 #define X_111__1 071 #define X_111_1_ 072 #define X_1111__ 074 #define X_1111_1 075 #define X_11111_ 076 #define X_111111 077 #define X1______ 0100 #define X1_____1 0101 #define X1____1_ 0102 #define X1____11 0103 #define X1___1__ 0104 #define X1___1_1 0105 #define X1___11_ 0106 #define X1__1___ 0110 #define X1__1__1 0111 #define X1__11_1 0115 #define X1__1111 0117 #define X1_1____ 0120 #define X1_1___1 0121 #define X1_1_1_1 0125 #define X1_1_11_ 0126 #define X1_111__ 0134 #define X1_1111_ 0136 #define X11____1 0141 #define X11___1_ 0142 #define X11___11 0143 #define X11_1___ 0150 #define X11_1__1 0151 #define X111_11_ 0166 #define X1111___ 0170 #define X11111__ 0174 #define X111111_ 0176 #define X1111111 0177 static const struct glyph g9x8[] = { { ' ', 0, 8, { X_______, X_______, X_______, X_______, X_______, X_______, X_______, X_______, X_______}}, /* */ { '!', 0, 8, { X__11___, X__11___, X__11___, X__11___, X__11___, X_______, X_______, X__11___, X__11___}}, /* ! */ { '"', 0, 8, { X_1__1__, X_1__1__, X_______, X_______, X_______, X_______, X_______, X_______, X_______}}, /* " */ { '#', 0, 8, { X_______, X__1_1__, X__1_1__, X1111111, X__1_1__, X1111111, X__1_1__, X__1_1__, X_______}}, /* # */ { '$', 0, 8, { X___1___, X_11111_, X1__1__1, X1__1___, X_11111_, X___1__1, X1__1__1, X_11111_, X___1___}}, /* $ */ { '%', 0, 8, { X_1_____, X1_1___1, X_1___1_, X____1__, X___1___, X__1____, X_1___1_, X1___1_1, X_____1_}}, /* % */ { '&', 0, 8, { X_11____, X1__1___, X1___1__, X_1_1___, X__1____, X_1_1__1, X1___11_, X1___11_, X_111__1}}, /* & */ { '\'', 0, 8, { X___11__, X___11__, X___1___, X__1____, X_______, X_______, X_______, X_______, X_______}}, /* ' */ { '(', 0, 8, { X____1__, X___1___, X__1____, X__1____, X__1____, X__1____, X__1____, X___1___, X____1__}}, /* ( */ { ')', 0, 8, { X__1____, X___1___, X____1__, X____1__, X____1__, X____1__, X____1__, X___1___, X__1____}}, /* ) */ { '*', 0, 8, { X_______, X___1___, X1__1__1, X_1_1_1_, X__111__, X_1_1_1_, X1__1__1, X___1___, X_______}}, /* * */ { '+', 0, 8, { X_______, X___1___, X___1___, X___1___, X1111111, X___1___, X___1___, X___1___, X_______}}, /* + */ { ',', 0, 8, { X_______, X_______, X_______, X_______, X_______, X_______, X_______, X__11___, X__11___, X__1____, X_1_____, X_______}}, /* , */ { '-', 0, 8, { X_______, X_______, X_______, X_______, X1111111, X_______, X_______, X_______, X_______}}, /* - */ { '.', 0, 8, { X_______, X_______, X_______, X_______, X_______, X_______, X_______, X__11___, X__11___}}, /* . */ { '/', 0, 8, { X_______, X______1, X_____1_, X____1__, X___1___, X__1____, X_1_____, X1______, X_______}}, /* / */ { '0', 0, 8, { X_11111_, X1_____1, X1____11, X1___1_1, X1__1__1, X1_1___1, X11____1, X1_____1, X_11111_}}, /* 0 */ { '1', 0, 8, { X___1___, X__11___, X_1_1___, X___1___, X___1___, X___1___, X___1___, X___1___, X_11111_}}, /* 1 */ { '2', 0, 8, { X_11111_, X1_____1, X______1, X_____1_, X__111__, X_1_____, X1______, X1______, X1111111}}, /* 2 */ { '3', 0, 8, { X_11111_, X1_____1, X______1, X______1, X__1111_, X______1, X______1, X1_____1, X_11111_}}, /* 3 */ { '4', 0, 8, { X_____1_, X____11_, X___1_1_, X__1__1_, X_1___1_, X1____1_, X1111111, X_____1_, X_____1_}}, /* 4 */ { '5', 0, 8, { X1111111, X1______, X1______, X11111__, X_____1_, X______1, X______1, X1____1_, X_1111__}}, /* 5 */ { '6', 0, 8, { X__1111_, X_1_____, X1______, X1______, X1_1111_, X11____1, X1_____1, X1_____1, X_11111_}}, /* 6 */ { '7', 0, 8, { X1111111, X1_____1, X_____1_, X____1__, X___1___, X__1____, X__1____, X__1____, X__1____}}, /* 7 */ { '8', 0, 8, { X_11111_, X1_____1, X1_____1, X1_____1, X_11111_, X1_____1, X1_____1, X1_____1, X_11111_}}, /* 8 */ { '9', 0, 8, { X_11111_, X1_____1, X1_____1, X1_____1, X_111111, X______1, X______1, X1_____1, X_1111__}}, /* 9 */ { ':', 0, 8, { X_______, X_______, X_______, X__11___, X__11___, X_______, X_______, X__11___, X__11___}}, /* : */ { ';', 0, 8, { X_______, X_______, X_______, X__11___, X__11___, X_______, X_______, X__11___, X__11___, X__1____, X_1_____}}, /* ; */ { '<', 0, 8, { X____1__, X___1___, X__1____, X_1_____, X1______, X_1_____, X__1____, X___1___, X____1__}}, /* < */ { '=', 0, 8, { X_______, X_______, X_______, X1111111, X_______, X1111111, X_______, X_______, X_______}}, /* = */ { '>', 0, 8, { X__1____, X___1___, X____1__, X_____1_, X______1, X_____1_, X____1__, X___1___, X__1____}}, /* > */ { '?', 0, 8, { X__1111_, X_1____1, X_1____1, X______1, X____11_, X___1___, X___1___, X_______, X___1___}}, /* ? */ { '@', 0, 8, { X__1111_, X_1____1, X1__11_1, X1_1_1_1, X1_1_1_1, X1_1111_, X1______, X_1____1, X__1111_}}, /* @ */ { 'A', 0, 8, { X__111__, X_1___1_, X1_____1, X1_____1, X1111111, X1_____1, X1_____1, X1_____1, X1_____1}}, /* A */ { 'B', 0, 8, { X111111_, X_1____1, X_1____1, X_1____1, X_11111_, X_1____1, X_1____1, X_1____1, X111111_}}, /* B */ { 'C', 0, 8, { X__1111_, X_1____1, X1______, X1______, X1______, X1______, X1______, X_1____1, X__1111_}}, /* C */ { 'D', 0, 8, { X11111__, X_1___1_, X_1____1, X_1____1, X_1____1, X_1____1, X_1____1, X_1___1_, X11111__}}, /* D */ { 'E', 0, 8, { X1111111, X1______, X1______, X1______, X111111_, X1______, X1______, X1______, X1111111}}, /* E */ { 'F', 0, 8, { X1111111, X1______, X1______, X1______, X111111_, X1______, X1______, X1______, X1______}}, /* F */ { 'G', 0, 8, { X__1111_, X_1____1, X1______, X1______, X1______, X1__1111, X1_____1, X_1____1, X__1111_}}, /* G */ { 'H', 0, 8, { X1_____1, X1_____1, X1_____1, X1_____1, X1111111, X1_____1, X1_____1, X1_____1, X1_____1}}, /* H */ { 'I', 0, 8, { X_11111_, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X_11111_}}, /* I */ { 'J', 0, 8, { X__11111, X____1__, X____1__, X____1__, X____1__, X____1__, X____1__, X1___1__, X_111___}}, /* J */ { 'K', 0, 8, { X1_____1, X1____1_, X1___1__, X1__1___, X1_1____, X11_1___, X1___1__, X1____1_, X1_____1}}, /* K */ { 'L', 0, 8, { X1______, X1______, X1______, X1______, X1______, X1______, X1______, X1______, X1111111}}, /* L */ { 'M', 0, 8, { X1_____1, X11___11, X1_1_1_1, X1__1__1, X1_____1, X1_____1, X1_____1, X1_____1, X1_____1}}, /* M */ { 'N', 0, 8, { X1_____1, X11____1, X1_1___1, X1__1__1, X1___1_1, X1____11, X1_____1, X1_____1, X1_____1}}, /* N */ { 'O', 0, 8, { X__111__, X_1___1_, X1_____1, X1_____1, X1_____1, X1_____1, X1_____1, X_1___1_, X__111__}}, /* O */ { 'P', 0, 8, { X111111_, X1_____1, X1_____1, X1_____1, X111111_, X1______, X1______, X1______, X1______}}, /* P */ { 'Q', 0, 8, { X__111__, X_1___1_, X1_____1, X1_____1, X1_____1, X1__1__1, X1___1_1, X_1___1_, X__111_1}}, /* Q */ { 'R', 0, 8, { X111111_, X1_____1, X1_____1, X1_____1, X111111_, X1__1___, X1___1__, X1____1_, X1_____1}}, /* R */ { 'S', 0, 8, { X_11111_, X1_____1, X1______, X1______, X_11111_, X______1, X______1, X1_____1, X_11111_}}, /* S */ { 'T', 0, 8, { X1111111, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___}}, /* T */ { 'U', 0, 8, { X1_____1, X1_____1, X1_____1, X1_____1, X1_____1, X1_____1, X1_____1, X1_____1, X_11111_}}, /* U */ { 'V', 0, 8, { X1_____1, X1_____1, X1_____1, X_1___1_, X_1___1_, X__1_1__, X__1_1__, X___1___, X___1___}}, /* V */ { 'W', 0, 8, { X1_____1, X1_____1, X1_____1, X1_____1, X1__1__1, X1__1__1, X1_1_1_1, X11___11, X1_____1}}, /* W */ { 'X', 0, 8, { X1_____1, X1_____1, X_1___1_, X__1_1__, X___1___, X__1_1__, X_1___1_, X1_____1, X1_____1}}, /* X */ { 'Y', 0, 8, { X1_____1, X1_____1, X_1___1_, X__1_1__, X___1___, X___1___, X___1___, X___1___, X___1___}}, /* Y */ { 'Z', 0, 8, { X1111111, X______1, X_____1_, X____1__, X___1___, X__1____, X_1_____, X1______, X1111111}}, /* Z */ { '[', 0, 8, { X_1111__, X_1_____, X_1_____, X_1_____, X_1_____, X_1_____, X_1_____, X_1_____, X_1111__}}, /* [ */ { '\\', 0, 8, { X_______, X1______, X_1_____, X__1____, X___1___, X____1__, X_____1_, X______1, X_______}}, /* \ */ { ']', 0, 8, { X__1111_, X_____1_, X_____1_, X_____1_, X_____1_, X_____1_, X_____1_, X_____1_, X__1111_}}, /* ] */ { '^', 0, 8, { X___1___, X__1_1__, X_1___1_, X1_____1, X_______, X_______, X_______, X_______, X_______}}, /* ^ */ { '_', 0, 8, { X_______, X_______, X_______, X_______, X_______, X_______, X_______, X_______, X_______, X1111111, X_______}}, /* _ */ { '`', 0, 8, { X__11___, X__11___, X___1___, X____1__, X_______, X_______, X_______, X_______, X_______}}, /* ` */ { 'a', 0, 8, { X_______, X_______, X_______, X_1111__, X_____1_, X_11111_, X1_____1, X1____11, X_1111_1}}, /* a */ { 'b', 0, 8, { X1______, X1______, X1______, X1_111__, X11___1_, X1_____1, X1_____1, X11___1_, X1_111__}}, /* b */ { 'c', 0, 8, { X_______, X_______, X_______, X_1111__, X1____1_, X1______, X1______, X1____1_, X_1111__}}, /* c */ { 'd', 0, 8, { X_____1_, X_____1_, X_____1_, X_111_1_, X1___11_, X1____1_, X1____1_, X1___11_, X_111_1_}}, /* d */ { 'e', 0, 8, { X_______, X_______, X_______, X_1111__, X1____1_, X111111_, X1______, X1____1_, X_1111__}}, /* e */ { 'f', 0, 8, { X___11__, X__1__1_, X__1____, X__1____, X11111__, X__1____, X__1____, X__1____, X__1____}}, /* f */ { 'g', 0, 8, { X_______, X_______, X_______, X_111_1_, X1___11_, X1____1_, X1____1_, X1___11_, X_111_1_, X_____1_, X1____1_, X_1111__}}, /* g */ { 'h', 0, 8, { X1______, X1______, X1______, X1_111__, X11___1_, X1____1_, X1____1_, X1____1_, X1____1_}}, /* h */ { 'i', 0, 8, { X_______, X___1___, X_______, X__11___, X___1___, X___1___, X___1___, X___1___, X__111__}}, /* i */ { 'j', 0, 8, { X_______, X_______, X_______, X____11_, X_____1_, X_____1_, X_____1_, X_____1_, X_____1_, X_____1_, X_1___1_, X__111__}}, /* j */ { 'k', 0, 8, { X1______, X1______, X1______, X1___1__, X1__1___, X1_1____, X11_1___, X1___1__, X1____1_}}, /* k */ { 'l', 0, 8, { X__11___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X__111__}}, /* l */ { 'm', 0, 8, { X_______, X_______, X_______, X1_1_11_, X11_1__1, X1__1__1, X1__1__1, X1__1__1, X1__1__1}}, /* m */ { 'n', 0, 8, { X_______, X_______, X_______, X1_111__, X11___1_, X1____1_, X1____1_, X1____1_, X1____1_}}, /* n */ { 'o', 0, 8, { X_______, X_______, X_______, X_1111__, X1____1_, X1____1_, X1____1_, X1____1_, X_1111__}}, /* o */ { 'p', 0, 8, { X_______, X_______, X_______, X1_111__, X11___1_, X1____1_, X1____1_, X11___1_, X1_111__, X1______, X1______, X1______}}, /* p */ { 'q', 0, 8, { X_______, X_______, X_______, X_111_1_, X1___11_, X1____1_, X1____1_, X1___11_, X_111_1_, X_____1_, X_____1_, X_____1_}}, /* q */ { 'r', 0, 8, { X_______, X_______, X_______, X1_111__, X11___1_, X1______, X1______, X1______, X1______}}, /* r */ { 's', 0, 8, { X_______, X_______, X_______, X_1111__, X1____1_, X_11____, X___11__, X1____1_, X_1111__}}, /* s */ { 't', 0, 8, { X_______, X__1____, X__1____, X11111__, X__1____, X__1____, X__1____, X__1__1_, X___11__}}, /* t */ { 'u', 0, 8, { X_______, X_______, X_______, X1____1_, X1____1_, X1____1_, X1____1_, X1___11_, X_111_1_}}, /* u */ { 'v', 0, 8, { X_______, X_______, X_______, X1_____1, X1_____1, X1_____1, X_1___1_, X__1_1__, X___1___}}, /* v */ { 'w', 0, 8, { X_______, X_______, X_______, X1_____1, X1__1__1, X1__1__1, X1__1__1, X1__1__1, X_11_11_}}, /* w */ { 'x', 0, 8, { X_______, X_______, X_______, X1____1_, X_1__1__, X__11___, X__11___, X_1__1__, X1____1_}}, /* x */ { 'y', 0, 8, { X_______, X_______, X_______, X1____1_, X1____1_, X1____1_, X1____1_, X1___11_, X_111_1_, X_____1_, X1____1_, X_1111__}}, /* y */ { 'z', 0, 8, { X_______, X_______, X_______, X111111_, X____1__, X___1___, X__1____, X_1_____, X111111_}}, /* z */ { '}', 0, 8, { X___11__, X__1____, X__1____, X__1____, X_1_____, X__1____, X__1____, X__1____, X___11__}}, /* } */ { '|', 0, 8, { X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___, X___1___}}, /* | */ { '}', 0, 8, { X__11___, X____1__, X____1__, X____1__, X_____1_, X____1__, X____1__, X____1__, X__11___}}, /* } */ { '~', 0, 8, { X_11____, X1__1__1, X____11_, X_______, X_______, X_______, X_______, X_______, X_______}}, /* ~ */ { 'X', 0, 8, { X_1__1__, X1__1__1, X__1__1_, X_1__1__, X1__1__1, X__1__1_, X_1__1__, X1__1__1, X__1__1_}} /* rub-out */ }; /* 9 by 8 font: 12 rows high, 8 cols wide, 9 lines above baseline */ static const struct font Font9x8 = { 12, 8, 9, g9x8 }; static void Out_line( void ); static void breakline( int c ); static void bigprint( const struct font *font, const char *line ); static void do_char( const struct font *font, const struct glyph *glyph, char *str, int line, int wid ); /* * Print a banner * * banner(): print the banner * 1. Allocate a buffer for output string * 2. Calculate the various proportions * - topblast * - topbreak * - big letters * - info - 6 lines * - * - bottombreak * - bottomblast */ static char bline[1024]; static int bigjobnumber, biglogname, bigfromhost, bigjobname; static int top_break, /* break lines at top of page */ top_sep, /* separator from info at top of page */ bottom_sep, /* separator from info at bottom of page */ bottom_break; /* break lines at bottom of page */ static int breaksize = 3; /* numbers of rows in break */ /* * userinfo: just p rintf the information */ static void userinfo( void ) { time_t tmp; time(&tmp); (void) plp_snprintf( bline, sizeof(bline), "User: %s@%s (%s)", login, host, bnrname); Out_line(); strftime(bline,sizeof(bline),"Date: %b %d %H:%M:%S", localtime(&tmp)); Out_line(); (void) plp_snprintf( bline, sizeof(bline), "Job: %s", job ); Out_line(); (void) plp_snprintf( bline, sizeof(bline), "Class: %s", class ); Out_line(); } /* * seebig: calcuate if the big letters can be seen * i.e.- printed on the page */ static void seebig( int *len, int bigletter_height, int *big ) { *big = 0; if( *len > bigletter_height ){ *big = bigletter_height+1; *len -= *big; } } /* * banner: does all the actual work */ static const char *isnull( const char *s ) { if( s == 0 ) s = ""; return( s ); } static void banner(void) { int len; /* length of page */ int i; /* ACME integers, INC */ char jobnumber[1024]; jobnumber[0] = 0; #if 0 /* read from the STDIN */ (void)fgets( jobnumber, sizeof(jobnumber), stdin ); if(debug)FPRINTF(STDOUT, "BANNER CMD '%s'\n", jobnumber ); #endif bigjobnumber = biglogname = bigfromhost = bigjobname = 0; /* now calculate the numbers of lines available */ if(debug)FPRINTF(STDERR, "BANNER: length %d\n", length ); len = length; len -= 4; /* user information */ /* now we add a top break and bottom break */ if( len > 2*breaksize ){ top_break = breaksize; bottom_break = breaksize; } else { top_break = 1; bottom_break = 1; } len -= (top_break + bottom_break); if( bnrname == 0 ){ bnrname = login; } /* see if we can do big letters */ jobnumber[0] = 0; if( controlfile ){ strncpy( jobnumber, controlfile+3, 3 ); jobnumber[3] = 0; } if( *jobnumber ) seebig( &len, Font9x8.height, &bigjobnumber ); if(bnrname && *bnrname) seebig( &len, Font9x8.height, &biglogname ); if(host && *host ) seebig( &len, Font9x8.height, &bigfromhost ); if(job && *job) seebig( &len, Font9x8.height, &bigjobname ); /* now we see how much space we have left */ while( length > 0 && len < 0 ){ len += length; } /* * we add padding * Note that we can optionally produce a banner page * exactly PL-1 lines long * This allows a form feed to be added onto the end. */ if( len > 0 ){ /* adjust the total page length */ /* len = len -1; */ /* check to see if we make breaks a little larger */ if( len > 16 ){ top_break += 3; bottom_break += 3; len -= 6; } top_sep = len/2; bottom_sep = len - top_sep; } if(debug)FPRINTF(STDERR, "BANNER: length %d, top_break %d, top_sep %d\n", length, top_break, top_sep ); if(debug)FPRINTF(STDERR, "BANNER: bigjobnumber %d, jobnumber '%s'\n", bigjobnumber, isnull(jobnumber) ); if(debug)FPRINTF(STDERR, "BANNER: biglogname %d, bnrname '%s'\n", biglogname, isnull(bnrname) ); if(debug)FPRINTF(STDERR, "BANNER: bigfromhost %d, host '%s'\n", bigfromhost, isnull(host) ); if(debug)FPRINTF(STDERR, "BANNER: bigjobname %d, jobname '%s'\n", bigjobname, isnull(job) ); if(debug)FPRINTF(STDERR, "BANNER: userinfo %d\n", 4 ); if(debug)FPRINTF(STDERR, "BANNER: bottom_sep %d, bottom_break %d\n", bottom_sep, bottom_break ); for( i = 0; i < top_break; ++i ){ breakline( '*'); } for( i = 0; i < top_sep; ++i ){ breakline( 0 ); } /* * print the Name, Host and Jobname in BIG letters * allow some of them to be dropped if there isn't enough * room. */ if( bigjobnumber ) bigprint( &Font9x8, jobnumber ); if( biglogname ) bigprint( &Font9x8, bnrname ); if( bigfromhost ) bigprint( &Font9x8, host); if( bigjobname ) bigprint( &Font9x8, job ); userinfo(); for( i = 0; i < bottom_sep; ++i ){ breakline( 0 ); } for( i = 0; i < bottom_break; ++i ){ breakline( '*'); } } static void breakline( int c ) { int i; if( c ){ for( i = 0; i < width; i++) bline[i] = c; bline[i] = '\0'; } else { bline[0] = '\0'; } Out_line(); } /*************************************************************************** * bigprint( struct font *font, char * line) * print the line in big characters * for i = topline to bottomline do * for each character in the line do * get the scan line representation for the character * foreach bit in the string do * if the bit is set, print X, else print ' '; * endfor * endfor * endfor * ***************************************************************************/ static void bigprint( const struct font *font, const char *line ) { int i, j, k, len; /* ACME Integers, Inc. */ bline[width] = 0; len = strlen(line); if(debug)FPRINTF(STDERR,"bigprint: '%s'\n", line ); for( i = 0; i < font->height; ++i ){ for( j = 0; j < width; ++j ){ bline[j] = ' '; } for( j = 0, k = 0; j < width && k < len; j += font->width, ++k ){ do_char( font, &font->glyph[line[k]-32], &bline[j], i, width - j ); } Out_line(); } bline[0] = 0; Out_line(); } /*************************************************************************** * write the buffer out to the file descriptor. * don't do if fail is invalid. ***************************************************************************/ static void Out_line( void ) { int i, l; const char *str; bline[sizeof(bline)-1] = 0; if( width < (int)sizeof(bline) ) bline[width] = 0; for( str = bline, i = strlen(str); i > 0 && (l = write( 1, str, i)) > 0; i -= l, str += l ); for( str = "\n", i = strlen(str); i > 0 && (l = write( 1, str, i)) > 0; i -= l, str += l ); } static void do_char( const struct font *font, const struct glyph *glyph, char *str, int line, int wid ) { int chars, i, j, k; const char *s; /* if(debug)FPRINTF(STDERR,"do_char: '%c', wid %d\n", glyph->ch, wid ); */ chars = (font->width+7)/8; /* calculate the row */ s = &glyph->bits[line*chars]; /* get start of row */ for( k = 0, i = 0; k < wid && i < chars; ++i ){ /* for each byte in row */ for( j = 7; k < wid && j >= 0; ++k, --j ){ /* from most to least sig bit */ if( *s & (1<pw_uid; } } DEBUG2( "lprm: uid '%ld'", (long)uid ); found = ( uid == OriginalRUID ); DEBUG2( "lprm: found '%ld'", (long)found ); } if( !found ){ DEBUG1( "-U (username) can only be used by ROOT or authorized users" ); Username_JOB = 0; } } if( Username_JOB ){ Set_DYN( &Logname_DYN, Username_JOB ); } Add_line_list(&args,Logname_DYN,0,0,0); for( i = Optind; argv[i]; ++i ){ Add_line_list(&args,argv[i],0,0,0); } Check_max(&args,2); args.list[args.count] = 0; if( All_printers ){ if( All_line_list.count == 0 ){ FPRINTF(STDERR,"no printers\n"); cleanup(0); } for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,All_line_list.list[i] ); Do_removal(args.list); } } else { Get_printer(); Do_removal(args.list); } Free_line_list(&args); DEBUG1("lprm: done"); Remove_tempfiles(); DEBUG1("lprm: tempfiles removed"); Errorcode = 0; DEBUG1("lprm: cleaning up"); cleanup(0); } void Do_removal(char **argv) { int fd, n; char msg[LINEBUFFER]; DEBUG1("Do_removal: start"); Fix_Rm_Rp_info(0,0); if( ISNULL(RemotePrinter_DYN) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - cannot remove jobs from device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } /* fix up authentication */ if( Auth ){ Set_DYN(&Auth_DYN, getenv("AUTH")); } if( Check_for_rg_group( Logname_DYN ) ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - not in privileged group\n"), Printer_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } if( Direct_DYN && Lp_device_DYN ){ plp_snprintf( msg, sizeof(msg), _("Printer: %s - direct connection to device '%s'\n"), Printer_DYN, Lp_device_DYN ); if( Write_fd_str( 1, msg ) < 0 ) cleanup(0); return; } fd = Send_request( 'M', REQ_REMOVE, argv, Connect_timeout_DYN, Send_query_rw_timeout_DYN, 1 ); if( fd > 0 ){ shutdown( fd, 1 ); while( (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN, fd, msg, sizeof(msg)) ) > 0 ){ if( write(1,msg,n) < 0 ) cleanup(0); } close(fd); } DEBUG1("Do_removal: end"); } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ extern char *next_opt; static void Get_parms_clean(int argc, char *argv[] ); static void Get_parms_lprm(int argc, char *argv[] ); void Get_parms(int argc, char *argv[] ) { if( argv[0] && (Name = strrchr( argv[0], '/' )) ) { ++Name; } else { Name = argv[0]; } /* check to see if we simulate (poorly) the LP options */ if( Name && safestrcmp( Name, "clean" ) == 0 ){ LP_mode = 1; Get_parms_clean(argc,argv); } else { Get_parms_lprm(argc,argv); } if( Verbose ){ FPRINTF( STDERR, "%s\n", Version ); if( Verbose > 1 ) Printlist( Copyright, 1 ); } } static void Get_parms_lprm(int argc, char *argv[] ) { int option; while ((option = Getopt (argc, argv, "AaD:P:U:V" )) != EOF) switch (option) { case 'A': Auth = 1; break; case 'a': All_printers = 1; Set_DYN(&Printer_DYN,"all"); break; case 'D': Parse_debug(Optarg, 1); break; case 'V': ++Verbose; break; case 'U': Username_JOB = Optarg; break; case 'P': Set_DYN(&Printer_DYN, Optarg); break; default: usage(); break; } } static void Get_parms_clean(int argc, char *argv[] ) { char *name; int option; while ((option = Getopt (argc, argv, "AD:" )) != EOF) switch (option) { case 'A': Auth = 1; break; case 'D': Parse_debug( Optarg, 1 ); break; default: usage(); break; } if( Optind < argc ){ name = argv[argc-1]; Get_all_printcap_entries(); if( safestrcasecmp(name,ALL) != 0){ if( Find_exists_value( &All_line_list, name, Hash_value_sep ) ){ Set_DYN(&Printer_DYN,name); argv[argc-1] = 0; } } else { All_printers = 1; Set_DYN(&Printer_DYN,"all"); } } } static void usage(void) { if( !LP_mode ){ FPRINTF(STDERR, _(" usage: %s [-A] [-a | -Pprinter] [-Ddebuglevel] (jobid|user|'all')*\n" " -a - all printers\n" " -A - use authentication\n" " -Pprinter - printer (default PRINTER environment variable)\n" " -Uuser - impersonate this user (root or privileged user only)\n" " -Ddebuglevel - debug level\n" " -V - show version information\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'lprm -Plp 30' removes job 30 on printer lp\n" " 'lprm -a' removes all your jobs on all printers\n" " 'lprm -a all' removes all jobs on all printers\n" " Note: lprm removes only jobs for which you have removal permission\n"), Name ); } else { FPRINTF(STDERR, _(" usage: %s [-A] [-Ddebuglevel] (jobid|user|'all')* [printer]\n" " -A - use authentication\n" " -Ddebuglevel - debug level\n" " user removes user jobs\n" " all removes all jobs\n" " jobid removes job number jobid\n" " Example:\n" " 'clean 30 lp' removes job 30 on printer lp\n" " 'clean' removes first job on default printer\n" " 'clean all' removes all your jobs on default printer\n" " 'clean all all' removes all your jobs on all printers\n" " Note: clean removes only jobs for which you have removal permission\n"), Name ); } { char buffer[128]; FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); } Parse_debug("=",-1); FPRINTF( STDOUT, "%s\n", Version ); exit(1); } lprng-3.8.B/src/common/lpd_secure.c0000644000131400013140000003017511531672132014156 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "user_auth.h" #include "lpd_dispatch.h" #include "getopt.h" #include "getqueue.h" #include "proctitle.h" #include "permission.h" #include "linksupport.h" #include "errorcodes.h" #include "fileopen.h" #include "lpd_rcvjob.h" #include "child.h" #include "lpd_jobs.h" #include "krb5_auth.h" #include "lpd_secure.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * Patrick Powell Mon Apr 17 05:43:48 PDT 1995 * * The protocol used to send a secure job consists of the following * following: * * \REQ_SECUREprintername C/F user authtype\n - receive a command * 0 1 2 3 4 * \REQ_SECUREprintername C/F user authtype jobsize\n - receive a job * 0 1 2 3 4 * * The server will return an ACK, and then start the authentication * process. See README.security for details. * ***************************************************************************/ static int Do_secure_work( char *jobsize, int from_server, char *tempfile, struct line_list *header_info ); static const struct security *Fix_receive_auth( char *name, struct line_list *info ); /************************************************************************* * Receive_secure() - receive a secure transfer *************************************************************************/ int Receive_secure( int *sock, char *input ) { char *printername; char error[SMALLBUFFER]; /* error message */ char *authtype; char *cf, *s; char *jobsize = 0; char *user = 0; int tempfd = -1; int ack, status, from_server; struct line_list args, header_info, info; struct stat statb; char *tempfile = 0; const struct security *security = 0; Name = "RCVSEC"; memset( error, 0, sizeof(error)); ack = 0; status = 0; DEBUGF(DRECV1)("Receive_secure: input line '%s'", input ); Init_line_list( &args ); Init_line_list( &header_info ); Init_line_list( &info ); Split(&args,input+1,Whitespace,0,0,0,0,0,0); DEBUGFC(DRECV1)Dump_line_list("Receive_secure - input", &args); if( args.count != 5 && args.count != 4 ){ plp_snprintf( error+1, sizeof(error)-1, _("bad command line '%s'"), input ); ack = ACK_FAIL; /* no retry, don't send again */ status = JFAIL; goto error; } Check_max(&args,1); args.list[args.count] = 0; /* * \REQ_SECUREprintername C/F user authtype jobsize\n - receive a job * 0 1 2 3 4 */ printername = args.list[0]; cf = args.list[1]; user = args.list[2]; /* user is escape encoded */ Unescape(user); authtype = args.list[3]; Unescape(authtype); jobsize = args.list[4]; setproctitle( "lpd %s '%s'", Name, printername ); Perm_check.authtype = authtype; from_server = 0; if( *cf == 'F' ){ from_server = 1; } /* set up the authentication support information */ if( Is_clean_name( printername ) ){ plp_snprintf( error+1, sizeof(error)-1, _("bad printer name '%s'"), input ); ack = ACK_FAIL; /* no retry, don't send again */ status = JFAIL; goto error; } Set_DYN(&Printer_DYN,printername); if( Setup_printer( printername, error+1, sizeof(error)-1, 0 ) ){ if( jobsize ){ plp_snprintf( error+1, sizeof(error)-1, _("bad printer '%s'"), printername ); ack = ACK_FAIL; /* no retry, don't send again */ status = JFAIL; goto error; } } else { int db, dbf; db = Debug; dbf = DbgFlag; s = Find_str_value(&Spool_control,DEBUG); if(!s) s = New_debug_DYN; Parse_debug( s, 0 ); if( !(DRECVMASK & DbgFlag) ){ Debug = db; DbgFlag = dbf; } else { int tdb, tdbf; tdb = Debug; tdbf = DbgFlag; Debug = db; DbgFlag = dbf; if( Log_file_DYN ){ tempfd = Checkwrite( Log_file_DYN, &statb,0,0,0); if( tempfd > 0 && tempfd != 2 ){ dup2(tempfd,2); close(tempfd); } tempfd = -1; } Debug = tdb; DbgFlag = tdbf; LOGDEBUG("Receive_secure: socket fd %d", *sock); Dump_line_list("Receive_secure - input", &args); } DEBUGF(DRECV1)("Receive_secure: debug '%s', Debug %d, DbgFlag 0x%x", s, Debug, DbgFlag ); } if( !(security = Fix_receive_auth(authtype, &info)) ){ plp_snprintf( error+1, sizeof(error)-1, _("unsupported authentication '%s'"), authtype ); ack = ACK_FAIL; /* no retry, don't send again */ status = JFAIL; goto error; } if( !security->server_receive ){ plp_snprintf( error+1, sizeof(error)-1, _("no receive method supported for '%s'"), authtype ); ack = ACK_FAIL; /* no retry, don't send again */ status = JFAIL; goto error; } if( jobsize ){ double read_len; read_len = strtod(jobsize,0); DEBUGF(DRECV2)("Receive_secure: spooling_disabled %d", Sp_disabled(&Spool_control) ); if( Sp_disabled(&Spool_control) ){ plp_snprintf( error+1, sizeof(error)-1, _("%s: spooling disabled"), Printer_DYN ); ack = ACK_RETRY; /* retry */ status = JFAIL; goto error; } if( Max_job_size_DYN > 0 && (read_len+1023)/1024 > Max_job_size_DYN ){ plp_snprintf( error+1, sizeof(error)-1, _("%s: job size %0.0f is larger than %d K"), Printer_DYN, read_len, Max_job_size_DYN ); ack = ACK_RETRY; status = JFAIL; goto error; } else if( !Check_space( read_len, Minfree_DYN, Spool_dir_DYN ) ){ plp_snprintf( error+1, sizeof(error)-1, _("%s: insufficient file space"), Printer_DYN ); ack = ACK_RETRY; status = JFAIL; goto error; } } tempfd = Make_temp_fd(&tempfile); close(tempfd); tempfd = -1; DEBUGF(DRECV1)("Receive_secure: sock %d, user '%s', jobsize '%s'", *sock, user, jobsize ); status = security->server_receive( sock, Send_job_rw_timeout_DYN, user, jobsize, from_server, authtype, &info, error+1, sizeof(error)-1, &header_info, security, tempfile, Do_secure_work); error: DEBUGF(DRECV1)("Receive_secure: status %d, ack %d, error '%s'", status, ack, error+1 ); if( status ){ if( ack == 0 ) ack = ACK_FAIL; error[0] = ack; DEBUGF(DRECV1)("Receive_secure: sending '%s'", error ); (void)Link_send( ShortRemote_FQDN, sock, Send_query_rw_timeout_DYN, error, safestrlen(error), 0 ); Errorcode = JFAIL; } Free_line_list( &args ); Free_line_list( &header_info ); Free_line_list( &info ); close( *sock ); *sock = -1; Remove_tempfiles(); if( status == 0 && jobsize ){ /* start a new server */ DEBUGF(DRECV1)("Receive_secure: starting server"); if( Server_queue_name_DYN ){ Do_queue_jobs( Server_queue_name_DYN, 0 ); } else { Do_queue_jobs( Printer_DYN, 0 ); } } cleanup(0); } static int Do_secure_work( char *jobsize, int from_server, char *tempfile, struct line_list *header_info ) { int n, len, linecount = 0, done = 0, fd, status = 0; char *s, *t; char buffer[SMALLBUFFER]; char error[SMALLBUFFER]; struct stat statb; error[0] = 0; if( (fd = Checkread(tempfile,&statb)) < 0 ){ status = JFAIL; plp_snprintf( error, sizeof(error), "Do_secure_work: reopen of '%s' failed - %s", tempfile, Errormsg(errno)); goto error; } buffer[0] = 0; n = 0; done = 0; linecount = 0; while( !done && n < (int)sizeof(buffer)-1 && (len = Read_fd_len_timeout( Send_query_rw_timeout_DYN, fd, buffer+n, sizeof(buffer)-1-n )) > 0 ){ buffer[n+len] = 0; DEBUGF(DRECV1)("Do_secure_work: read %d - '%s'", len, buffer ); while( !done && (s = safestrchr(buffer,'\n')) ){ *s++ = 0; if( safestrlen(buffer) == 0 ){ done = 1; break; } DEBUGF(DRECV1)("Do_secure_work: line [%d] '%s'", linecount, buffer ); if( (t = strchr(buffer,'=')) ){ *t++ = 0; Unescape(t); Set_str_value(header_info, buffer, t ); } else { switch( linecount ){ case 0: if( jobsize ){ if( from_server ){ Set_str_value(header_info,CLIENT,buffer); } done = 1; } else { Set_str_value(header_info,INPUT,buffer); break; } break; case 1: Set_str_value(header_info,CLIENT,buffer); done = 1; break; } } ++linecount; memmove(buffer,s,safestrlen(s)+1); n = safestrlen(buffer); } } if( fd >= 0 ) close(fd); fd = -1; DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header", header_info ); if( (status = Check_secure_perms( header_info, from_server, error, sizeof(error))) ){ goto error; } DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header after check", header_info ); buffer[0] = 0; if( jobsize ){ if( (fd = Checkread(tempfile, &statb) ) < 0 ){ status = JFAIL; plp_snprintf( error, sizeof(error), "Do_secure_work: reopen of '%s' for read failed - %s", tempfile, Errormsg(errno)); goto error; } status = Scan_block_file( fd, error, sizeof(error), header_info ); if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ status = JFAIL; plp_snprintf( error, sizeof(error), "Do_secure_work: reopen of '%s' for write failed - %s", tempfile, Errormsg(errno)); goto error; } } else { if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ status = JFAIL; plp_snprintf( error, sizeof(error), "Do_secure_work: reopen of '%s' for write failed - %s", tempfile, Errormsg(errno)); goto error; } if( (s = Find_str_value(header_info,INPUT)) ){ Dispatch_input( &fd, s, "from secure link" ); } } error: if( fd >= 0 ) close(fd); fd = -1; DEBUGF(DRECV1)("Do_secure_work: status %d, tempfile '%s', error '%s'", status, tempfile, error ); if( error[0] ){ DEBUGF(DRECV1)("Do_secure_work: updating tempfile '%s', error '%s'", tempfile, error ); if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Do_secure_work: reopen of '%s' for write failed", tempfile ); } Write_fd_str(fd,error); close(fd); } DEBUGF(DRECV1)("Do_secure_work: returning %d", status ); return( status ); } /*************************************************************************** * void Fix_auth() - get the Use_auth_DYN value for the remote printer ***************************************************************************/ static const struct security *Fix_receive_auth( char *name, struct line_list *info ) { const struct security *s; if( name == 0 ){ if( Is_server ){ name = Auth_forward_DYN; } else { name = Auth_DYN; } } s = FindSecurity(name); if( s != NULL ){ char buffer[64]; const char *str; DEBUG1("Fix_receive_auth: name '%s' matches '%s'", name, s->name ); if( !(str = s->config_tag) ) str = s->name; plp_snprintf(buffer,sizeof(buffer), "%s_", str ); Find_default_tags( info, Pc_var_list, buffer ); Find_tags( info, &Config_line_list, buffer ); Find_tags( info, &PC_entry_line_list, buffer ); Expand_hash_values( info ); } if(DEBUGL1)Dump_line_list("Fix_receive_auth: info", info ); return(s); } int Check_secure_perms( struct line_list *options, int from_server, char *error, int errlen ) { /* * line 1 - CLIENT=xxxx - client authentication * line 2 - SERVER=xxxx - server authentication * ... - FROM=xxxx - from * line 3 - INPUT=\00x - command line */ char *authfrom, *authuser; authfrom = Find_str_value(options,AUTHFROM); if( !authfrom ) authfrom = Find_str_value(options,FROM); authuser = Find_str_value(options,AUTHUSER); if( !from_server ){ if( !authuser && authfrom ) authuser = authfrom; } if( !authuser ) authuser = Find_str_value(options,CLIENT); Set_str_value(options, AUTHTYPE, Perm_check.authtype ); Set_str_value(options, AUTHFROM, authfrom ); Set_str_value(options, AUTHUSER, authuser ); Perm_check.authfrom = Find_str_value(options,AUTHFROM); Perm_check.authuser = authuser = Find_str_value(options,AUTHUSER); if( !authuser ){ plp_snprintf( error, errlen, "Printer %s@%s: missing authentication client id", Printer_DYN,Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN ); return( JABORT ); } Perm_check.authca = Find_str_value(options,AUTHCA); DEBUGFC(DRECV1)Dump_line_list("Check_secure_perms - after",options); DEBUGFC(DRECV1)Dump_perm_check( "Check_secure_perms - checking", &Perm_check ); return(0); } lprng-3.8.B/src/common/lpd.c0000644000131400013140000007464711531672131012623 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "child.h" #include "fileopen.h" #include "errorcodes.h" #include "initialize.h" #include "linksupport.h" #include "lpd_logger.h" #include "getqueue.h" #include "getopt.h" #include "proctitle.h" #include "lockfile.h" #include "lpd_worker.h" #include "lpd_jobs.h" #include "lpd_dispatch.h" #include "user_auth.h" /* force local definitions */ #undef EXTERN #undef DEFINE #undef DEFS #define EXTERN #define DEFINE(X) X #define DEFS #include "lpd.h" char* Lpd_listen_port_arg; /* command line listen port value */ #ifdef IPP_STUBS char* Ipp_listen_port_arg; /* command line listen port value */ #endif /* not IPP_STUBS */ char* Lpd_port_arg; /* command line port value */ char* Lpd_socket_arg; /* command line unix socket value */ #if HAVE_TCPD_H #include int allow_severity = LOG_INFO; int deny_severity = LOG_WARNING; #endif /**** ENDINCLUDE ****/ /*************************************************************************** * main() * - top level of LPD Lite. This is a cannonical method of handling * input. Note that we assume that the LPD daemon will handle all * of the dirty work associated with formatting, printing, etc. * * 1. get the debug level from command line arguments * 2. set signal handlers for cleanup * 3. get the Host computer Name and user Name * 4. scan command line arguments * 5. check command line arguments for consistency * ****************************************************************************/ static char *malloc_area; int main(int argc, char *argv[], char *envp[]) { int sock = 0; /* socket for listen */ pid_t pid; /* pid */ fd_set defreadfds, readfds; /* for select() */ int max_socks = 0; /* maximum number of sockets */ int lockfd; /* the lock file descriptor */ int err; time_t last_time; /* time that last Start_all was done */ time_t server_started_time; /* time servers were started */ plp_status_t status; int max_servers; int start_fd = 0; pid_t start_pid = 0, logger_process_pid = 0; int request_pipe[2], status_pipe[2]; pid_t last_fork_pid_value; struct line_list args; int first_scan = 1; int unix_sock = 0; #ifdef IPP_STUBS int ipp_sock = 0; #endif /* not IPP_STUBS */ int fd_available; Init_line_list( &args ); Is_server = 1; /* we are the LPD server */ Logger_fd = -1; #ifndef NODEBUG Debug = 0; #endif if(DEBUGL3){ int n; LOGDEBUG("lpd: argc %d", argc ); for( n = 0; n < argc; ++n ){ LOGDEBUG(" [%d] '%s'", n, argv[n] ); } LOGDEBUG("lpd: env" ); for( n = 0; envp[n]; ++n ){ LOGDEBUG(" [%d] '%s'", n, envp[n] ); } } /* set signal handlers */ (void) plp_signal(SIGHUP, (plp_sigfunc_t)Reinit); (void) plp_signal(SIGINT, cleanup_INT); (void) plp_signal(SIGQUIT, cleanup_QUIT); (void) plp_signal(SIGTERM, cleanup_TERM); (void) signal(SIGUSR1, SIG_IGN); (void) signal(SIGUSR2, SIG_IGN); (void) signal(SIGCHLD, SIG_DFL); (void) signal(SIGPIPE, SIG_IGN); /* the next bit of insanity is caused by the interaction of signal(2) and execve(2) man signal(2): When a process which has installed signal handlers forks, the child pro- cess inherits the signals. All caught signals may be reset to their de- fault action by a call to the execve(2) function; ignored signals remain ignored. man execve(2): Signals set to be ignored in the calling process are set to be ignored in ^^^^^^^ signal(SIGCHLD, SIG_IGN) <- in the acroread code??? the new process. Signals which are set to be caught in the calling pro- cess image are set to default action in the new process image. Blocked signals remain blocked regardless of changes to the signal action. The signal stack is reset to be undefined (see sigaction(2) for more informa- tion). ^&*(*&^!!! &*())&*&*!!! and again, I say, &*()(&*!!! This means that if you fork/execve a child, then you better make sure that you set up its signal/mask stuff correctly. So if somebody blocks all signals and then starts up LPD, it will not work correctly. */ { plp_block_mask oblock; plp_unblock_all_signals( &oblock ); } Get_parms(argc, argv); /* scan input args */ Initialize(argc, argv, envp, 'D' ); DEBUG1("Get_parms: UID_root %ld, OriginalRUID %ld", (long)UID_root, (long)OriginalRUID); if( UID_root && (OriginalRUID != ROOTUID) ){ fatal(LOG_ERR, "lpd installed SETUID root and started by user %ld! Possible hacker attack", (long)OriginalRUID); } Setup_configuration(); /* get the maximum number of servers allowed */ max_servers = Get_max_servers(); if(DEBUGL1){ int max_file_descriptors = Get_max_fd(); DEBUG1( "lpd: maximum servers %d, maximum file descriptors %d ", max_servers, max_file_descriptors ); } if( Lockfile_DYN == 0 ){ logerr_die(LOG_INFO, _("No LPD lockfile specified!") ); } /* chdir to the root directory */ if( chdir( "/" ) == -1 ){ Errorcode = JABORT; logerr_die(LOG_ERR, "cannot chdir to /"); } pid = Get_lpd_pid(); #if defined(__CYGWIN__) if( (pid > 0) && ( kill(pid,0) || (errno != ESRCH) )) { DIEMSG( _("Another print spooler active, possibly lpd process '%ld'"), (long)pid ); } lockfd = Lock_lpd_pid(); if( lockfd < 0 ){ DIEMSG( _("cannot open or lock lockfile - %s"), Errormsg(errno) ); } Set_lpd_pid( lockfd ); close( lockfd ); lockfd = -1; #else lockfd = Lock_lpd_pid(); if( lockfd < 0 ){ DIEMSG( _("Another print spooler active, possibly lpd process '%ld'"), (long)pid ); } Set_lpd_pid( lockfd ); #endif { char *s; s = Lpd_listen_port_arg; if( ISNULL(s) ) s = Lpd_listen_port_DYN; if( ISNULL(s) ) s = Lpd_port_DYN; if( !ISNULL(s) && safestrcasecmp( s,"off") && strtol(s,0,0) ){ sock = Link_listen(s); DEBUG1("lpd: listening socket fd %d",sock); if( sock < 0 ){ Errorcode = 1; DIEMSG("Cannot bind to lpd port '%s'", s); } if( sock >= max_socks ) max_socks = sock; } #ifdef IPP_STUBS s = Ipp_listen_port_arg; if( ISNULL(s) ) s = Ipp_listen_port_DYN; if( !ISNULL(s) && safestrcasecmp( s,"off") && strtol(s,0,0) ){ ipp_sock = Link_listen(s); DEBUG1("lpd: listening socket fd %d",ipp_sock); if( ipp_sock < 0 ){ Errorcode = 1; DIEMSG("Cannot bind to lpd port '%s'", s); } if( ipp_sock >= max_socks ) max_socks = ipp_sock; } #endif /* not IPP_STUBS */ s = Lpd_socket_arg; if( ISNULL(s) ) s = Unix_socket_path_DYN; if( !ISNULL(s) && safestrcasecmp( s,"off") ){ unix_sock = Unix_link_listen(s); DEBUG1("lpd: unix listening socket fd %d, path '%s'",unix_sock, s); if( unix_sock < 0 ){ Errorcode = 1; DIEMSG("Cannot bind to UNIX socket '%s'", s ); } if( unix_sock >= max_socks ) max_socks = unix_sock; } } /* setting nonblocking on the listening fd * will prevent a problem with terminations of connections * before ACCEPT has completed * 1. user connects, does the 3 Way Handshake * 2. before accept() is done, a RST packet is sent * 3. a select() will succeed, but the accept() will hang * 4. if the non-blocking mode is used, then the select will * succeed and the accept() will fail */ Set_nonblock_io(sock); /* * At this point you are the server for the LPD port * you need to fork to allow the regular user to continue * you put the child in its separate process group as well */ if( (pid = dofork(1)) < 0 ){ logerr_die(LOG_ERR, _("lpd: main() dofork failed") ); } else if( pid ){ if( Foreground_LPD ){ while( (pid = plp_waitpid( pid, &status, 0)) > 0 ){ DEBUG1( "lpd: process %ld, status '%s'", (long)pid, Decode_status(&status)); } } Errorcode = 0; exit(0); } /* set up the log file and standard environment - do not fool around with anything but fd 0,1,2 which should be safe as we made sure that the fd 0,1,2 existed. */ Setup_log( Logfile_LPD ); Name = "Waiting"; setproctitle( "lpd %s", Name ); /* * Write the PID into the lockfile */ #if defined(__CYGWIN__) lockfd = Lock_lpd_pid(); if( lockfd < 0 ) { DIEMSG( "Can't open lockfile for writing" ); } Set_lpd_pid( lockfd ); close( lockfd ); lockfd = -1; #else Set_lpd_pid( lockfd ); #endif if( Drop_root_DYN ){ Full_daemon_perms(); } /* establish the pipes for low level processes to use */ if( pipe( request_pipe ) == -1 ){ logerr_die(LOG_ERR, _("lpd: pipe call failed") ); } Max_open(request_pipe[0]); Max_open(request_pipe[1]); DEBUG2( "lpd: fd request_pipe(%d,%d)",request_pipe[0],request_pipe[1]); Lpd_request = request_pipe[1]; Set_nonblock_io( Lpd_request ); Logger_fd = -1; logger_process_pid = -1; if( Logger_destination_DYN ){ if( pipe( status_pipe ) == -1 ){ logerr_die(LOG_ERR, _("lpd: pipe call failed") ); } Max_open(status_pipe[0]); Max_open(status_pipe[1]); Logger_fd = status_pipe[1]; DEBUG2( "lpd: fd status_pipe(%d,%d)",status_pipe[0],status_pipe[1]); logger_process_pid = Start_logger( status_pipe[0] ); if( logger_process_pid < 0 ){ logerr_die(LOG_ERR, _("lpd: cannot start initial logger process") ); } } /* open a connection to logger */ setmessage(0,LPD,"Starting"); /* * set up the select parameters */ FD_ZERO( &defreadfds ); if( sock > 0 ) FD_SET( sock, &defreadfds ); if( unix_sock > 0 ) FD_SET( unix_sock, &defreadfds ); #ifdef IPP_STUBS if( ipp_sock > 0 ) FD_SET( ipp_sock, &defreadfds ); #endif /* not IPP_STUBS */ FD_SET( request_pipe[0], &defreadfds ); /* * start waiting for connections from processes */ last_time = time( (void *)0 ); server_started_time = 0; start_pid = last_fork_pid_value = Start_all(first_scan, &start_fd ); Fork_error( last_fork_pid_value ); if( start_pid > 0 ){ first_scan = 0; } malloc_area = sbrk(0); #ifdef DMALLOC DEBUG1( "lpd: LOOP START - sbrk 0x%lx", (long)malloc_area ); { extern int dmalloc_outfile_fd; char buffer[128]; plp_snprintf(buffer,sizeof(buffer), "lpd: LOOP START - sbrk 0x%lx\n", (long)malloc_area ); Write_fd_str(dmalloc_outfile_fd, buffer ); dmalloc_log_unfreed(); } #endif do{ struct timeval timeval, *timeout; time_t this_time = time( (void *)0 ); int elapsed_time; #ifdef DMALLOC /* check for memory leaks */ { char *s = sbrk(0); int n = s - malloc_area; DEBUG1("lpd: LOOP - sbrk 0x%lx", (long)s ); if( n > 1024 ){ extern int dmalloc_outfile_fd; char buffer[128]; plp_snprintf(buffer,sizeof(buffer), "lpd: LOOP sbrk reports 0x%lx, or %d more memory\n", (long)s, n ); Write_fd_str(dmalloc_outfile_fd, buffer ); dmalloc_log_unfreed(); DEBUG1( "lpd: LOOP sbrk reports 0x%lx, or %d more memory", (long)s, n ); malloc_area += n; } } #endif /* set up the timeout values */ timeout = 0; memset(&timeval, 0, sizeof(timeval)); if(DEBUGL3){ int fd; fd = dup(0); LOGDEBUG("lpd: next fd %d",fd); close(fd); }; DEBUG2( "lpd: Poll_time %d, Force_poll %d, start_pid %ld, start_fd %d, Started_server %d", Poll_time_DYN, Force_poll_DYN, (long)start_pid, start_fd, Started_server ); if(DEBUGL1)Dump_line_list("lpd - Servers_line_list",&Servers_line_list ); /* * collect zombies. If one exits, you can set last_fork_pid_value * to 0, as you may now be able to start a process */ while( (pid = plp_waitpid( -1, &status, WNOHANG)) > 0 ){ DEBUG1( "lpd: process %d, status '%s'", pid, Decode_status(&status)); if( pid == logger_process_pid ){ /* ARGH! the logger process died */ logger_process_pid = -1; } if( pid == start_pid ){ start_pid = -1; } last_fork_pid_value = 0; } /* * if the Logger process dies, then you have real problems, * so you need to start it up. */ if( last_fork_pid_value >= 0 && Logger_fd > 0 && logger_process_pid <= 0 ){ DEBUG1( "lpd: restarting logger process"); last_fork_pid_value = logger_process_pid = Start_logger( status_pipe[0] ); Fork_error( last_fork_pid_value ); DEBUG1("lpd: logger_process_pid %d", logger_process_pid ); } /* you really do not want to start up more proceses until you can */ if( last_fork_pid_value < 0 ){ goto waitloop; } /* * Check to see if you need to rescan the spool queues * - you have done all of the work in the Servers_line_list * started by the last scan * - it is time to do a new scan */ elapsed_time = (this_time - last_time); if( Poll_time_DYN > 0 && start_pid <= 0 ){ int doit, scanned_queue_count; DEBUG1("lpd: checking for scan, start_fd %d, start_pid %ld, Poll_time_DYN %d, elapsed_time %d, Started_server %d, Force_poll %d", start_fd, (long)start_pid, Poll_time_DYN, elapsed_time, Started_server, Force_poll_DYN ); if( elapsed_time >= Poll_time_DYN ){ for( scanned_queue_count = doit = 0; scanned_queue_count == 0 && doit < Servers_line_list.count; ++doit ){ char *s = Servers_line_list.list[doit]; if( s && cval(s) == '.' ) ++scanned_queue_count; } DEBUG1( "lpd: timeout checking for scan, scanned_queue_count %d", scanned_queue_count); if( scanned_queue_count == 0 && ( Started_server || Force_poll_DYN ) ){ last_fork_pid_value = start_pid = Start_all(first_scan, &start_fd ); Fork_error( last_fork_pid_value ); DEBUG1( "lpd: restarting poll, start_pid %ld, start_fd %d", (long)start_pid, start_fd); if( start_fd > 0 ){ first_scan = 0; Started_server = 0; last_time = this_time; } else { /* argh! process exhaustion */ goto waitloop; } } } else { /* oops... need to wait longer */ timeout = &timeval; timeval.tv_sec = Poll_time_DYN - elapsed_time; } } /* * check to see if there are any spool queues that require * service. This is the case when * - time since last startup was non-zero * - Servers_line_list has an entry * OR you have had a forced startup request */ if( Servers_line_list.count ){ int number_of_servers = Countpid(); int server_processes_started = 0; int doit; char *server_to_start = 0; int forced_start = 0; elapsed_time = this_time - server_started_time; /* find the first entry WITHOUT a '.' as first character */ if(DEBUGL1)Dump_line_list("lpd: Servers_line_list", &Servers_line_list ); for( forced_start = doit = 0; !forced_start && doit < Servers_line_list.count; ++doit ){ server_to_start = Servers_line_list.list[doit]; if( server_to_start && cval(server_to_start) != '.' ){ forced_start = 1; break; } server_to_start = 0; } #ifdef DMALLOC /* check for memory leaks */ { char *s = sbrk(0); int n = s - malloc_area; DEBUG1("lpd: BEFORE POLL SERVICE - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count ); if( n > 1024 ){ extern int dmalloc_outfile_fd; char buffer[128]; plp_snprintf(buffer,sizeof(buffer), "lpd: BEFORE POLL SERVICE sbrk reports 0x%lx, or %d more memory\n", (long)s, n ); Write_fd_str(dmalloc_outfile_fd, buffer ); dmalloc_log_unfreed(); DEBUG1( "lpd: BEFORE POLL SERVICE sbrk reports 0x%lx, or %d more memory", (long)s, n ); malloc_area += n; } } #endif while( (elapsed_time > Poll_start_interval_DYN || forced_start ) && Servers_line_list.count > 0 && server_processes_started < Poll_servers_started_DYN && number_of_servers + server_processes_started < max_servers-4 ){ DEBUG1("lpd: elapsed time %d, server_started_time %d, max_servers %d, number_of_servers %d, started %d", (int)elapsed_time, (int)server_started_time, max_servers, number_of_servers, server_processes_started ); /* find the first entry WITHOUT a '.' as first character */ for( forced_start = doit = 0; doit < Servers_line_list.count; ++doit ){ server_to_start = Servers_line_list.list[doit]; if( server_to_start && cval(server_to_start) != '.' ){ forced_start = 1; break; } server_to_start = 0; } /* Ok, then settle for the first entry */ if( !server_to_start ){ doit = 0; server_to_start = Servers_line_list.list[doit]; if( cval(server_to_start) == '.' ) ++server_to_start; } if( !ISNULL(server_to_start) ){ server_started_time = this_time; DEBUG1("lpd: starting server '%s'", server_to_start ); Free_line_list(&args); Set_str_value(&args,PRINTER,server_to_start); last_fork_pid_value = pid = Start_worker( "queue", Service_queue, &args, 0 ); Fork_error( last_fork_pid_value ); Free_line_list(&args); if( pid > 0 ){ Remove_line_list( &Servers_line_list, doit ); Started_server = 1; server_started_time = this_time; if( forced_start ){ ++number_of_servers; } else { ++server_processes_started; } } else { /* argh! process exhaustion */ goto waitloop; } } else { /* empty line... */ Remove_line_list( &Servers_line_list, doit ); } } #ifdef DMALLOC /* check for memory leaks */ { char *s = sbrk(0); int n = s - malloc_area; DEBUG1("lpd: AFTER POLL SERVICE - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count ); if( n > 1024 ){ extern int dmalloc_outfile_fd; char buffer[128]; plp_snprintf(buffer,sizeof(buffer), "lpd: AFTER POLL SERVICE sbrk reports 0x%lx, or %d more memory\n", (long)s, n ); Write_fd_str(dmalloc_outfile_fd, buffer ); dmalloc_log_unfreed(); DEBUG1( "lpd: AFTER POLL SERVICE sbrk reports 0x%lx, or %d more memory", (long)s, n ); malloc_area += n; } } #endif } /* we see if we have any work to do * and then schedule a timeout if necessary to start a process * NOTE: if the Poll_start_interval value is 0, * then we will wait until a process exits */ if( Servers_line_list.count > 0 && Poll_start_interval_DYN ){ int time_left; elapsed_time = this_time - server_started_time; time_left = Poll_start_interval_DYN - elapsed_time; if( time_left < 0 ) time_left = 0; timeout = &timeval; if( timeval.tv_sec == 0 || timeval.tv_sec > time_left ){ timeval.tv_sec = time_left; } } waitloop: /* * the place where we actually do some waiting */ DEBUG1("lpd: Started_server %d, last_fork_pid_value %ld, active servers %d, max %d", Started_server, (long)last_fork_pid_value, Countpid(), max_servers ); /* do not accept incoming call if no worker available */ readfds = defreadfds; if( Countpid() >= max_servers || last_fork_pid_value < 0 ){ DEBUG1( "lpd: not accepting requests" ); if( sock > 0 ) FD_CLR( sock, &readfds ); if( unix_sock > 0 ) FD_CLR( unix_sock, &readfds ); #ifdef IPP_STUBS if( ipp_sock > 0 ) FD_CLR( ipp_sock, &readfds ); #endif /* not IPP_STUBS */ timeval.tv_sec = 10; timeout = &timeval; } if( request_pipe[0] >= max_socks ){ max_socks = request_pipe[0]+1; } if( start_fd > 0 ){ FD_SET( start_fd, &readfds ); if( start_fd >= max_socks ){ max_socks = start_fd+1; } } DEBUG1( "lpd: starting select timeout '%s', %d sec, max_socks %d", timeout?"yes":"no", (int)(timeout?timeout->tv_sec:0), max_socks ); if(DEBUGL2){ int i; for(i=0; i < max_socks; ++i ){ if( FD_ISSET( i, &readfds ) ){ LOGDEBUG( "lpd: waiting for fd %d to be readable", i ); } } } Setup_waitpid_break(); errno = 0; fd_available = select( max_socks, &readfds, NULL, NULL, timeout ); err = errno; Setup_waitpid(); if(DEBUGL1){ int i; LOGDEBUG( "lpd: select returned %d, error '%s'", fd_available, Errormsg(err) ); for(i=0; fd_available > 0 && i < max_socks; ++i ){ if( FD_ISSET( i, &readfds ) ){ LOGDEBUG( "lpd: fd %d readable", i ); } } } /* if we got a SIGHUP then we reread configuration */ if( Reread_config || !Use_info_cache_DYN ){ DEBUG1( "lpd: rereading configuration" ); /* we need to force the LPD logger to use new printcap information */ if( Reread_config ){ if( logger_process_pid > 0 ) kill( logger_process_pid, SIGINT ); setmessage(0,LPD,"Restart"); Reread_config = 0; } Setup_configuration(); } /* mark this as a timeout */ if( fd_available < 0 ){ if( err != EINTR ){ errno = err; logerr_die(LOG_ERR, _("lpd: select error!")); break; } continue; } else if( fd_available == 0 ){ DEBUG1( "lpd: signal or time out, last_fork_pid_value %d", last_fork_pid_value ); /* we try to fork now */ if( last_fork_pid_value < 0 ) last_fork_pid_value = 1; continue; } if( sock > 0 && FD_ISSET( sock, &readfds ) ){ DEBUG1("lpd: accept on LPD socket"); Accept_connection( sock ); } if( unix_sock > 0 && FD_ISSET( unix_sock, &readfds ) ){ DEBUG1("lpd: accept on UNIX socket"); Accept_connection( unix_sock ); } #ifdef IPP_STUBS if( ipp_sock > 0 && FD_ISSET( ipp_sock, &readfds ) ){ DEBUG1("lpd: accept on IPP socket"); Accept_connection( ipp_sock ); } #endif /* not IPP_STUBS */ if( FD_ISSET( request_pipe[0], &readfds ) && Read_server_status( request_pipe[0] ) == 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, _("lpd: Lpd_request pipe EOF! cannot happen") ); } if( start_fd > 0 && FD_ISSET( start_fd, &readfds ) ){ start_fd = Read_server_status( start_fd ); } }while( 1 ); Free_line_list(&args); cleanup(0); } /*************************************************************************** * Setup_log( char *logfile, int sock ) * Purpose: to set up a standard error logging environment * saveme will prevent STDIN from being clobbered * 1. dup 'sock' to fd 0, close sock * 2. opens /dev/null on fd 1 * 3. If logfile is "-" or NULL, output file is alread opened * 4. Open logfile; if unable to, then open /dev/null for output ***************************************************************************/ static void Setup_log(char *logfile ) { struct stat statb; close(0); close(1); if (open("/dev/null", O_RDONLY, 0) != 0) { logerr_die(LOG_ERR, _("Setup_log: open /dev/null failed")); } if (open("/dev/null", O_WRONLY, 0) != 1) { logerr_die(LOG_ERR, _("Setup_log: open /dev/null failed")); } /* * open logfile; if it is "-", use STDERR; if Foreground is set, use stderr */ if( fstat(2,&statb) == -1 && dup2(1,2) == -1 ){ logerr_die(LOG_ERR, _("Setup_log: dup2(%d,%d) failed"), 1, 2); } if( logfile == 0 ){ if( !Foreground_LPD && dup2(1,2) == -1 ){ logerr_die(LOG_ERR, _("Setup_log: dup2(%d,%d) failed"), 1, 2); } } else if( safestrcmp(logfile, "-") ){ close(2); if( Checkwrite(logfile, &statb, O_WRONLY|O_APPEND, 0, 0) != 2) { logerr_die(LOG_ERR, _("Setup_log: open %s failed"), logfile ); } } } /*************************************************************************** * Reinit() * Reinitialize the database/printcap/permissions information * 1. free any allocated memory ***************************************************************************/ static void Reinit(void) { Reread_config = 1; (void) plp_signal (SIGHUP, (plp_sigfunc_t)Reinit); } /*************************************************************************** * Get_lpd_pid() and Set_lpd_pid() * Get and set the LPD pid into the LPD status file ***************************************************************************/ int Get_lpd_pid(void) { pid_t pid; char *path; path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ ); pid = Read_pid_from_file( path ); if( path ) free(path); path = 0; return(pid); } static void Set_lpd_pid(int lockfd) { /* we write our PID */ if( ftruncate( lockfd, 0 ) ){ logerr_die(LOG_ERR, _("lpd: Cannot truncate lock file") ); } Server_pid = getpid(); DEBUG1( "lpd: writing lockfile fd %d with pid '%ld'",lockfd, (long)Server_pid ); Write_pid( lockfd, Server_pid, (char *)0 ); } int Lock_lpd_pid(void) { int lockfd; char *path; struct stat statb; int euid = geteuid(); path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ ); To_euid_root(); lockfd = Checkwrite( path, &statb, O_RDWR, 1, 0 ); if( lockfd < 0 ){ logerr_die(LOG_ERR, _("lpd: Cannot open lock file '%s'"), path ); } #if !defined(__CYGWIN__) fchown( lockfd, DaemonUID, DaemonGID ); fchmod( lockfd, (statb.st_mode & ~0777) | 0644 ); #endif To_euid(euid); if( Do_lock( lockfd, 0 ) < 0 ){ close( lockfd ); lockfd = -1; } return(lockfd); } int Read_server_status( int fd ) { int status, count, found, n; char buffer[LINEBUFFER]; char *name; fd_set readfds; /* for select() */ struct timeval timeval; struct line_list l; buffer[0] = 0; errno = 0; DEBUG1( "Read_server_status: starting" ); Init_line_list(&l); while(1){ FD_ZERO( &readfds ); FD_SET( fd, &readfds ); memset(&timeval,0, sizeof(timeval)); status = select( fd+1, &readfds, NULL, NULL, &timeval ); DEBUG1( "Read_server_status: select status %d", status); if( status == 0 ){ break; } else if( status < 0 ){ close(fd); fd = 0; break; } status = ok_read(fd,buffer,sizeof(buffer)-1); DEBUG1( "Read_server_status: read status %d", status ); if( status <= 0 ){ close(fd); fd = -1; break; } buffer[status] = 0; DEBUG1( "Read_server_status: read status %d '%s'", status, buffer ); /* we split up read line and record information */ Split(&l,buffer,Whitespace,0,0,0,0,0,0); if(DEBUGL1)Dump_line_list("Read_server_status - input", &l ); for( count = 0; count < l.count; ++count ){ name = l.list[count]; if( ISNULL(name) ) continue; found = 0; for( n = 0;!found && n < Servers_line_list.count; ++n ){ found = !safestrcasecmp( Servers_line_list.list[n], name); } if( !found ){ Add_line_list(&Servers_line_list,name,0,0,0); } Started_server = 1; } Free_line_list(&l); } Free_line_list(&l); #ifdef DMALLOC { char *s = sbrk(0); int n = s - malloc_area; DEBUG1("lpd: READ_SERVER_STATUS - sbrk 0x%lx, cnt %d", (long)s, Servers_line_list.count ); if( n > 1024 ){ extern int dmalloc_outfile_fd; char buffer[128]; plp_snprintf(buffer,sizeof(buffer), "lpd: READ_SERVER_STATSUS sbrk reports 0x%lx, or %d more memory\n", (long)s, n ); Write_fd_str(dmalloc_outfile_fd, buffer ); dmalloc_log_unfreed(); DEBUG1( "lpd: READ_SERVER_STATUS sbrk reports 0x%lx, or %d more memory", (long)s, n ); malloc_area += n; } } #endif if(DEBUGL2)Dump_line_list("Read_server_status - waiting for start", &Servers_line_list ); return(fd); } /*************************************************************************** * void Get_parms(int argc, char *argv[]) * 1. Scan the argument list and get the flags * 2. Check for duplicate information ***************************************************************************/ static void usage(void) { FPRINTF( STDERR, _("usage: %s [-FV][-D dbg][-L log][-P path][-p port][-R remote LPD TCP/IP destination port]\n" " Options\n" " -D dbg - set debug level and flags\n" " -F - run in foreground, log to STDERR\n" " -L logfile - append log information to logfile\n" " -V - show version info\n" " -p port - TCP/IP listen port, 'off' disables TCP/IP listening port (lpd_listen_port)\n" " -P path - UNIX socket path, 'off' disables UNIX listening socket (unix_socket_path)\n" " -R port - remote LPD server port (lpd_port)\n"), Name ); { char buffer[128]; FPRINTF( STDERR, "Security Supported: %s\n", ShowSecuritySupported(buffer,sizeof(buffer)) ); } Parse_debug("=",-1); FPRINTF( STDERR, "%s\n", Version ); exit(1); } static const char LPD_optstr[] /* LPD options */ = "D:FL:VX:p:P:" ; static void Get_parms(int argc, char *argv[] ) { int option, verbose = 0; while ((option = Getopt (argc, argv, LPD_optstr )) != EOF){ switch (option) { case 'D': Parse_debug(Optarg, 1); break; case 'F': Foreground_LPD = 1; break; case 'L': Logfile_LPD = Optarg; break; case 'V': ++verbose; break; case 'X': Worker_LPD = Optarg; break; case 'p': Lpd_listen_port_arg = Optarg; break; case 'P': Lpd_socket_arg = Optarg; break; default: usage(); break; } } if( Optind != argc ){ usage(); } if( verbose ) { FPRINTF( STDERR, "%s\n", Version ); if( verbose > 1 ) Printlist( Copyright, 1 ); exit(0); } } /* * Accept_connection * - accept the connection and fork the child to handle it */ static void Accept_connection( int sock ) { struct line_list args; struct sockaddr sinaddr; int newsock, err; pid_t pid; socklen_t len; Init_line_list(&args); len = sizeof( sinaddr ); newsock = accept( sock, &sinaddr, &len ); err = errno; DEBUG1("Accept_connection: connection fd %d", newsock ); if( newsock > 0 ){ #if defined(TCPWRAPPERS) /* * libwrap/tcp_wrappers: * draht@suse.de, Mon Jan 28 2002 */ if( !unix_socket ){ struct request_info wrap_req; request_init(&wrap_req, RQ_DAEMON, "lpd" , RQ_FILE, newsock, NULL); fromhost(&wrap_req); openlog("lpd", LOG_PID, LOG_LPR); /* we syslog(3) initialized, no closelog(). */ if (hosts_access(&wrap_req)) { /* We accept. */ syslog(LOG_INFO, "connection from %s", eval_client(&wrap_req)); } else { syslog(LOG_WARNING, "connection refused from %s", eval_client(&wrap_req)); close( newsock ); return; } } #endif pid = Start_worker( "server", Service_connection, &args, newsock ); if( pid < 0 ){ logerr(LOG_INFO, _("lpd: fork() failed") ); /* this was written with an impossible condition, why? safefprintf(newsock, "\002%s\n", _("Server load too high")); */ } else { DEBUG1( "lpd: listener pid %ld running", (long)pid ); } close( newsock ); Free_line_list(&args); } else { errno = err; logerr(LOG_INFO, _("lpd: accept on listening socket failed") ); } } /* * int Start_all( int first_scan, int *start_fd ) * returns the pid of the process doing the scanning */ static pid_t Start_all( int first_scan, int *start_fd ) { struct line_list args; int p[2]; pid_t pid; Init_line_list(&args); DEBUG1( "Start_all: first_scan %d", first_scan ); if( pipe(p) == -1 ){ logerr_die(LOG_INFO, _("Start_all: pipe failed!") ); } Max_open(p[0]); Max_open(p[1]); DEBUG1( "Start_all: fd pipe(%d,%d)",p[0],p[1]); Set_str_value(&args,CALL,"all"); Set_decimal_value(&args,FIRST_SCAN,first_scan); pid = Start_worker( "all", Service_all, &args, p[1]); close(p[1]); if( pid < 0 ){ close( p[0] ); p[0] = -1; } DEBUG1("Start_all: pid %ld, fd %d", (long)pid, p[0] ); if( start_fd ) *start_fd = p[0]; return(pid); } plp_signal_t sigchld_handler (int signo UNUSED) { signal( SIGCHLD, SIG_DFL ); write(Lpd_request,"\n", 1); } static void Setup_waitpid (void) { signal( SIGCHLD, SIG_DFL ); } static void Setup_waitpid_break (void) { (void) plp_signal_break(SIGCHLD, sigchld_handler); } static void Fork_error( pid_t last_fork_pid_value ) { DEBUG1("Fork_error: %ld", (long)last_fork_pid_value ); if( last_fork_pid_value < 0 ){ logmsg(LOG_CRIT, "LPD: fork failed! LPD not accepting any requests"); } } lprng-3.8.B/src/common/permission.c0000644000131400013140000005221711531672132014222 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "fileopen.h" #include "globmatch.h" #include "gethostinfo.h" #include "getqueue.h" #include "permission.h" #include "linksupport.h" /**** ENDINCLUDE ****/ struct keywords permwords[] = { {"ACCEPT", 0, P_ACCEPT,0,0,0,0}, {"AUTH", 0, P_AUTH,0,0,0,0}, {"AUTHFROM", 0, P_AUTHFROM,0,0,0,0}, {"AUTHJOB", 0, P_AUTHJOB,0,0,0,0}, {"AUTHSAMEUSER", 0, P_AUTHSAMEUSER,0,0,0,0}, {"AUTHTYPE", 0, P_AUTHTYPE,0,0,0,0}, {"AUTHUSER", 0, P_AUTHUSER,0,0,0,0}, {"CONTROLLINE", 0, P_CONTROLLINE,0,0,0,0}, {"DEFAULT", 0, P_DEFAULT,0,0,0,0}, {"FORWARD", 0, P_FORWARD,0,0,0,0}, {"GROUP", 0, P_GROUP,0,0,0,0}, {"HOST", 0, P_HOST,0,0,0,0}, {"IFIP", 0, P_IFIP,0,0,0,0}, {"IP", 0, P_IP,0,0,0,0}, {"LPC", 0, P_LPC,0,0,0,0}, {"NOMATCHFOUND", 0, 0,0,0,0,0}, {"NOT", 0, P_NOT,0,0,0,0}, {"PORT", 0, P_PORT,0,0,0,0}, {"PRINTER", 0, P_PRINTER,0,0,0,0}, {"REJECT", 0, P_REJECT,0,0,0,0}, {"REMOTEGROUP", 0, P_REMOTEGROUP,0,0,0,0}, {"REMOTEHOST", 0, P_REMOTEHOST,0,0,0,0}, {"REMOTEIP", 0, P_REMOTEIP,0,0,0,0}, {"REMOTEPORT", 0, P_REMOTEPORT,0,0,0,0}, {"REMOTEUSER", 0, P_REMOTEUSER,0,0,0,0}, {"SAMEHOST", 0, P_SAMEHOST,0,0,0,0}, {"SAMEUSER", 0, P_SAMEUSER,0,0,0,0}, {"SERVER", 0, P_SERVER,0,0,0,0}, {"SERVICE", 0, P_SERVICE,0,0,0,0}, {"USER", 0, P_USER,0,0,0,0}, {"UNIXSOCKET", 0, P_UNIXSOCKET,0,0,0,0}, {"AUTHCA", 0, P_AUTHCA,0,0,0,0}, {0,0,0,0,0,0,0} }; static int match_host( struct line_list *list, struct host_information *host, int invert ); static int match_range( struct line_list *list, int port, int invert ); static int match_char( struct line_list *list, int value, int invert ); static int match_group( struct line_list *list, const char *str, int invert ); static int ingroup( char *group, const char *user ); const char *perm_str( int n ) { return(Get_keystr(n,permwords)); } static int perm_val( char *s ) { if( !s )return(0); if( safestrlen(s) == 1 && isupper(cval(s)) ){ return( P_CONTROLLINE ); } return(Get_keyval(s,permwords)); } /*************************************************************************** * Perms_check( struct line_list *perms, struct perm_check ); * - run down the list of permissions * - do the check on each of them * - if you get a distinct fail or success, return * 1. the P_NOT field inverts the result of the next test * 2. if one test fails, then we go to the next line * 3. The entire set of tests is accepted if all pass, i.e. none fail ***************************************************************************/ int Perms_check( struct line_list *perms, struct perm_check *check, struct job *job, int job_check ) { int j, c, linecount, valuecount, key; int invert = 0; int result = 0, m = 0; struct line_list values, args; char *s, *t; /* string */ int last_default_perm; char buffer[4]; DEBUGFC(DDB1)Dump_perm_check( "Perms_check - checking", check ); DEBUGFC(DDB1)Dump_line_list( "Perms_check - permissions", perms ); Init_line_list(&values); Init_line_list(&args); last_default_perm = perm_val( Default_permission_DYN ); DEBUGF(DDB1)("Perms_check: last_default_perm '%s', Default_perm '%s'", perm_str( last_default_perm ), Default_permission_DYN ); if( check == 0 || perms == 0 ){ return( last_default_perm ); } for( linecount = 0; result == 0 && linecount < perms->count; ++linecount ){ DEBUGF(DDB2)("Perms_check: line [%d]='%s'", linecount, perms->list[linecount]); Free_line_list(&values); Split(&values,perms->list[linecount],Whitespace,0,0,0,0,0,0); if( values.count == 0 ) continue; result = 0; m = 0; invert = 0; for( valuecount = 0; m == 0 && valuecount < values.count; ++valuecount ){ DEBUGF(DDB2)("Perms_check: [%d]='%s'",valuecount, values.list[valuecount] ); Free_line_list(&args); Split(&args,values.list[valuecount],Perm_sep,0,0,0,0,0,0); if( args.count == 0 ) continue; if( invert > 0 ){ invert = -1; } else { invert = 0; } key = perm_val( args.list[0] ); if( key == 0 ){ m = 1; break; } /* we remove the key entry */ Remove_line_list( &args, 0 ); DEBUGF(DDB2)("Perms_check: before doing %s, result %d, %s", perm_str(key), result, perm_str(result) ); switch( key ){ case P_NOT: invert = 1; continue; case P_REJECT: result = P_REJECT; m = 0; break; case P_ACCEPT: result = P_ACCEPT; m = 0; break; case P_USER: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ case 'X': break; default: m = match( &args, check->user, invert ); break; } break; case P_LPC: m = 1; switch (check->service){ case 'X': break; case 'C': m = match( &args, check->lpc, invert ); break; } break; case P_IP: case P_HOST: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ case 'X': break; default: m = match_host( &args, check->host, invert ); break; } break; case P_GROUP: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ case 'X': break; default: m = match_group( &args, check->user, invert ); break; } break; case P_REMOTEPORT: case P_PORT: m = 1; switch (check->service){ case 'X': case 'M': case 'C': m = match_range( &args, check->port, invert ); break; } break; case P_REMOTEUSER: m = 1; switch (check->service){ case 'X': break; default: m = match( &args, check->remoteuser, invert ); break; } break; case P_REMOTEGROUP: m = 1; switch (check->service){ case 'X': break; default: m = match_group( &args, check->remoteuser, invert ); break; } break; case P_IFIP: case P_REMOTEHOST: case P_REMOTEIP: m = match_host( &args, check->remotehost, invert ); break; case P_AUTH: m = 1; switch (check->service){ case 'X': break; default: DEBUGF(DDB3)( "Perms_check: P_AUTH authuser '%s'", check->authuser ); m = !check->authuser; if( invert ) m = !m; } break; case P_AUTHTYPE: m = 1; switch (check->service){ case 'X': break; default: DEBUGF(DDB3)( "Perms_check: P_AUTHTYPE authtype '%s'", check->authtype ); m = match( &args, check->authtype, invert ); } break; case P_AUTHFROM: m = 1; switch (check->service){ case 'X': break; default: m = match( &args, check->authfrom, invert ); } break; case P_AUTHCA: m = 1; switch (check->service){ case 'X': break; default: m = match( &args, check->authca, invert ); } break; case P_AUTHUSER: m = 1; switch (check->service){ case 'X': break; default: m = match( &args, check->authuser, invert ); } break; case P_CONTROLLINE: /* check to see if we have control line */ m = 1; if( !job_check ){ m = 0; } for( j = 0; m && j < args.count; ++j ){ if( !(t = args.list[j]) ) continue; c = cval(t); buffer[1] = 0; buffer[0] = c; if( isupper(c) && (s = Find_str_value(&job->info,buffer))){ /* we do a glob match against line */ m = Globmatch( t+1, s ); } } if( invert ) m = !m; break; case P_PRINTER: m = 1; switch (check->service){ case 'X': break; default: m = match( &args, check->printer, invert ); break; } break; case P_SERVICE: m = match_char( &args, check->service, invert ); break; case P_FORWARD: case P_SAMEHOST: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ default: /* P_SAMEHOST check succeeds if P_REMOTEIP == P_IP */ m = Same_host(check->host, check->remotehost); if( m ){ /* check to see if both remote and local are server */ int r, h; r = Same_host(check->remotehost,&Host_IP); if( r ) r = Same_host(check->remotehost,&Localhost_IP); h = Same_host(check->host,&Host_IP); if( h ) h = Same_host(check->host,&Localhost_IP); DEBUGF(DDB3)( "Perms_check: P_SAMEHOST server name check r=%d,h=%d", r, h ); if( h == 0 && r == 0 ){ m = 0; } } if( invert ) m = !m; break; } if( key == P_FORWARD ) m = !m; break; case P_SAMEUSER: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ default: break; case 'Q': case 'M': case 'C': /* check succeeds if remoteuser == user */ m = (safestrcmp( check->user, check->remoteuser ) != 0); if( invert ) m = !m; DEBUGF(DDB3)( "Perms_check: P_SAMEUSER '%s' == remote '%s', rslt %d", check->user, check->remoteuser, m ); break; } break; case P_AUTHSAMEUSER: m = 1; if( !job_check ){ m = 0; } else switch (check->service){ default: break; case 'Q': case 'M': case 'C': /* check succeeds if remoteuser == user */ t = Find_str_value(&job->info,AUTHUSER); m = (safestrcmp( check->authuser, t ) != 0); if( invert ) m = !m; DEBUGF(DDB3)( "Perms_check: P_AUTHSAMEUSER job authinfo '%s' == auth_id '%s', rslt %d", t, check->authuser, m ); break; } break; case P_AUTHJOB: m = 1; switch (check->service){ default: break; case 'Q': case 'M': case 'C': /* check succeeds if authinfo present */ t = Find_str_value(&job->info,AUTHUSER); m = !t; if( invert ) m = !m; DEBUGF(DDB3)( "Perms_check: P_AUTHJOB job authinfo '%s', rslt %d", t, m ); break; } break; case P_SERVER: m = 1; /* check succeeds if remote P_IP and server P_IP == P_IP */ m = Same_host(check->remotehost,&Host_IP); if( m ) m = Same_host(check->remotehost,&Localhost_IP); if( invert ) m = !m; break; case P_UNIXSOCKET: m = 1; /* check succeeds if connection via unix socket */ m = !check->unix_socket; if( invert ) m = !m; break; case P_DEFAULT: DEBUGF(DDB3)("Perms_check: DEFAULT - %d, values.count %d", valuecount, values.count ); m = 1; if( values.count == 2 ){ switch( perm_val( values.list[1]) ){ case P_REJECT: last_default_perm = P_REJECT; break; case P_ACCEPT: last_default_perm = P_ACCEPT; break; } } } DEBUGF(DDB2)("Perms_check: match %d, result '%s' default now '%s'", m, perm_str(result), perm_str(last_default_perm) ); } if( m ){ result = 0; } else if( result == 0 ){ result = last_default_perm; } DEBUGF(DDB1)("Perms_check: '%s' - match %d, result '%s' default now '%s'", perms->list[linecount], m, perm_str(result), perm_str(last_default_perm) ); } if( result == 0 ){ result = last_default_perm; } DEBUGF(DDB1)("Perms_check: final result %d '%s'", result, perm_str( result ) ); Free_line_list(&values); Free_line_list(&args); return( result ); } /*************************************************************************** * static int match( char **val, char *str ); * returns 1 on failure, 0 on success * - match the string against the list of options * options are glob type regular expressions; we implement this * currently using the most crude of pattern matching * - if string is null or pattern list is null, then match fails * if both are null, then match succeeds ***************************************************************************/ int match( struct line_list *list, const char *str, int invert ) { int result = 1, i, c; char *s; DEBUGF(DDB3)("match: str '%s', invert %d", str, invert ); if(str)for( i = 0; result && i < list->count; ++i ){ if( !(s = list->list[i])) continue; DEBUGF(DDB3)("match: str '%s' to '%s'", str, s ); /* now do the match */ c = cval(s); if( c == '@' ) { /* look up host in netgroup */ #ifdef HAVE_INNETGR result = !innetgr( s+1, (char *)str, 0, 0 ); #else /* HAVE_INNETGR */ DEBUGF(DDB3)("match: no innetgr() call, netgroups not permitted"); #endif /* HAVE_INNETGR */ } else if( c == '<' && cval(s+1) == '/' ){ struct line_list users; Init_line_list(&users); Get_file_image_and_split(s+1,0,0,&users,Whitespace, 0,0,0,0,0,0); DEBUGFC(DDB3)Dump_line_list("match- file contents'", &users ); result = match( &users,str,0); Free_line_list(&users); } else { result = Globmatch( s, str ); } DEBUGF(DDB3)("match: list[%d]='%s', result %d", i, s, result ); } if( invert ) result = !result; DEBUGF(DDB3)("match: str '%s' final result %d", str, result ); return( result ); } /*************************************************************************** * static int match_host( char **list, char *host ); * returns 1 on failure, 0 on success * - match the hostname/printer strings against the list of options * options are glob type regular expressions; we implement this * currently using the most crude of pattern matching * - if string is null or pattern list is null, then match fails * if both are null, then match succeeds ***************************************************************************/ static int match_host( struct line_list *list, struct host_information *host, int invert ) { int result = Match_ipaddr_value(list,host); if( invert ) result = !result; DEBUGF(DDB3)("match_host: host '%s' final result %d", host?host->fqdn:0, result ); return( result ); } /*************************************************************************** * static int match_range( char **list, int port ); * check the port number and/or range * entry has the format: number number-number ***************************************************************************/ static int portmatch( char *val, int port ) { int low, high, err; char *end; int result = 1; char *s, *t, *tend; err = 0; s = safestrchr( val, '-' ); if( s ){ *s = 0; } end = val; low = strtol( val, &end, 10 ); if( end == val || *end ) err = 1; high = low; if( s ){ tend = t = s+1; high = strtol( t, &tend, 10 ); if( t == tend || *tend ) err = 1; *s = '-'; } if( err ){ logmsg( LOG_ERR, "portmatch: bad port range '%s'", val ); } if( high < low ){ err = high; high = low; low = err; } result = !( port >= low && port <= high ); DEBUGF(DDB3)("portmatch: low %d, high %d, port %d, result %d", low, high, port, result ); return( result ); } static int match_range( struct line_list *list, int port, int invert ) { int result = 1; int i; char *s; DEBUGF(DDB3)("match_range: port '0x%x'", port ); for( i = 0; result && i < list->count; ++i ){ /* now do the match */ if( !(s = list->list[i]) ) continue; result = portmatch( s, port ); } if( invert ) result = !result; DEBUGF(DDB3)("match_range: port '%d' result %d", port, result ); return( result ); } /*************************************************************************** * static int match_char( char **list, int value ); * check for the character value in one of the option strings * entry has the format: string ***************************************************************************/ static int match_char( struct line_list *list, int value, int invert ) { int result = 1; int i; char *s; DEBUGF(DDB3)("match_char: value '0x%x' '%c'", value, value ); DEBUGFC(DDB3)Dump_line_list("match_char - lines", list ); for( i = 0; result && i < list->count; ++i ){ if( !(s = list->list[i]) ) continue; result = (safestrchr( s, value ) == 0) && (safestrchr(s,'*') == 0) ; DEBUGF(DDB3)("match_char: val %c, str '%s', match %d", value, s, result); } if( invert ) result = !result; DEBUGF(DDB3)("match_char: value '%c' result %d", value, result ); return( result ); } /*************************************************************************** * static int match_group( char **list, char *str ); * returns 1 on failure, 0 on success * - get the UID for the named user * - scan the listed groups to see if there is a group * check to see if user is in group ***************************************************************************/ static int match_group( struct line_list *list, const char *str, int invert ) { int result = 1; int i; char *s; DEBUGF(DDB3)("match_group: str '%s'", str ); for( i = 0; str && result && i < list->count; ++i ){ /* now do the match */ if( !(s = list->list[i]) ) continue; result = ingroup( s, str ); } if( invert ) result = !result; DEBUGF(DDB3)("match: str '%s' value %d", str, result ); return( result ); } /*************************************************************************** * static int ingroup( char* *group, char *user ); * returns 1 on failure, 0 on success * scan group for user name * Note: we first check for the group. If there is none, we check for * wildcard (*) in group name, and then scan only if we need to ***************************************************************************/ static int ingroup( char *group, const char *user ) { struct group *grent; struct passwd *pwent; char **members; int result = 1; DEBUGF(DDB3)("ingroup: checking '%s' for membership in group '%s'", user, group); if( group == 0 || user == 0 ){ return( result ); } /* first try getgrnam, see if it is a group */ pwent = getpwnam(user); if( group[0] == '@' ) { /* look up user in netgroup */ #ifdef HAVE_INNETGR if( !innetgr( group+1, 0, (char *)user, 0 ) ) { DEBUGF(DDB3)( "ingroup: user %s P_NOT in netgroup %s", user, group+1 ); } else { DEBUGF(DDB3)( "ingroup: user %s in netgroup %s", user, group+1 ); result = 0; } #else /* HAVE_INNETGR */ DEBUGF(DDB3)( "ingroup: no innetgr() call, netgroups not permitted" ); #endif /* HAVE_INNETGR */ } else if( group[0] == '<' && group[1] == '/' ){ struct line_list users; Init_line_list(&users); Get_file_image_and_split(group+1,0,0,&users,Whitespace, 0,0,0,0,0,0); DEBUGFC(DDB3)Dump_line_list("match- file contents'", &users ); result = match_group( &users,user,0); Free_line_list(&users); } else if( (grent = getgrnam( group )) ){ DEBUGF(DDB3)("ingroup: group id: %ld\n", (long)grent->gr_gid); if( pwent && ((long)pwent->pw_gid == (long)grent->gr_gid) ){ DEBUGF(DDB3)("ingroup: user default group id: %ld\n", (long)pwent->pw_gid); result = 0; } else for( members = grent->gr_mem; result && *members; ++members ){ DEBUGF(DDB3)("ingroup: member '%s'", *members); result = (safestrcmp( user, *members ) != 0); } } else if( safestrpbrk( group, "*[]") ){ /* wildcard in group name, scan through all groups */ setgrent(); while( result && (grent = getgrent()) ){ DEBUGF(DDB3)("ingroup: group name '%s'", grent->gr_name); /* now do match against group */ if( Globmatch( group, grent->gr_name ) == 0 ){ if( pwent && ((long)pwent->pw_gid == (long)grent->gr_gid) ){ DEBUGF(DDB3)("ingroup: user default group id: %ld\n", (long)pwent->pw_gid); result = 0; } else { DEBUGF(DDB3)("ingroup: found '%s'", grent->gr_name); for( members = grent->gr_mem; result && *members; ++members ){ DEBUGF(DDB3)("ingroup: member '%s'", *members); result = (safestrcmp( user, *members ) != 0); } } } } endgrent(); } DEBUGF(DDB3)("ingroup: result: %d", result ); return( result ); } /*************************************************************************** * Dump_perm_check( char *title, struct perm_check *check ) * Dump perm_check information ***************************************************************************/ void Dump_perm_check( const char *title, struct perm_check *check ) { char buffer[SMALLBUFFER]; if( title ) LOGDEBUG( "*** perm_check %s ***", title ); buffer[0] = 0; if( check ){ LOGDEBUG( " user '%s', rmtuser '%s', printer '%s', service '%c', lpc '%s'", check->user, check->remoteuser, check->printer, check->service, check->lpc ); Dump_host_information( " host", check->host ); Dump_host_information( " remotehost", check->remotehost ); /* LOGDEBUG( " ip '%s' port %d, unix_socket %d", inet_ntop_sockaddr( &check->addr, buffer, sizeof(buffer)), check->port, check->unix_socket ); */ LOGDEBUG( " port %d, unix_socket %d", check->port, check->unix_socket ); LOGDEBUG( " authtype '%s', authfrom '%s', authuser '%s', authca '%s'", check->authtype, check->authfrom, check->authuser, check->authca ); } } /*************************************************************************** * Perm_check_to_list( struct line_list *list, struct perm_check *check ) * Put perm_check information in list ***************************************************************************/ void Perm_check_to_list( struct line_list *list, struct perm_check *check ) { char buffer[SMALLBUFFER]; Set_str_value( list, USER, check->user ); Set_str_value( list, REMOTEUSER, check->remoteuser ); Set_str_value( list, PRINTER, check->printer ); plp_snprintf(buffer,sizeof(buffer), "%c",check->service); Set_str_value( list, SERVICE, buffer ); Set_str_value( list, LPC, check->lpc ); if( check->host ){ Set_str_value( list, HOST, check->host->fqdn ); } if( check->remotehost ){ Set_str_value( list, HOST, check->remotehost->fqdn ); } Set_decimal_value( list, PORT, check->port ); Set_str_value( list, AUTHTYPE, check->authtype ); Set_str_value( list, AUTHFROM, check->authfrom ); Set_str_value( list, AUTHUSER, check->authuser ); Set_str_value( list, AUTHCA, check->authca ); } lprng-3.8.B/src/common/debug.c0000644000131400013140000001556311531672131013122 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /************************************************************* * void Get_debug_parm(int argc, char *argv[], struct keywords *list) * Scan the command line for -D debugparms * debugparms has the format value,key=value,key,key@... * 1. if the value is an integer, then we treat it as a value for DEBUG * 2. if a key is present, then we scan the list and find the * match for the key. We then convert according to the type of * option expected. *************************************************************/ #include "lp.h" #include "errorcodes.h" #include "getopt.h" #include "child.h" /**** ENDINCLUDE ****/ struct keywords debug_vars[] /* debugging variables */ = { #if !defined(NODEBUG) { "print", 0,FLAG_K,(void *)&Debug,1, 0,0}, { "print+1",0,FLAG_K,(void *)&Debug,1, 0,0}, { "print+2",0,FLAG_K,(void *)&Debug,2, 0,0}, { "print+3",0,FLAG_K,(void *)&Debug,3, 0,0}, { "print+4",0,FLAG_K,(void *)&Debug,4, 0,0}, { "lpr",0,FLAG_K,(void *)&DbgFlag,DRECV1, DRECVMASK,0}, { "lpr+1",0,FLAG_K,(void *)&DbgFlag,DRECV1, DRECVMASK,0}, { "lpr+2",0,FLAG_K,(void *)&DbgFlag,DRECV2|DRECV1, DRECVMASK,0}, { "lpr+3",0,FLAG_K,(void *)&DbgFlag,DRECV3|DRECV2|DRECV1, DRECVMASK,0}, { "lpr+4",0,FLAG_K,(void *)&DbgFlag,DRECV4|DRECV3|DRECV2|DRECV1, DRECVMASK,0}, { "lpc",0,FLAG_K,(void *)&DbgFlag,DCTRL1, DCTRLMASK,0}, { "lpc+1",0,FLAG_K,(void *)&DbgFlag,DCTRL1, DCTRLMASK,0}, { "lpc+2",0,FLAG_K,(void *)&DbgFlag,DCTRL2|DCTRL1, DCTRLMASK,0}, { "lpc+3",0,FLAG_K,(void *)&DbgFlag,DCTRL3|DCTRL2|DCTRL1, DCTRLMASK,0}, { "lpc+4",0,FLAG_K,(void *)&DbgFlag,DCTRL4|DCTRL3|DCTRL2|DCTRL1, DCTRLMASK,0}, { "lprm",0,FLAG_K,(void *)&DbgFlag,DLPRM1, DLPRMMASK,0}, { "lprm+1",0,FLAG_K,(void *)&DbgFlag,DLPRM1, DLPRMMASK,0}, { "lprm+2",0,FLAG_K,(void *)&DbgFlag,DLPRM2|DLPRM1, DLPRMMASK,0}, { "lprm+3",0,FLAG_K,(void *)&DbgFlag,DLPRM3|DLPRM2|DLPRM1, DLPRMMASK,0}, { "lprm+4",0,FLAG_K,(void *)&DbgFlag,DLPRM4|DLPRM3|DLPRM2|DLPRM1, DLPRMMASK,0}, { "lpq",0,FLAG_K,(void *)&DbgFlag,DLPQ1, DLPQMASK,0}, { "lpq+1",0,FLAG_K,(void *)&DbgFlag,DLPQ1, DLPQMASK,0}, { "lpq+2",0,FLAG_K,(void *)&DbgFlag,DLPQ2|DLPQ1, DLPQMASK,0}, { "lpq+3",0,FLAG_K,(void *)&DbgFlag,DLPQ3|DLPQ2|DLPQ1, DLPQMASK,0}, { "lpq+4",0,FLAG_K,(void *)&DbgFlag,DLPQ4|DLPQ3|DLPQ2|DLPQ1, DLPQMASK,0}, { "network",0,FLAG_K,(void *)&DbgFlag,DNW1, DNWMASK,0}, { "network+1",0,FLAG_K,(void *)&DbgFlag,DNW1, DNWMASK,0}, { "network+2",0,FLAG_K,(void *)&DbgFlag,DNW2|DNW1, DNWMASK,0}, { "network+3",0,FLAG_K,(void *)&DbgFlag,DNW3|DNW2|DNW1, DNWMASK,0}, { "network+4",0,FLAG_K,(void *)&DbgFlag,DNW4|DNW3|DNW2|DNW1, DNWMASK,0}, { "database",0,FLAG_K,(void *)&DbgFlag,DDB1, DDBMASK,0}, { "database+1",0,FLAG_K,(void *)&DbgFlag,DDB1, DDBMASK,0}, { "database+2",0,FLAG_K,(void *)&DbgFlag,DDB2|DDB1, DDBMASK,0}, { "database+3",0,FLAG_K,(void *)&DbgFlag,DDB3|DDB2|DDB1, DDBMASK,0}, { "database+4",0,FLAG_K,(void *)&DbgFlag,DDB4|DDB3|DDB2|DDB1, DDBMASK,0}, { "database+4",0,FLAG_K,(void *)&DbgFlag,DDB4, DDBMASK,0}, { "log",0,FLAG_K,(void *)&DbgFlag,DLOG1, DLOGMASK,0}, { "log+1",0,FLAG_K,(void *)&DbgFlag,DLOG1, DLOGMASK,0}, { "log+2",0,FLAG_K,(void *)&DbgFlag,DLOG2|DLOG1, DLOGMASK,0}, { "log+3",0,FLAG_K,(void *)&DbgFlag,DLOG3|DLOG2|DLOG1, DLOGMASK,0}, { "log+4",0,FLAG_K,(void *)&DbgFlag,DLOG4|DLOG3|DLOG2|DLOG1, DLOGMASK,0}, { "test",0,INTEGER_K,(void *)&DbgTest,0,0,0}, #endif { 0,0,0,0,0,0,0 } }; /* Parse_debug (char *dbgstr, struct keywords *list, int interactive ); Input string: value,key=value,flag+n 1. crack the input line at the ',' 2. crack each option at = 3. search for key words 4. assign value to variable */ static const char *guide[] = { " use on command line, or in printcap :db=... entry", " for server:", " print: show queue (printing) actions, larger number, more information", " NUMBER same as print+NUMBER", " lpr: show servicing lpr actions", " lpq: show servicing lpq actions", " lprm: show servicing lprm actions", " network: show low level network actions", " database: show low level database actions", " log: Testing. Don't use this unless you read the code.", " test: Testing. don't use this unless you read the code.", " for clients (lpr, lpq, etc):", " print: show client actions, larger number, more information", " NUMBER same as print+NUMBER", " network: show low level network actions.", " database: show low level database actions.", 0 }; void Parse_debug (const char *dbgstr, int interactive ) { #if !defined(NODEBUG) char *key, *end; const char *convert; int i, n, found, count; struct keywords *list = debug_vars; struct line_list l; Init_line_list(&l); Split(&l,dbgstr,File_sep,0,0,0,0,0,0); for( count = 0; count < l.count; ++count ){ found = 0; end = key = l.list[count]; n = strtol(key,&end,0); if( *end == 0 ){ Debug = n; if( n == 0 )DbgFlag = 0; found = 1; } else { if( (end = safestrchr(key,'=')) ){ *end++ = 0; n = strtol(end,0,0); } /* search the keyword list */ for (i = 0; (convert = list[i].keyword) && safestrcasecmp( convert, key ); ++i ); if( convert != 0 ){ switch( list[i].type ){ case INTEGER_K: *(int *)list[i].variable = n; found = 1; break; case FLAG_K: *(int *)list[i].variable |= list[i].maxval; /* DEBUG1("Parse_debug: key '%s', val 0x%x, DbgFlag 0x%x", key, list[i].maxval, DbgFlag ); */ found = 1; break; default: break; } } } if(!found && interactive ){ int i; int lastflag = 0; FPRINTF (STDERR, "debug flag format: num | flag[+num] | flag=str\n"); FPRINTF (STDERR, " flag names:"); for (i = 0; list[i].keyword; i++) { if( safestrchr( list[i].keyword, '+' ) ) continue; if( lastflag ){ FPRINTF( STDERR, ", " ); if( !(lastflag % 4) ) FPRINTF( STDERR, "\n " ); } else { FPRINTF( STDERR, " " ); } switch( list[i].type ){ case INTEGER_K: FPRINTF (STDERR, "%s=num", list[i].keyword); break; case STRING_K: FPRINTF (STDERR, "%s=str", list[i].keyword); break; case FLAG_K: FPRINTF (STDERR, "%s[+N]", list[i].keyword ); break; default: break; } ++lastflag; } FPRINTF (STDERR, "\n"); for(i = 0; guide[i]; ++i ){ FPRINTF (STDERR, "%s\n", guide[i]); } Errorcode = JABORT; if( interactive > 0 ) cleanup(0); } } Free_line_list(&l); #endif /* LOGDEBUG("Parse_debug: Debug %d, DbgFlag 0x%x", Debug, DbgFlag ); */ } lprng-3.8.B/src/common/checkpc.c0000644000131400013140000012266111531672131013432 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "getopt.h" #include "checkpc.h" #include "getprinter.h" #include "getqueue.h" #include "initialize.h" #include "lockfile.h" #include "fileopen.h" #include "child.h" #include "stty.h" #include "proctitle.h" #include "lpd_remove.h" #include "linksupport.h" #include "gethostinfo.h" /**** ENDINCLUDE ****/ static int Noaccount; static int Nolog, Nostatus, Fix, Age, Printcap; static int Truncate = -1; static int Remove; static char *User_specified_printer; static time_t Current_time; static int Check_path_list( char *plist, int allow_missing ); int Mail_fd; /* pathnames of the spool directory (sd) and control directory (cd) */ int main( int argc, char *argv[], char *envp[] ) { int i, c, found_pc; char *path; /* end of string */ int ruid, euid, rgid, egid; char *printcap; /*char *serial_line = 0;*/ struct line_list raw, spooldirs; const char *s, *t; char *p; struct stat statb; (void)signal( SIGPIPE, SIG_IGN ); (void)signal( SIGCHLD, SIG_DFL ); s = t = printcap = 0; Init_line_list(&raw); Init_line_list(&spooldirs); /* set up the uid state */ To_euid_root(); time(&Current_time); Verbose = 0; Warnings = 1; Is_server = 1; /* send trace on STDOUT */ dup2(1,2); #ifndef NODEBUG Debug = 0; #endif s = t = 0; for( i = 0; Pc_var_list[i].keyword; s = t, ++i ){ t = Pc_var_list[i].keyword; if( s && t && strcmp(s,t) >= 0 ){ FPRINTF(STDERR, "Pc_var_list: '%s' >= '%s'\n", s, t ); } } /* scan the argument list for a 'Debug' value */ while( (c = Getopt( argc, argv, "aflprst:A:CD:P:T:V" ) ) != EOF ){ switch( c ){ default: usage(); case 'a': Noaccount = 1; break; case 'f': Fix = 1; break; case 'l': Nolog = 1; break; case 'r': Remove = 1; break; case 's': Nostatus = 1; break; case 't': if( Optarg ){ Truncate = getk( Optarg ); } else { usage(); } break; case 'A': if( Optarg){ Age = getage( Optarg ); } else { usage(); } break; case 'D': Parse_debug(Optarg,1); break; case 'V': ++Verbose; break; case 'p': ++Printcap; break; case 'P': User_specified_printer = Optarg; break; case 'T': initsetproctitle( argc, argv, envp ); Test_port( getuid(), geteuid(), Optarg ); exit(0); break; } } if( Verbose ){ if(Verbose)MESSAGE( Version ); } Initialize(argc, argv, envp, 'D' ); Setup_configuration(); To_daemon(); /* we have a user specified printcap we can check as well */ Free_line_list(&raw); for( i = Optind; i < argc; ++i ){ Getprintcap_pathlist( Require_configfiles_DYN, &raw, &PC_filters_line_list, argv[i] ); } Build_printcap_info( &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, &raw, &Host_IP ); Free_line_list( &raw ); #if defined (__CYGWIN__) if( Fix && (geteuid() != ROOTUID && getuid() != ROOTUID) ){ #else if( Fix && geteuid() && getuid() ){ #endif WARNMSG("Fix option (-f) requires root permissions\n" ); } if(Verbose)MESSAGE("Checking for configuration files '%s'", Config_file_DYN); found_pc = Check_path_list( Config_file_DYN, 0 ); if( found_pc == 0 ){ WARNMSG("No configuration file found in '%s'", Config_file_DYN ); } if(Verbose)MESSAGE("Checking for printcap files '%s'", Printcap_path_DYN); if( Is_server && Lpd_printcap_path_DYN ){ if(Verbose)MESSAGE("Checking for lpd only printcap files '%s'", Lpd_printcap_path_DYN); found_pc += Check_path_list( Lpd_printcap_path_DYN, 1 ); } else { found_pc += Check_path_list( Printcap_path_DYN, 0 ); } if( found_pc == 0 ){ WARNMSG("No printcap files!!!" ); } Get_all_printcap_entries(); euid = geteuid(); ruid = getuid(); egid = getegid(); rgid = getgid(); DEBUG1("Effective UID %d, Real UID %d, Effective GID %d, Real GID %d", euid, ruid, egid, rgid ); if(Verbose)MESSAGE(" DaemonUID %ld, DaemonGID %ld", (long)DaemonUID, (long)DaemonGID ); if(Verbose )MESSAGE("Using Config file '%s'", Config_file_DYN); /* print errors and everything on STDOUT */ if( Lockfile_DYN == 0 ){ WARNMSG( "Warning: no LPD lockfile" ); } else if( Lpd_port_DYN == 0 ){ WARNMSG( "Warning: no LPD port" ); } else { int oldfile = Spool_file_perms_DYN; Spool_file_perms_DYN = 0644; path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ ); if(Verbose)MESSAGE( "LPD lockfile '%s'", path ); if( path[0] != '/' ){ WARNMSG( "Warning: LPD lockfile '%s' not absolute path", path ); } else if( !(p = safestrrchr(path+1,'/')) ){ WARNMSG( "Warning: bad LPD lockfile '%s' path format", path ); } else { *p = 0; if( stat( path, &statb ) ){ WARNMSG( " LPD Lockfile directory '%s' does not exist!", path); if( Fix ){ mkdir_path( path ); } } *p = '/'; } if( path ) free( path ); path = 0; Spool_file_perms_DYN = oldfile; } if( Verbose )Show_all_printcap_entries(); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("main: START open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } if(Verbose)MESSAGE("Checking printcap info"); if( User_specified_printer ){ if( DEBUGL1 ) Dump_line_list("checkpc: names", &PC_names_line_list ); s = Find_str_value( &PC_names_line_list, User_specified_printer ); DEBUG1("checkpc: for SERVER %s is really %s", User_specified_printer, s ); if( s ){ Set_DYN(&Printer_DYN,s); Scan_printer(&spooldirs); } } else { if( DEBUGL1 ) Dump_line_list("checkpc: all", &All_line_list ); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,All_line_list.list[i]); Scan_printer(&spooldirs); } } if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("main: END open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } Free_line_list(&raw); Free_line_list(&spooldirs); return(0); } void mkdir_path( char *path ) { struct stat statb; char *s; if( ! stat(path,&statb) ){ s = strrchr(path,'/'); if( s ){ *s = 0; mkdir_path(path); *s = '/'; if( mkdir( path, 0755 ) ){ FPRINTF(STDERR,"You cannot mkdir %s - something is wrong", path ); exit(1); } } else { FPRINTF(STDERR,"You cannot stat %s - something is wrong", path ); exit(1); } } } /*************************************************************************** * Scan_printer() * process the printer spool queue * 1. get the spool queue entry * 2. check to see if there is a spool dir * 3. perform checks for various files existence and permissions ***************************************************************************/ /* check for these names and values */ static const char *filter_names[] = { "filter", "bp", "bs", "be", 0 }; void Scan_printer(struct line_list *spooldirs) { DIR *dir; struct dirent *d; char *s, *cf_name; /* ACME pointers */ const char *cs, **names; int jobfile; struct stat statb; int fd = 0; /* device file descriptor */ int i, n, fifo_header_len; char error[SMALLBUFFER]; int errorlen = sizeof(error); struct job job; time_t delta; fifo_header_len = safestrlen( Fifo_lock_file_DYN ); Init_job(&job); error[0] = 0; if(Verbose)MESSAGE( "Checking printer '%s'", Printer_DYN ); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Scan_printer: START open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } /* get printer information */ error[0] = 0; Fix_Rm_Rp_info(error, sizeof(error) ); if( error[0] ){ WARNMSG( "%s: '%s'", Printer_DYN, error ); } if( !Is_server ){ if( !Lp_device_DYN && !RemoteHost_DYN && !Force_localhost_DYN ){ WARNMSG( "%s: no printer printer information", Printer_DYN); } if( RemoteHost_DYN && !RemotePrinter_DYN ){ WARNMSG( "%s: no remote printer information", Printer_DYN); } goto test_filters; } if( !Find_first_key(&PC_entry_line_list,"bq",Option_value_sep,&n) || !Find_first_key(&Config_line_list,"bq",Option_value_sep,&n ) ){ WARNMSG( "%s: bq option is no longer supported, use 'lpd_bounce' option", Printer_DYN); } if( !Find_first_key(&PC_entry_line_list,"check_idle",Option_value_sep,&n) || !Find_first_key(&Config_line_list,"check_idle",Option_value_sep,&n ) ){ WARNMSG( "%s: check_idle option is no longer supported, use 'chooser' option", Printer_DYN); } if( !Find_first_key(&PC_entry_line_list,"sf",Option_value_sep,&n) || !Find_first_key(&Config_line_list,"sf",Option_value_sep,&n ) ){ WARNMSG( "%s: sf (suppress form feeds) is deprecated. Use 'ff_separator' if you want FF between job files", Printer_DYN); } if( strchr(Printer_DYN, '*') ){ WARNMSG( "printcap entry '%s': Wildcard entry cannot be a server queue name, use :client to mark for client or use wildcard as alias", Printer_DYN); return; } Setup_printer( Printer_DYN, error, errorlen, 0); DEBUG3( "Scan_printer: Printer_DYN '%s', RemoteHost_DYN '%s', RemotePrinter_DYN '%s', Lp '%s'", Printer_DYN, RemoteHost_DYN, RemotePrinter_DYN, Lp_device_DYN ); /* check to see if printer defined in database */ if( Spool_dir_DYN == 0 ){ WARNMSG("%s: Bad printcap entry - missing 'sd' or 'client' entry?", Printer_DYN); return; } if( (s = Find_str_value(spooldirs,Spool_dir_DYN)) ){ WARNMSG("%s: CATASTROPHIC ERROR! queue '%s' also has spool directory '%s'", Printer_DYN, s, Spool_dir_DYN); return; } Set_str_value(spooldirs,Spool_dir_DYN,Printer_DYN); /* * check the permissions of files and directories * Also remove old job or control files */ if( Check_spool_dir( Spool_dir_DYN ) > 1 ){ WARNMSG( " Printer_DYN '%s' spool dir '%s' needs fixing", Printer_DYN, Spool_dir_DYN ); return; } if( !(dir = opendir( Spool_dir_DYN )) ){ WARNMSG( " Printer_DYN '%s' spool dir '%s' cannot be scanned '%s'", Printer_DYN, Spool_dir_DYN, Errormsg(errno) ); return; } if( (Fix || Remove) && Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } while( (d = readdir(dir)) ){ cf_name = d->d_name; if( safestrcmp( cf_name, "." ) == 0 || safestrcmp( cf_name, ".." ) == 0 ) continue; DEBUG2("Scan_printer: file '%s'", cf_name ); if( fifo_header_len && !safestrncmp( cf_name,Fifo_lock_file_DYN, fifo_header_len) ){ DEBUG2("Scan_printer: fifo file '%s'", cf_name ); unlink( cf_name ); continue; } if( stat(cf_name,&statb) == -1 ){ WARNMSG( " stat of file '%s' failed '%s'", cf_name, Errormsg(errno) ); continue; } /* do not touch symbolic links */ if( S_ISLNK( statb.st_mode ) ){ continue; } delta = Current_time - statb.st_mtime; /* * cfA000 -> cXXn * dfA000 -> cXXn * hfA000 -> cXXn */ jobfile = ( strchr( "cdh", cf_name[0] ) && isalpha(cval(cf_name+1)) && isalpha(cval(cf_name+2)) && isdigit(cval(cf_name+3)) ); if( jobfile && Age && delta > Age ){ float n = (delta)/60.0 ; float a = (Age)/60.0 ; const char *remove = Remove?" (removing)":""; const char *range = "mins"; if( a/60 > 2 ){ a = a/60; n = n/60; range = "hours"; if( a/24 > 2 ){ a = a/24; n = n/24; range = "days"; } } if( (statb.st_size == 0) ){ if( Remove || Verbose)MESSAGE( " %s: file '%s', zero length file > %3.2f %s old%s", Printer_DYN, cf_name, n, range, remove ); if( Remove ){ unlink(cf_name); } continue; } else { if( Remove || Verbose)MESSAGE( " %s: file '%s', age %3.2f %s > %3.2f %s maximum%s", Printer_DYN, cf_name, n, range, a, range, remove ); if( Remove ){ unlink(cf_name); } continue; } } /* we update all real files in this directory */ if( jobfile ){ Check_file( cf_name, Fix, 0, 0 ); } } closedir(dir); Make_write_file( Queue_control_file_DYN, 0 ); Make_write_file( Queue_status_file_DYN, 0 ); Fix_clean(Status_file_DYN,Nostatus); Fix_clean(Log_file_DYN,Nolog); Fix_clean(Accounting_file_DYN,Noaccount); if( (s = Ppd_file_DYN) ){ Check_read_file( s, Fix, 0644 ); } /* * get the jobs in the queue */ if( Fix ){ if( Lpq_status_file_DYN ) unlink(Lpq_status_file_DYN ); } Free_line_list( &Sort_order ); { int fdx = open("/dev/null",O_RDWR); DEBUG1("Scan_printer: Scan_queue before maxfd %d", fdx); close(fdx); } Scan_queue( &Spool_control, &Sort_order,0,0,0,0, 0, 0,0,0 ); { int fdx = open("/dev/null",O_RDWR); DEBUG1("Scan_printer: Scan_queue after maxfd %d", fdx); close(fdx); } /* * check to see if we have a local or remote printer * do not check if name has a | or % character in it */ /* we should have a local printer */ if( Server_queue_name_DYN == 0 && RemotePrinter_DYN == 0 && Lp_device_DYN == 0 ){ WARNMSG( "Missing 'lp' and 'rp' entry for local printer" ); } test_filters: if( Lp_device_DYN && safestrpbrk( Lp_device_DYN, "|%@" ) == 0 ){ s = Lp_device_DYN; fd = -1; if( s[0] != '/' ){ WARNMSG( "%s: lp device not absolute pathname '%s'", Printer_DYN, s ); } else if( stat(s,&statb) < 0 ){ WARNMSG( "%s: cannot stat lp device '%s' - %s", Printer_DYN, s, Errormsg(errno) ); } else if( (fd = Checkwrite(s,&statb,0,0,1)) < 0 ){ WARNMSG( "%s: cannot open lp device '%s' - %s", Printer_DYN, s, Errormsg(errno) ); } if( fd >= 0 ) close(fd); } /* check the filters */ strcpy(error,"xf"); for( i = 'a'; i <= 'z'; ++i ){ if( safestrchr("afls",i) ) continue; error[0] = i; Check_executable_filter( error, 0 ); } for( names = filter_names; (cs = *names); ++names ){ Check_executable_filter( cs, 0 ); } /* check the Lpd_port_DYN */ n = 0; if( (s = safestrchr( Lpd_port_DYN, '%')) ){ n = Link_dest_port_num(s+1); } else if( Lpd_port_DYN ){ n = Link_dest_port_num(Lpd_port_DYN); } if( n == 0 ){ WARNMSG( "%s: bad lpd_port value '%s'", Printer_DYN, Lpd_port_DYN ); } } void Check_executable_filter( const char *id, char *filter_str ) { struct line_list files; char *s, *t; struct stat statb; int c, j, n; Init_line_list(&files); if( !filter_str ){ filter_str = Find_str_value(&PC_entry_line_list,id); if(!filter_str) filter_str = Find_str_value(&Config_line_list,id); } Split(&files,filter_str,Whitespace,0,0,0,0,0,0); if( files.count ){ if(Verbose)MESSAGE(" '%s' filter '%s'", id, filter_str ); s = 0; for( j = 0; j < files.count; ++j ){ s = files.list[j]; while(s && (c =cval(s)) ){ if( isspace(c) ){ ++s; continue; }; if( c == '|' ){ ++s; continue; }; if( !safestrncasecmp(s,"$-",2) ){ s+=2; continue;} if( !safestrncasecmp(s,"-$",2) ){ s+=2; continue;} if( !safestrncasecmp(s,"root",4) ){ s+=4; continue;} break; } if( *s ) break; } c = cval(s); if( c == '(' || strpbrk( s, "<>|;") ){ if(Verbose)MESSAGE(" shell script '%s'", filter_str ); t = filter_str + safestrlen(filter_str) - 1; while( isspace(cval(t)) ) --t; if( cval(t) != ')' ){ WARNMSG("filter needs ')' at end - '%s'", filter_str ); } if( c == '(' ) ++s; while( isspace(cval(s)) ) ++s; c = cval(s); if( c != '/' ) goto exit; } if(Verbose)MESSAGE(" executable '%s'", s ); if( stat(s,&statb) ){ WARNMSG("cannot stat '%s' filter '%s' - %s", id, s, Errormsg(errno) ); } else if(!S_ISREG(statb.st_mode)) { WARNMSG("'%s' filter '%s' not a file", id, s); } else { n = statb.st_mode & 0111; if( !(n & 0001) && !((n & 0010) && statb.st_gid == DaemonGID ) && !((n & 0100) && statb.st_uid == DaemonUID ) ){ WARNMSG("'%s' filter '%s' does not have execute perms", id, s ); } } } exit: Free_line_list( &files ); } /*************************************************************************** * Make_write_file( * dir - directory name * name - file name * printer - if non-zero, append to end of file name ***************************************************************************/ void Make_write_file( char *file, char *printer ) { int fd; struct stat statb; char *s; if( file == 0 || *file == 0 ){ return; } s = safestrdup2(file,printer,__FILE__,__LINE__); DEBUG1("Make_write_file '%s'", s ); if( Verbose || DEBUGL1 ){ if(Verbose)MESSAGE( " checking '%s' file", s ); } if( (fd = Checkwrite( s, &statb, O_RDWR, 1, 1 )) < 0 ){ WARNMSG( " ** cannot open '%s' - '%s'", s, Errormsg(errno) ); if( Fix ){ int euid = geteuid(); To_euid_root(); fd = open( s, O_RDWR|O_CREAT, Spool_file_perms_DYN ); To_euid(euid); if( fd < 0 ){ WARNMSG( " ** cannot create '%s' - '%s'", s, Errormsg(errno) ); } Fix_owner( s ); } } if( Check_file( s, Fix, 0, 0 ) ){ WARNMSG(" ** ownership or permissions problem with '%s'", s ); } if( s ) free(s); s = 0; if( fd >= 0 ) close(fd); fd = -1; } static void usage(void) { FPRINTF( STDERR, "checkpc [-aflprsV] [-A age] [-D debuglevel] [-P printer] [-t size]\n" " Check printcap for printer information and fix files where possible\n" " Option:\n" " -a do not create accounting info (:af) file\n" " -f fix missing files and inconsistent file permissions\n" " -l do not create logging info (:lf) file\n" " -p verbose printcap information\n" " -r remove job files older than -A age seconds\n" " -s do not create filter status (:ps) info file\n" " -t size[kM] truncate log files (:lf) to size (k=Kbyte, M=Mbytes)\n" " -A age[DHMS] remove files of form ?f[A-Z][0-9][0-9][0-9] older than\n" " age, D days (default), H hours, M minutes, S seconds\n" " -D debuglevel set debug level\n" " -P printer check or fix only this printer entry\n" " -V really verbose information\n" " -T line portability diagnostic, use serial line device for stty test\n"); Parse_debug("=",-1); FPRINTF( STDOUT, "%s\n", Version ); exit(1); } int getage( char *age ) { int t; char *end = age; t = strtol( age, &end, 10 ); if( t && end != age ){ switch( *end ){ default: t = 0; break; case 0: case 'd': case 'D': t *= 24; case 'h': case 'H': t *= 60; case 'm': case 'M': t *= 60; case 's': case 'S': break; } } if( t == 0 ){ FPRINTF( STDERR, "Bad format for age '%s'", age ); usage(); } return t; } int getk( char *age ) { int t; char *end = age; t = strtol( age, &end, 10 ); if( end != age ){ switch( *end ){ default: FPRINTF( STDERR, "Bad format for number '%s'", age ); usage(); case 0: break; case 'k': case 'K': break; case 'm': case 'M': t *= (1024); break; } } return t; } /*************************************************************************** * Check_file( char *dpath - pathname of directory/files * int fix - fix or check * int t - time to compare against * int age - maximum age of file ***************************************************************************/ int Check_file( char *path, int fix, int age, int rmflag ) { struct stat statb; int old; int err = 0; DEBUG4("Check_file: '%s', fix %d, time 0x%lx, age %d", path, fix, (long)Current_time, age ); if( stat( path, &statb ) ){ WARNMSG( " %s: cannot stat file '%s', %s", Printer_DYN?Printer_DYN:"", path, Errormsg(errno) ); err = 1; return( err ); } if( S_ISDIR( statb.st_mode ) ){ WARNMSG(" %s: '%s' is a directory, not a file", Printer_DYN?Printer_DYN:"",path ); return(2); } else if( !S_ISREG( statb.st_mode ) ){ WARNMSG( " %s: '%s' not a regular file - unusual", Printer_DYN?Printer_DYN:"",path ); return(2) ; } if( statb.st_uid != DaemonUID || statb.st_gid != DaemonGID ){ WARNMSG( "owner/group of '%s' are %ld/%ld, not %ld/%ld", path, (long)(statb.st_uid), (long)(statb.st_gid), (long)DaemonUID, (long)DaemonGID ); if( fix ){ if( Fix_owner( path ) ) err = 2; } } if( 07777 & (statb.st_mode ^ Spool_file_perms_DYN) ){ WARNMSG( "permissions of '%s' are 0%o, not 0%o", path, (unsigned int)(statb.st_mode & 07777), Spool_file_perms_DYN ); if( fix ){ if( Fix_perms( path, Spool_file_perms_DYN ) ) err = 1; } } if( age ){ old = Current_time - statb.st_ctime; if( old >= age ){ FPRINTF( STDOUT, "file %s age is %d secs, max allowed %d secs\n", path, old, age ); if( rmflag ){ FPRINTF( STDOUT, "removing '%s'\n", path ); if( unlink( path ) == -1 ){ WARNMSG( "cannot remove '%s', %s", path, Errormsg(errno) ); } } } } return( err ); } /*************************************************************************** * Check_read_file( char *dpath - pathname of directory/files * int fix - fix or check ***************************************************************************/ int Check_read_file( char *path, int fix, int perms ) { struct stat statb; int err = 0; int fd; DEBUG4("Check_read_file: '%s', fix %d", path, fix ); if( stat( path, &statb ) ){ WARNMSG( " %s: cannot stat file '%s', %s", Printer_DYN?Printer_DYN:"", path, Errormsg(errno) ); err = 1; return( err ); } if( S_ISDIR( statb.st_mode ) ){ WARNMSG(" %s: '%s' is a directory, not a file", Printer_DYN?Printer_DYN:"",path ); return(2); } else if( !S_ISREG( statb.st_mode ) ){ WARNMSG( " %s: '%s' not a regular file - unusual", Printer_DYN?Printer_DYN:"",path ); return(2) ; } if( (fd = Checkread( path, &statb )) < 0 ){ if( fix ){ Fix_perms( path, perms ); } else { WARNMSG( " %s: cannot open %s - %s", Printer_DYN?Printer_DYN:"", path, Errormsg(errno) ); } } if( fd >= 0 ) close(fd); return( err ); } int Fix_create_dir( char *path, struct stat *statb ) { char *s; int err = 0; s = path+safestrlen(path)-1; if( *s == '/' ) *s = 0; if( stat( path, statb ) == 0 ){ if( !S_ISDIR( statb->st_mode ) ){ if( !S_ISREG( statb->st_mode ) ){ WARNMSG( "not regular file '%s'", path ); err = 1; } else if( unlink( s ) ){ WARNMSG( "cannot unlink file '%s', %s", path, Errormsg(errno) ); err = 1; } } } /* we don't have a directory */ if( stat( path, statb ) ){ int euid = geteuid(); To_euid_root(); if( mkdir( path, Spool_dir_perms_DYN ) ){ WARNMSG( "mkdir '%s' failed, %s", path, Errormsg(errno) ); err = 1; } else { err = Fix_owner( path ); } To_euid(euid); } return( err ); } int Fix_owner( char *path ) { int status = 0; int err; int euid = geteuid(); To_euid_root(); WARNMSG( " changing ownership '%s' to %ld/%ld", path, (long)DaemonUID, (long)DaemonGID ); chown( path, DaemonUID, DaemonGID ); if( geteuid() == ROOTUID ){ WARNMSG( " changing ownership '%s' to %ld/%ld", path, (long)DaemonUID, (long)DaemonGID ); status = chown( path, DaemonUID, DaemonGID ); err = errno; if( status ){ WARNMSG( "chown '%s' failed, %s", path, Errormsg(err) ); } errno = err; } To_euid(euid); return( status != 0 ); } int Fix_perms( char *path, int perms ) { int status; int err; int euid = geteuid(); To_euid_root(); status = chmod( path, perms ); err = errno; To_euid( euid ); if( status ){ WARNMSG( "chmod '%s' to 0%o failed, %s", path, perms, Errormsg(err) ); } errno = err; return( status != 0 ); } /*************************************************************************** * Check to see that the spool directory exists, and create it if necessary ***************************************************************************/ int Check_spool_dir( char *path ) { struct stat statb; struct line_list parts; char *pathname = 0; int err = 0, i; /* get the required group and user ids */ if(Verbose)MESSAGE(" Checking directory: '%s'", path ); pathname = path+safestrlen(path)-1; if( pathname[0] == '/' ) *pathname = 0; Init_line_list(&parts); if( path == 0 || path[0] != '/' || strstr(path,"/../") ){ WARNMSG("bad spooldir path '%s'", path ); return(2); } pathname = 0; Split(&parts,path,"/",0,0,0,0,0,0); for( i = 0; i < parts.count; ++i ){ pathname = safeextend3(pathname,"/",parts.list[i],__FILE__,__LINE__); if(Verbose)MESSAGE(" directory '%s'", pathname); if( stat( pathname, &statb ) || !S_ISDIR( statb.st_mode ) ){ if( Fix ){ if( Fix_create_dir( pathname, &statb ) ){ return(2); } } else { WARNMSG(" bad directory - %s", pathname ); return( 2 ); } } if( stat( pathname, &statb ) == 0 && S_ISDIR( statb.st_mode ) && chdir( pathname ) == -1 ){ if( !Fix ){ WARNMSG( "cannot chdir to '%s' as UID %ld, GRP %ld - '%s'", pathname, (long)geteuid(), (long)getegid(), Errormsg(errno) ); } else { Fix_perms( pathname, Spool_dir_perms_DYN ); if( chdir( pathname ) == -1 ){ WARNMSG( "Permission change FAILED: cannot chdir to '%s' as UID %ld, GRP %ld - '%s'", pathname, (long)geteuid(), (long)getegid(), Errormsg(errno) ); Fix_owner( pathname ); Fix_perms( pathname, Spool_dir_perms_DYN ); } if( chdir( pathname ) == -1 ){ WARNMSG( "Owner and Permission change FAILED: cannot chdir to '%s' as UID %ld, GRP %ld - '%s'", pathname, (long)geteuid(), (long)getegid(), Errormsg(errno) ); } } } } if(pathname) free(pathname); pathname = 0; Free_line_list(&parts); /* now we do chown if necessary */ if( Fix ){ char cmd[SMALLBUFFER]; int euid = geteuid(); To_euid_root(); plp_snprintf( cmd, sizeof(cmd), "%s -R %ld %s", CHOWN, (long)DaemonUID, path ); system( cmd ); plp_snprintf( cmd, sizeof(cmd), "%s -R %ld %s", CHGRP, (long)DaemonGID, path ); system( cmd ); To_euid(euid); } if( stat( path, &statb ) ){ WARNMSG( "stat of '%s' failed - %s", path, Errormsg(errno) ); err = 1; return( err ); } /* now we look at the last directory */ if( statb.st_uid != DaemonUID || statb.st_gid != DaemonGID ){ WARNMSG( "owner/group of '%s' are %ld/%ld, not %ld/%ld", path, (long)(statb.st_uid), (long)(statb.st_gid), (long)DaemonUID, (long)DaemonGID ); err = 1; if( Fix ){ if( Fix_owner( path ) ) err = 2; } } if( 07777 & (statb.st_mode ^ Spool_dir_perms_DYN) ){ WARNMSG( "permissions of '%s' are 0%o, not 0%o", path, (unsigned int)(statb.st_mode & 07777), Spool_dir_perms_DYN ); err = 1; if( Fix ){ if( Fix_perms( path, Spool_dir_perms_DYN ) ) err = 1; } } return(err); } /*************************************************************************** * We have put a slew of portatbility tests in here. * 1. setuid * 2. RW/pipes, and as a side effect, waitpid() * 3. get file system size (/tmp) * 4. try nonblocking open * 5. try locking test * 6. getpid() test * 7. try serial line locking * 8. try file locking ***************************************************************************/ void Test_port(int ruid, int euid, char *serial_line ) { FILE *tf; char line[LINEBUFFER]; char cmd[LINEBUFFER]; char t1[LINEBUFFER]; char t2[LINEBUFFER]; char stty[LINEBUFFER]; char diff[LINEBUFFER]; const char *sttycmd; const char *diffcmd; int ttyfd; static pid_t pid, result; plp_status_t status; double freespace; static int fd; static int i, err; struct stat statb; /*char *Stty_command;*/ status = 0; fd = -1; /* * SETUID * - try to go to user and then back */ Spool_file_perms_DYN = 000600; Spool_dir_perms_DYN = 042700; if( ( ruid == ROOTUID && euid == ROOTUID ) || (ruid != ROOTUID && euid != ROOTUID ) ){ FPRINTF( STDERR, "*******************************************************\n" ); FPRINTF( STDERR, "***** not SETUID, skipping setuid checks\n" ); FPRINTF( STDERR, "*******************************************************\n" ); goto freespace; } else if( ( ruid == ROOTUID || euid == ROOTUID ) ){ if( UID_root == 0 ){ FPRINTF( STDERR, "checkpc: setuid code failed!! Portability problems\n" ); exit(1); } if( To_euid(1) ){ FPRINTF( STDERR, "checkpc: To_euid() seteuid code failed!! Portability problems\n" ); exit(1); } if( To_daemon() ){ FPRINTF( STDERR, "checkpc: To_usr() seteuid code failed!! Portability problems\n" ); exit(1); } FPRINTF( STDERR, "***** SETUID code works\n" ); } freespace: freespace = Space_avail( "/tmp" ); FPRINTF( STDERR, "***** Free space '/tmp' = %0.0f Kbytes \n" " (check using df command)\n", (double)freespace ); /* * check serial line */ if( serial_line == 0 ){ FPRINTF( STDERR, "*******************************************************\n" ); FPRINTF( STDERR, "********** Missing serial line\n" ); FPRINTF( STDERR, "*******************************************************\n" ); goto test_lockfd; } else { FPRINTF( STDERR, "Trying to open '%s'\n", serial_line ); fd = Checkwrite_timeout( 2, serial_line, &statb, O_RDWR, 0, 1 ); err = errno; if( Alarm_timed_out ){ FPRINTF( STDERR, "ERROR: open of '%s'timed out\n" " Check to see that the attached device is online\n", serial_line ); goto test_stty; } else if( fd < 0 ){ FPRINTF( STDERR, "Error opening line '%s'\n", Errormsg(err)); goto test_stty; } else if( !isatty( fd ) ){ FPRINTF( STDERR, "*******************************************************\n" ); FPRINTF( STDERR, "***** '%s' is not a serial line!\n", serial_line ); FPRINTF( STDERR, "*******************************************************\n" ); goto test_stty; } else { FPRINTF( STDERR, "\nTrying read with timeout\n" ); i = Read_fd_len_timeout( 1, fd, cmd, sizeof(cmd) ); err = errno; if( Alarm_timed_out ){ FPRINTF( STDERR, "***** Read with Timeout successful\n" ); } else { if( i < 0 ){ FPRINTF( STDERR, "***** Read with Timeout FAILED!! Error '%s'\n", Errormsg( err ) ); } else { FPRINTF( STDERR, "***** Read with Timeout FAILED!! read() returned %d\n", i ); FPRINTF( STDERR, "***** On BSD derived systems CARRIER DETECT (CD) = OFF indicates EOF condition.\n" ); FPRINTF( STDERR, "***** Check that CD = ON and repeat test with idle input port.\n" ); FPRINTF( STDERR, "***** If the test STILL fails, then you have problems.\n" ); } } } /* * now we try locking the serial line */ /* we try to lock the serial line */ FPRINTF( STDERR, "\nChecking for serial line locking\n" ); #if defined(LOCK_DEVS) && LOCK_DEVS == 0 FPRINTF( STDERR, "*******************************************************\n" ); FPRINTF( STDERR, "******** Device Locking Disabled by compile time options" ); FPRINTF( STDERR, "\n" ); FPRINTF( STDERR, "*******************************************************\n" ); goto test_stty; #endif i = 0; if( Set_timeout() ){ Set_timeout_alarm( 1 ); i = LockDevice( fd, 0 ); } Clear_timeout(); err = errno; if( Alarm_timed_out || i < 0 ){ if( Alarm_timed_out ){ FPRINTF( STDERR, "LockDevice timed out - %s", Errormsg(err) ); } FPRINTF( STDERR, "*******************************************************\n" ); FPRINTF( STDERR, "********* LockDevice failed - %s\n", Errormsg(err) ); FPRINTF( STDERR, "********* Try an alternate lock routine\n" ); FPRINTF( STDERR, "*******************************************************\n" ); goto test_stty; } FPRINTF( STDERR, "***** LockDevice with no contention successful\n" ); /* * now we fork a child with tries to reopen the file and lock it */ if( (pid = fork()) < 0 ){ FPRINTF( STDERR, "fork failed - %s", Errormsg(errno) ); } else if( pid == 0 ){ close(fd); fd = -1; i = -1; FPRINTF( STDERR, "Daughter re-opening line '%s'\n", serial_line ); if( Set_timeout() ){ Set_timeout_alarm( 1 ); fd = Checkwrite( serial_line, &statb, O_RDWR, 0, 0 ); if( fd >= 0 ) i = LockDevice( fd, 1 ); } Clear_timeout(); err = errno; FPRINTF( STDERR, "Daughter open completed- fd '%d', lock %d\n", fd, i ); if( Alarm_timed_out ){ FPRINTF( STDERR, "Timeout opening line '%s'\n", serial_line ); } else if( fd < 0 ){ FPRINTF( STDERR, "Error opening line '%s' - %s\n", serial_line, Errormsg(err)); } else if( i > 0 ){ FPRINTF( STDERR, "Lock '%s' succeeded! wrong result\n", serial_line); } else { FPRINTF( STDERR, "**** Lock '%s' failed, desired result\n", serial_line); } if( fd >= 0 ){ FPRINTF( STDERR,"Daughter closing '%d'\n", fd ); close( fd ); } FPRINTF( STDERR,"Daughter exit with '%d'\n", (i >= 0) ); exit(i >= 0); } else { status = 0; FPRINTF( STDERR, "Mother starting sleep\n" ); plp_usleep(2000); FPRINTF( STDERR, "Mother sleep done\n" ); while(1){ result = plp_waitpid( -1, &status, 0 ); err = errno; FPRINTF( STDERR, "waitpid result %d, status %d, errno '%s'\n", (int)result, status, Errormsg(err) ); if( result == pid ){ FPRINTF( STDERR, "Daughter exit status %d\n", status ); if( status != 0 ){ FPRINTF( STDERR, "LockDevice failed\n"); } break; } else if( (result == -1 && errno == ECHILD) || result == 0 ){ break; } else if( result == -1 && errno != EINTR ){ FPRINTF( STDERR, "plp_waitpid() failed! This should not happen!"); status = -1; break; } } if( status == 0 ){ FPRINTF( STDERR, "***** LockDevice() works\n" ); } } test_stty: /* * do an STTY operation, then print the status. * we cheat and use a shell script; check the output */ if( fd <= 0 ) goto test_lockfd; FPRINTF( STDERR, "\n\n" ); FPRINTF( STDERR, "Checking stty functions, fd %d\n\n", fd ); if( (pid = fork()) < 0 ){ FPRINTF( STDERR, "fork failed - %s", Errormsg(errno) ); } else if( pid == 0 ){ /* default for status */ plp_snprintf( t1, sizeof(t1), "/tmp/t1XXX%ld", (long)getpid() ); plp_snprintf( t2, sizeof(t2), "/tmp/t2XXX%ld", (long)getpid() ); diffcmd = "diff -c %s %s 1>&2"; ttyfd = 1; /*STDOUT is reported */ sttycmd = "stty -a 2>%s"; /* on STDERR */ #if defined(SUNOS4_1_4) ttyfd = 1; /*STDOUT is reported */ sttycmd = "/bin/stty -a 2>%s"; /* on STDERR */ #elif defined(SOLARIS) || defined(SVR4) || defined(linux) ttyfd = 0; /* STDIN is reported */ sttycmd = "/bin/stty -a >%s"; /* on STDOUT */ #elif (defined(BSD) && (BSD >= 199103)) /* HMS: Might have to be 199306 */ ttyfd = 0; /* STDIN is reported */ sttycmd = "stty -a >%s"; /* on STDOUT */ #elif defined(BSD) /* old style BSD4.[23] */ sttycmd = "stty everything 2>%s"; #else /* That is: All other System V derivatives and AIX as well */ ttyfd = 0; /* STDIN is reported */ sttycmd = "/bin/stty -a >%s"; /* on STDOUT */ #endif if( fd != ttyfd ){ i = dup2(fd, ttyfd ); if( i != ttyfd ){ FPRINTF( STDERR, "dup2() failed - %s\n", Errormsg(errno) ); exit(-1); } close( fd ); } plp_snprintf( stty, sizeof(stty), sttycmd, t1 ); plp_snprintf( diff, sizeof(diff), diffcmd, t1, t2 ); plp_snprintf( cmd, sizeof(cmd), "%s; cat %s 1>&2", stty, t1 ); FPRINTF( STDERR, "Status before stty, using '%s', on fd %d->%d\n", cmd, fd, ttyfd ); i = system( cmd ); FPRINTF( STDERR, "\n\n" ); Stty_command_DYN = "9600 -even odd echo"; FPRINTF( STDERR, "Trying 'stty %s'\n", Stty_command_DYN ); Do_stty( ttyfd ); plp_snprintf( stty, sizeof(stty), sttycmd, t2 ); plp_snprintf( cmd, sizeof(cmd), "%s; %s", stty, diff ); FPRINTF( STDERR, "Doing '%s'\n", cmd ); i = system( cmd ); FPRINTF( STDERR, "\n\n" ); Stty_command_DYN = "1200 -odd even"; FPRINTF( STDERR, "Trying 'stty %s'\n", Stty_command_DYN ); Do_stty( ttyfd ); FPRINTF( STDERR, "Doing '%s'\n", cmd ); i = system( cmd ); FPRINTF( STDERR, "\n\n" ); Stty_command_DYN = "300 -even -odd -echo cbreak"; FPRINTF( STDERR, "Trying 'stty %s'\n", Stty_command_DYN ); Do_stty( ttyfd ); plp_snprintf( stty, sizeof(stty), sttycmd, serial_line, t2 ); FPRINTF( STDERR, "Doing '%s'\n", cmd ); i = system( cmd ); FPRINTF( STDERR, "\n\n" ); FPRINTF( STDERR, "Check the above for parity, speed and echo\n" ); FPRINTF( STDERR, "\n\n" ); unlink(t1); unlink(t2); exit(0); } else { close(fd); fd = -1; status = 0; while(1){ result = plp_waitpid( -1, &status, 0 ); if( result == pid ){ FPRINTF( STDERR, "Daughter exit status %d\n", status ); if( status != 0 ){ FPRINTF( STDERR, "STTY operation failed\n"); } break; } else if( (result == -1 && errno == ECHILD) || result == 0 ){ break; } else if( result == -1 && errno == EINTR ){ FPRINTF( STDERR, "plp_waitpid() failed! This should not happen!"); status = -1; break; } } if( status == 0 ){ FPRINTF( STDERR, "***** STTY works\n" ); } } } test_lockfd: if( fd >= 0 ) close(fd); fd = -1; FPRINTF( STDERR, "\n\n" ); /* * check out Lockf */ plp_snprintf( line, sizeof(line), "/tmp/XX%ldXX", (long)getpid() ); FPRINTF( STDERR, "Checking Lockf '%s'\n", line ); if( (fd = Checkwrite(line, &statb, O_RDWR, 1, 0 )) < 0) { err = errno; FPRINTF( STDERR, "open '%s' failed: wrong result - '%s'\n", line, Errormsg(errno) ); exit(1); } if( Do_lock( fd, 0 ) < 0 ) { FPRINTF( STDERR, "Mother could not lock '%s', in correct result\n", line ); exit(0); } plp_snprintf( cmd, sizeof(cmd), "ls -l %s", line ); i = system( cmd ); if( (pid = fork()) < 0 ){ FPRINTF( STDERR, "fork failed!\n"); } else if ( pid == 0 ){ FPRINTF( STDERR, "Daughter re-opening and locking '%s'\n", line ); close( fd ); if( (fd = Checkwrite(line, &statb, O_RDWR, 1, 0 )) < 0) { err = errno; FPRINTF( STDERR, "Daughter re-open '%s' failed: wrong result - '%s'\n", line, Errormsg(errno) ); exit(1); } if( Do_lock( fd, 0 ) < 0 ) { FPRINTF( STDERR, "Daughter could not lock '%s', correct result\n", line ); exit(0); } FPRINTF( STDERR, "Daughter locked '%s', incorrect result\n", line ); exit(1); } plp_usleep(1000); status = 0; while(1){ result = plp_waitpid( -1, &status, 0 ); if( result == pid ){ FPRINTF( STDERR, "Daughter exit status %d\n", status ); break; } else if( (result == -1 && errno == ECHILD) || result == 0 ){ break; } else if( result == -1 && errno != EINTR ){ FPRINTF( STDERR, "plp_waitpid() failed! This should not happen!"); status = -1; break; } } if( status == 0 ){ FPRINTF( STDERR, "***** Lockf() works\n" ); } if( (pid = fork()) < 0 ){ FPRINTF( STDERR, "fork failed!\n"); } else if ( pid == 0 ){ int lock = 0; FPRINTF( STDERR, "Daughter re-opening '%s'\n", line ); close( fd ); if( (fd = Checkwrite(line, &statb, O_RDWR, 1, 0 )) < 0) { err = errno; FPRINTF( STDERR, "Daughter re-open '%s' failed: wrong result - '%s'\n", line, Errormsg(errno) ); exit(1); } FPRINTF( STDERR, "Daughter blocking for lock\n" ); lock = Do_lock( fd, 1 ); if( lock < 0 ){ FPRINTF( STDERR, "Daughter lock '%s' failed! wrong result\n", line ); exit( 1 ); } FPRINTF( STDERR, "Daughter lock '%s' succeeded, correct result\n", line ); exit(0); } FPRINTF( STDERR, "Mother pausing before releasing lock on fd %d\n", fd ); plp_sleep(3); FPRINTF( STDERR, "Mother closing '%s', releasing lock on fd %d\n", line, fd ); close( fd ); fd = -1; status = 0; while(1){ result = plp_waitpid( -1, &status, 0 ); if( result == pid ){ FPRINTF( STDERR, "Daughter exit status %d\n", status ); break; } else if( (result == -1 && errno == ECHILD) || result == 0 ){ break; } else if( result == -1 && errno != EINTR ){ FPRINTF( STDERR, "plp_waitpid() failed! This should not happen!"); status = -1; break; } } if( status == 0 ){ FPRINTF( STDOUT, "***** Lockf() with unlocking works\n" ); } if( fd >= 0 ) close(fd); fd = - 1; unlink( line ); /*************************************************************************** * check out the process title ***************************************************************************/ FPRINTF( STDOUT, "checking if setting process info to 'lpd XXYYZZ' works\n" ); setproctitle( "lpd %s", "XXYYZZ" ); /* try simple test first */ i = 0; if( (tf = popen( "ps | grep XXYYZZ | grep -v grep", "r" )) ){ Max_open( fileno(tf) ); while( fgets( line, sizeof(line), tf ) ){ FPRINTF( STDOUT, line ); ++i; } fclose(tf); } if( i == 0 && (tf = popen( "ps | grep XXYYZZ | grep -v grep", "r" )) ){ Max_open( fileno(tf) ); while( fgets( line, sizeof(line), tf ) ){ FPRINTF( STDOUT, line ); ++i; } fclose(tf); } if( i ){ FPRINTF( STDOUT, "***** setproctitle works\n" ); } else { FPRINTF( STDOUT, "***** setproctitle debugging aid unavailable (not a problem)\n" ); } exit(0); } void Fix_clean( char *s, int no ) { struct stat statb; int fd; if( s ){ if(!no){ Make_write_file( s, 0 ); if( Truncate >= 0 ){ MESSAGE(" trimming '%s'", s ); fd = Trim_status_file( -1, s, Truncate, Truncate ); close(fd); } } else { if( stat(s,&statb) == 0 && Fix ){ MESSAGE(" removing '%s'", s ); unlink(s); } } } } int Check_path_list( char *plist, int allow_missing ) { struct line_list values; char *path; int found_pc = 0, i, fd; struct stat statb; Init_line_list(&values); Split(&values,plist,File_sep,0,0,0,0,0,0); for( i = 0; i < values.count; ++i ){ path = values.list[i]; if( path[0] == '|' ){ ++path; Check_executable_filter( path, 0 ); } else if( path[0] == '/' ){ if( (fd = Checkread( path,&statb ) ) < 0 ){ if( stat( path, &statb ) ){ if( ! allow_missing ) WARNMSG(" '%s' not present", path ); } else { WARNMSG(" '%s' cannot be opened - check path permissions", path ); } } else { close(fd); if(Verbose)MESSAGE(" found '%s', mod 0%o", path, (unsigned int)statb.st_mode ); ++found_pc; if( (statb.st_mode & 0444) != 0444 ){ WARNMSG(" '%s' is not world readable", path ); WARNMSG(" this file should have (suggested) 644 permissions, owned by root" ); } } } else { WARNMSG("not absolute pathname '%s' in '%s'", path, plist ); } } Free_line_list(&values); return(found_pc); } lprng-3.8.B/src/common/lpd_remove.c0000644000131400013140000003461511531672132014170 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "lpd_remove.h" #include "getqueue.h" #include "getprinter.h" #include "gethostinfo.h" #include "getopt.h" #include "permission.h" #include "child.h" #include "proctitle.h" #include "fileopen.h" #include "sendreq.h" /**** ENDINCLUDE ****/ static void Get_queue_remove( char *user, int *sock, struct line_list *tokens, struct line_list *done_list ); static void Get_local_or_remote_remove( char *user, int *sock, struct line_list *tokens, struct line_list *done_list ); /*************************************************************************** * Commentary: * Patrick Powell Tue May 2 09:32:50 PDT 1995 * * Remove a Job. * This is very similar to the status program. * * 1. We check for permissions first * - first we check to see if the remote host has permissions * - next we check to see if the user has permissions * Note: * if we have control permissions, then we can remove any job. * Normally, the options passed are 'user jobnumber' and we * use the user name and/or job number to select them. When we have * control permissions, we are not restricted to our own jobs. * so: if we have control permissions, AND pass an option, we * do not check for our name. * if we have control permissions AND we do not pass an option, * we check for our name. * * we have \006printer user key key key * 0 1 2 ... index ***************************************************************************/ int Job_remove( int *sock, char *input ) { char error[LINEBUFFER]; int i; char *name, *s, *user = 0; struct line_list tokens, done_list; Init_line_list(&tokens); Init_line_list(&done_list); Name = "Job_remove"; /* get the options */ ++input; DEBUGF(DLPRM1)("Job_remove: input '%s'", input ); Split(&tokens,input,Whitespace,0,0,0,0,0,0); DEBUGFC(DLPRM2)Dump_line_list("Job_remove: input", &tokens ); /* check printername for characters, underscore, digits */ if( tokens.count < 2 ){ plp_snprintf( error, sizeof(error), _("missing user or printer name")); goto error; } name = tokens.list[0]; DEBUGF(DLPRM1)("Job_remove: checking '%s'", name ); if( (s = Is_clean_name( name )) ){ plp_snprintf( error, sizeof(error), _("printer '%s' has illegal character at '%s' in name"), name, s ); goto error; } DEBUGF(DLPRM1)("Job_remove: result '%s'", name ); Set_DYN(&Printer_DYN,name); user = safestrdup(tokens.list[1],__FILE__,__LINE__); Perm_check.remoteuser = user; /* remove the first two tokens */ Remove_line_list(&tokens,1); Remove_line_list(&tokens,0); Check_max(&tokens,1); tokens.list[tokens.count] = 0; if( safestrcmp( Printer_DYN, ALL ) ){ DEBUGF(DLPRM2)( "Job_remove: checking printcap entry '%s'", Printer_DYN ); Set_DYN(&Printer_DYN, Printer_DYN ); Get_queue_remove( user, sock, &tokens, &done_list ); } else { Get_all_printcap_entries(); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN, All_line_list.list[i]); Get_queue_remove( user, sock, &tokens, &done_list ); } } goto done; error: logmsg( LOG_INFO, _("Job_remove: error '%s'"), error ); DEBUGF(DLPRM2)("Job_remove: error msg '%s'", error ); safestrncat(error,"\n"); if( Write_fd_str( *sock, error ) < 0 ) cleanup(0); done: DEBUGF(DLPRM2)( "Job_remove: done" ); if( user ) free(user); user = 0; Free_line_list(&done_list); Free_line_list(&tokens); return( 0 ); } /*************************************************************************** * void Get_queue_remove * - find and remove the spool queue entries ***************************************************************************/ static void Get_queue_remove( char *user, int *sock, struct line_list *tokens, struct line_list *done_list ) { char msg[SMALLBUFFER], header[SMALLBUFFER]; int control_perm, permission, count, removed, status, i, c = 0, pid; char *s, *identifier; struct line_list info, active_pid; struct job job; int fd = -1; Init_line_list(&info); Init_line_list(&active_pid); Init_job(&job); /* set printer name and printcap variables */ DEBUGFC(DLPRM2)Dump_line_list("Get_queue_remove - tokens", tokens ); DEBUGF(DLPRM2)( "Get_queue_remove: user '%s', printer '%s'", user, Printer_DYN ); Errorcode = 0; setproctitle( "lpd LPRM '%s'", Printer_DYN ); /* first check to see if you have control permissions */ msg[0] = 0; status = Setup_printer( Printer_DYN, msg, sizeof(msg), 0 ); if( status ){ if( msg[0] == 0 ){ DEBUGF(DLPRM2)("Get_queue_remove: cannot set up printer '%s'", Printer_DYN); } goto error; } c = Debug; i = DbgFlag; s = Find_str_value(&Spool_control,DEBUG); if( !s ) s = New_debug_DYN; Parse_debug( s, 0 ); if( !(DbgFlag & DLPRMMASK) ){ Debug = c; DbgFlag = i; } else { i = Debug; Debug = c; if( Log_file_DYN ){ fd = Trim_status_file( -1, Log_file_DYN, Max_log_file_size_DYN, Min_log_file_size_DYN ); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); } } Debug = i; } /* set up status */ if( Find_exists_value(done_list,Printer_DYN,Hash_value_sep ) ){ return; } Add_line_list(done_list,Printer_DYN,Hash_value_sep,1,1); /* check for permissions */ Perm_check.service = 'C'; Perm_check.printer = Printer_DYN; Perm_check.host = 0; Perm_check.user = 0; control_perm = Perms_check( &Perm_line_list, &Perm_check, 0, 0 ); DEBUGF(DLPRM2)("Job_remove: permission '%s'", perm_str(control_perm)); if( control_perm != P_ACCEPT ) control_perm = 0; plp_snprintf( msg, sizeof(msg), _("Printer %s@%s:\n"), Printer_DYN, ShortHost_FQDN ); Write_fd_str( *sock, msg ); Free_line_list( &Sort_order ); Scan_queue( &Spool_control, &Sort_order,0,0,0,0,0,0,0,0 ); DEBUGF(DLPRM2)("Get_queue_remove: total files %d", Sort_order.count ); /* scan the files to see if there is one which matches */ removed = 0; DEBUGFC(DLPRM3)Dump_line_list("Get_queue_remove - tokens", tokens ); fd = -1; for( count = 0; count < Sort_order.count; ++count ){ int incoming; Free_job(&job); if( fd > 0 ) close(fd); fd = -1; Get_job_ticket_file(&fd, &job, Sort_order.list[count] ); DEBUGFC(DLPRM3)Dump_job("Get_queue_remove - info",&job); if( tokens->count && Patselect( tokens, &job.info, 0) ){ continue; } /* get everything for the job now */ identifier = Find_str_value(&job.info,IDENTIFIER); if( !identifier ) identifier = Find_str_value(&job.info,XXCFTRANSFERNAME); DEBUGF(DLPRM3)("Get_queue_remove: matched '%s'", identifier ); plp_snprintf( msg, sizeof(msg), _(" checking perms '%s'\n"), identifier ); Write_fd_str( *sock, msg ); /* we check to see if we can remove this one if we are the user */ if( control_perm == 0 ){ /* now we get the user name and IP address */ Perm_check.user = Find_str_value(&job.info,LOGNAME); Perm_check.host = 0; if( (s = Find_str_value(&job.info,FROMHOST)) && Find_fqdn( &PermHost_IP, s ) ){ Perm_check.host = &PermHost_IP; } Perm_check.service = 'M'; permission = Perms_check( &Perm_line_list, &Perm_check, &job, 1 ); if( permission == P_REJECT ){ plp_snprintf( msg, sizeof(msg), _(" no permissions '%s'\n"), identifier ); Write_fd_str( *sock, msg ); continue; } } /* * we now check for the incoming jobs */ incoming = Find_flag_value(&job.info,INCOMING_TIME); pid = Find_flag_value(&job.info,INCOMING_PID); if( incoming && pid && !kill(pid,SIGINT) ){ DEBUGF(DLPRM4)("Get_queue_remove: removing incoming job '%s'", identifier ); plp_snprintf( msg, sizeof(msg), _(" removing incoming job '%s'\n"), identifier ); } else { DEBUGF(DLPRM4)("Get_queue_remove: removing '%s'", identifier ); plp_snprintf( msg, sizeof(msg), _(" dequeued '%s'\n"), identifier ); } /* log this to the world */ Write_fd_str( *sock, msg ); setmessage( &job, "LPRM", "start" ); if( Remove_job( &job ) ){ setmessage( &job, "LPRM", "fail" ); plp_snprintf( msg, sizeof(msg), _("error: could not remove '%s'"), identifier ); Write_fd_str( *sock, msg ); goto error; } setmessage( &job, "LPRM", "success" ); if( (pid = Find_flag_value(&job.info,SERVER)) ){ DEBUGF(DLPRM4)("Get_queue_remove: active_pid %d", pid ); if( kill( pid, 0 ) == 0 ){ Check_max(&active_pid,1); active_pid.list[active_pid.count++] = Cast_int_to_voidstar(pid); } } ++removed; if( tokens->count == 0 ) break; } if( fd > 0 ) close(fd); fd = -1; Free_line_list(&info); Free_job(&job); Free_line_list( &Sort_order ); if( removed ){ for( i = 0; i < active_pid.count; ++i ){ pid = Cast_ptr_to_int(active_pid.list[i]); active_pid.list[i] = 0; DEBUGF(DLPRM2)("Get_queue_remove: killing pid '%d' SIGHUP/SIGINT/SIGQUIT/SIGCONT", pid ); killpg( pid, SIGHUP ); kill( pid, SIGHUP ); killpg( pid, SIGINT ); kill( pid, SIGINT ); killpg( pid, SIGQUIT ); kill( pid, SIGQUIT ); killpg( pid, SIGCONT ); kill( pid, SIGCONT ); } /* kill spooler process */ pid = Read_pid_from_file( Queue_lock_file_DYN ); DEBUGF(DLPRM2)("Get_queue_status: checking server pid %d", pid ); /* kill active spooler */ if( pid > 0 ){ kill( pid, SIGUSR2 ); } } if( Server_names_DYN ){ Free_line_list(&info); Split(&info, Server_names_DYN, File_sep, 0,0,0,0,0,0); for( i = 0; i < info.count; ++i ){ DEBUGF(DLPRM2)("Get_queue_status: getting subserver status '%s'", info.list[i] ); Set_DYN(&Printer_DYN,info.list[i]); Get_local_or_remote_remove( user, sock, tokens, done_list ); DEBUGF(DLPRM2)("Get_queue_status: finished subserver status '%s'", info.list[i] ); } } else if( Destinations_DYN ){ Free_line_list(&info); Split(&info, Destinations_DYN, File_sep, 0,0,0,0,0,0); for( i = 0; i < info.count; ++i ){ DEBUGF(DLPRM2)("Get_queue_status: getting destination status '%s'", info.list[i] ); Set_DYN(&Printer_DYN,info.list[i]); Get_local_or_remote_remove( user, sock, tokens, done_list ); DEBUGF(DLPRM2)("Get_queue_status: finished destination status '%s'", info.list[i] ); } } else if( RemoteHost_DYN ){ if( Find_fqdn( &LookupHost_IP, RemoteHost_DYN ) && ( !Same_host(&LookupHost_IP,&Host_IP ) || !Same_host(&LookupHost_IP,&Localhost_IP )) ){ DEBUGF(DLPQ1)("Get_local_or_remote_status: doing local"); if( safestrcmp(RemotePrinter_DYN, Printer_DYN) ){ Set_DYN(&Printer_DYN,RemotePrinter_DYN); Get_queue_remove( user, sock, tokens, done_list ); } else { plp_snprintf(msg,sizeof(msg), "Error: loop in printcap- %s@%s -> %s@%s\n", Printer_DYN, FQDNHost_FQDN, RemotePrinter_DYN, RemoteHost_DYN ); Write_fd_str(*sock, msg ); } } else { /* put user name at start of list */ Check_max(tokens,2); for( i = tokens->count; i > 0; --i ){ tokens->list[i] = tokens->list[i-1]; } tokens->list[0] = user; ++tokens->count; tokens->list[tokens->count] = 0; fd = Send_request( 'M', REQ_REMOVE, tokens->list, Connect_timeout_DYN, Send_query_rw_timeout_DYN, *sock ); if( fd >= 0 ){ shutdown( fd, 1 ); while( (c = Read_fd_len_timeout(Send_query_rw_timeout_DYN, fd,msg,sizeof(msg))) > 0 ){ Write_fd_len(*sock,msg,c); } close(fd); fd = -1; } for( i = 0; i < tokens->count; ++i ){ tokens->list[i] = tokens->list[i+1]; } --tokens->count; } } DEBUGF(DLPRM2)("Get_queue_remove: finished '%s'", Printer_DYN ); goto done; error: DEBUGF(DLPRM2)("Get_queue_remove: error msg '%s'", msg ); plp_snprintf(header, sizeof(header), "Printer: %s", Printer_DYN ); safestrncpy( header, _(" ERROR: ") ); safestrncat( header, msg ); safestrncat( header, "\n" ); Write_fd_str( *sock, header ); done: active_pid.count = 0; Free_line_list(&info); Free_line_list(&active_pid); Free_job(&job); if( fd > 0 ) close(fd); fd = -1; return; } static void Get_local_or_remote_remove( char *user, int *sock, struct line_list *tokens, struct line_list *done_list ) { char msg[LARGEBUFFER]; int fd, n, i; /* we have to see if the host is on this machine */ if( !safestrchr(Printer_DYN,'@') ){ Get_queue_remove( user, sock, tokens, done_list ); return; } Fix_Rm_Rp_info(0,0); /* now we look at the remote host */ if( Find_fqdn( &LookupHost_IP, RemoteHost_DYN ) && ( !Same_host(&LookupHost_IP,&Host_IP ) || !Same_host(&LookupHost_IP,&Localhost_IP )) ){ Get_queue_remove( user, sock, tokens, done_list ); return; } /* put user name at start of list */ Check_max(tokens,2); for( i = tokens->count; i > 0; --i ){ tokens->list[i] = tokens->list[i-1]; } tokens->list[0] = user; ++tokens->count; tokens->list[tokens->count] = 0; fd = Send_request( 'M', REQ_REMOVE, tokens->list, Connect_timeout_DYN, Send_query_rw_timeout_DYN, *sock ); if( fd >= 0 ){ shutdown( fd, 1 ); while( (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN, fd,msg,sizeof(msg))) > 0 ){ Write_fd_len(*sock,msg,n); } close(fd); fd = -1; } for( i = 0; i < tokens->count; ++i ){ tokens->list[i] = tokens->list[i+1]; } --tokens->count; } int Remove_file( char *openname ) { int fail = 0; struct stat statb; if( openname && stat( openname, &statb ) == 0 ){ DEBUGF(DLPRM3)("Remove_file: removing '%s'", openname ); if( unlink( openname ) || stat( openname, &statb ) == 0 ){ logerr(LOG_INFO, "Remove_file: unlink did not remove '%s'", openname); fail |= 1; } } return( fail ); } int Remove_job( struct job *job ) { int i; int fail = 0; char *identifier, *openname; struct line_list *datafile; DEBUGFC(DLPRM1)Dump_job("Remove_job",job); setmessage(job,STATE,"REMOVE"); identifier = Find_str_value(&job->info,IDENTIFIER); if( !identifier ) identifier = Find_str_value(&job->info,XXCFTRANSFERNAME); DEBUGF(DLPRM1)("Remove_job: identifier '%s'",identifier); fail = 0; for( i = 0; i < job->datafiles.count; ++i ){ datafile = (void *)job->datafiles.list[i]; openname = Find_str_value(datafile,OPENNAME); fail |= Remove_file( openname ); openname = Find_str_value(datafile,DFTRANSFERNAME); fail |= Remove_file( openname ); } openname = Find_str_value(&job->info,OPENNAME); fail |= Remove_file( openname ); openname = Find_str_value(&job->info,HF_NAME); fail |= Remove_file( openname ); if( fail == 0 ){ setmessage( job, TRACE, "remove SUCCESS" ); } else { setmessage( job, TRACE, "remove FAILED" ); } if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } return( fail ); } lprng-3.8.B/src/common/getprinter.c0000644000131400013140000003272211531672131014213 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "gethostinfo.h" #include "getprinter.h" #include "getqueue.h" #include "child.h" /**** ENDINCLUDE ****/ /*************************************************************************** Get_printer() determine the name of the printer - Printer_DYN variable Note: this is used by clients to find the name of default printer or by server to find forwarding information. If the printcap RemotePrinter_DYN is specified this overrides the printer name. 1. -P option 2. $PRINTER, $LPDEST, $NPRINTER, $NGPRINTER argument variable 3. printcap file 4. "lp" if none specified 5. Get the printcap entry (if any), and re-extract information- - printer name (primary name) - lp=printer@remote or rp@rm information 6. recheck the printer name for printer@hostname form, and set RemoteHost_DYN to the hostname Note: this appears to cover all the cases, with the exception that a primary name of the form printer@host will be detected as the destination. Sigh... ***************************************************************************/ char *Get_printer(void) { char *s = Printer_DYN; DEBUG1("Get_printer: original printer '%s'", s ); if( s == 0 ) s = getenv( "PRINTER" ); if( s == 0 ) s = getenv( "LPDEST" ); if( s == 0 ) s = getenv( "NPRINTER" ); if( s == 0 ) s = getenv( "NGPRINTER" ); if( !Require_explicit_Q_DYN ){ if( s == 0 ){ Get_all_printcap_entries(); if( All_line_list.count ){ s = All_line_list.list[0]; } } if( s == 0 ) s = Default_printer_DYN; } if( s == 0 ){ fatal(LOG_ERR, "No printer name available, usage: 'lpr -Pprinter filename'" ); } Set_DYN(&Printer_DYN,s); Expand_vars(); DEBUG1("Get_printer: final printer '%s'",Printer_DYN); return(Printer_DYN); } /*************************************************************************** * Fix_Rm_Rp_info * - get the remote host and remote printer information * - we assume this is called by clients trying to get remote host * connection information * - we may want to get the printcap information as a side effect * ***************************************************************************/ void Fix_Rm_Rp_info(char *report_conflict, int report_len ) { char *s; DEBUG1("Fix_Rm_Rp_info: printer name '%s'", Printer_DYN ); /* * now check to see if we have a remote printer * 1. printer@host form overrides * 2. printcap entry, we use lp=pr@host * 3. printcap entry, we use remote host, remote printer * 4. no printcap entry, we use default printer, default remote host */ s = Printer_DYN; Printer_DYN = 0; Reset_config(); Printer_DYN = s; Free_line_list(&PC_alias_line_list); Free_line_list(&PC_entry_line_list); Set_DYN(&Lp_device_DYN, 0 ); Set_DYN(&RemotePrinter_DYN, 0 ); Set_DYN(&RemoteHost_DYN, 0 ); if( !Is_server ){ if( (s = safestrchr( Printer_DYN, '@' )) ){ Set_DYN(&RemotePrinter_DYN, Printer_DYN ); *s = 0; Set_DYN(&Queue_name_DYN, Printer_DYN ); s = safestrchr( RemotePrinter_DYN, '@'); *s++ = 0; Set_DYN(&RemoteHost_DYN, s ); if( (s = safestrchr(RemoteHost_DYN,'%')) ){ Set_DYN(&Unix_socket_path_DYN, 0 ); } /* force connection via TCP/IP */ goto done; } /* we search for the values in the printcap */ Set_DYN(&Queue_name_DYN, Printer_DYN ); s = 0; if( (s = Select_pc_info(Printer_DYN, &PC_entry_line_list, &PC_alias_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, 0, 1 )) || (s = Select_pc_info("*", &PC_entry_line_list, &PC_alias_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, 0, 0 )) ){ if( !safestrcmp( s, "*" ) ){ s = Queue_name_DYN; } Set_DYN(&Printer_DYN,s); DEBUG2("Fix_Rm_Rp_info: from printcap found '%s'", Printer_DYN ); if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_alias_line_list", &PC_alias_line_list ); if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_entry_line_list", &PC_entry_line_list ); } if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - final PC_entry_line_list", &PC_entry_line_list ); Find_default_tags( &PC_entry_line_list, Pc_var_list, "client." ); Find_tags( &PC_entry_line_list, &Config_line_list, "client." ); Find_tags( &PC_entry_line_list, &PC_entry_line_list, "client." ); Set_var_list( Pc_var_list, &PC_entry_line_list); if( RemoteHost_DYN && Lp_device_DYN && report_conflict ){ plp_snprintf(report_conflict,report_len, "conflicting printcap entries :lp=%s:rm=%s", Lp_device_DYN, RemoteHost_DYN ); } /* if a client and have direct, then we need to use * the LP values */ Expand_percent( &Lp_device_DYN ); if( Direct_DYN ){ DEBUG2("Fix_Rm_Rp_info: direct to '%s'", Lp_device_DYN ); if( strchr( "/|", cval(Lp_device_DYN)) ){ Set_DYN(&RemotePrinter_DYN, 0 ); Set_DYN(&RemoteHost_DYN, 0 ); goto done; } if( (s = safestrchr( Lp_device_DYN, '@' )) ){ Set_DYN(&RemotePrinter_DYN, Lp_device_DYN ); *s = 0; Set_DYN(&Queue_name_DYN, Printer_DYN ); s = safestrchr( RemotePrinter_DYN, '@'); *s++ = 0; Set_DYN(&RemoteHost_DYN, s ); if( (s = safestrchr(RemoteHost_DYN,'%')) ){ Set_DYN(&Unix_socket_path_DYN, 0 ); } goto done; } } if( Force_localhost_DYN ){ DEBUG2("Fix_Rm_Rp_info: force_localhost to '%s'", Printer_DYN ); Set_DYN( &RemoteHost_DYN, LOCALHOST ); Set_DYN( &RemotePrinter_DYN, Printer_DYN ); Set_DYN( &Lp_device_DYN, 0 ); goto done; } if( (s = safestrchr( Lp_device_DYN, '@' )) ){ DEBUG2("Fix_Rm_Rp_info: Lp_device_DYN is printer '%s'", Lp_device_DYN ); Set_DYN(&RemotePrinter_DYN, Lp_device_DYN ); if( (s = safestrchr( RemotePrinter_DYN,'@')) ){ *s++ = 0; Set_DYN(&RemoteHost_DYN, s ); if( (s = safestrchr(RemoteHost_DYN+1,'%')) ){ Set_DYN(&Unix_socket_path_DYN, 0 ); } } } if( RemoteHost_DYN == 0 || *RemoteHost_DYN == 0 ){ Set_DYN( &RemoteHost_DYN, Default_remote_host_DYN ); } if( RemoteHost_DYN == 0 || *RemoteHost_DYN == 0 ){ Set_DYN( &RemoteHost_DYN, FQDNHost_FQDN ); } if( RemotePrinter_DYN == 0 || *RemotePrinter_DYN == 0 ){ Set_DYN( &RemotePrinter_DYN, Printer_DYN ); } goto done; } /* we are a server */ /* we search for the values in the printcap */ s = 0; Set_DYN(&Queue_name_DYN, Printer_DYN ); if( (s = Select_pc_info(Printer_DYN, &PC_entry_line_list, &PC_alias_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, 0, 1 )) || (s = Select_pc_info("*", &PC_entry_line_list, &PC_alias_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, 0, 0 )) ){ if( !safestrcmp( s, "*" ) ){ s = Queue_name_DYN; } Set_DYN(&Printer_DYN,s); DEBUG2("Fix_Rm_Rp_info: found '%s'", Printer_DYN ); } if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_alias_line_list", &PC_alias_line_list ); if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_entry_line_list", &PC_entry_line_list ); /* now get the Server_xxx variables */ Find_default_tags( &PC_entry_line_list, Pc_var_list, "server." ); Find_tags( &PC_entry_line_list, &Config_line_list, "server." ); Find_tags( &PC_entry_line_list, &PC_entry_line_list, "server." ); Set_var_list( Pc_var_list, &PC_entry_line_list); if( RemoteHost_DYN && Lp_device_DYN && report_conflict ){ plp_snprintf(report_conflict,report_len, "conflicting printcap entries :lp=%s:rm=%s", Lp_device_DYN, RemoteHost_DYN ); } if( safestrchr( Lp_device_DYN, '@' ) ){ Set_DYN(&RemotePrinter_DYN, Lp_device_DYN ); s = safestrchr( RemotePrinter_DYN, '@'); if( s ) *s++ = 0; else if( *s == 0 ) s = 0; Set_DYN(&RemoteHost_DYN, s ); if( (s = safestrchr(RemoteHost_DYN,'%')) ){ Set_DYN(&Unix_socket_path_DYN, 0 ); } Set_DYN(&Lp_device_DYN,0); } else if( Lp_device_DYN ){ Set_DYN(&RemoteHost_DYN,0); Set_DYN(&RemotePrinter_DYN,0); } else if( RemoteHost_DYN ){ ; /* we use defaults */ } else if( Server_names_DYN == 0 ){ if( report_conflict ){ plp_snprintf(report_conflict,report_len, "no :rm, :lp, or :sv entry" ); } } if( !Lp_device_DYN ){ if( ISNULL(RemoteHost_DYN) ){ Set_DYN( &RemoteHost_DYN, Default_remote_host_DYN ); } if( ISNULL(RemoteHost_DYN) ){ Set_DYN( &RemoteHost_DYN, FQDNHost_FQDN ); } if( ISNULL(RemotePrinter_DYN) ){ Set_DYN( &RemotePrinter_DYN, Printer_DYN ); } } done: Expand_vars(); /* * make sure that these entries are in the printcap file */ if( Pc_entries_required_DYN){ struct line_list list; struct keywords *var_list = Pc_var_list; int i; Init_line_list( &list ); Split(&list,Pc_entries_required_DYN,File_sep,0,0,0,0,0,0); for( i = 0; i < list.count; ++i ){ const char *t; int mid; char *s = list.list[i]; if( ISNULL(s) ) continue; DEBUG3( "Fix_Rm_Rp_info: checking '%s'", s ); if( !Find_first_key( &PC_entry_line_list, s, Hash_value_sep, &mid ) ){ t = safestrpbrk(PC_entry_line_list.list[mid], Option_value_sep ); DEBUG1( "Fix_Rm_Rp_info: FOUND %s VALUE %s", s, t ); continue; } if( !Find_first_key( &Config_line_list, s, Hash_value_sep, &mid ) ){ t = safestrpbrk(Config_line_list.list[mid], Hash_value_sep ); DEBUG1( "Fix_Rm_Rp_info: CONFIG %s VALUE %s", s, t ); Set_str_value(&PC_entry_line_list, s, t); continue; } for( var_list = Pc_var_list; var_list->keyword; ++var_list ){ if( !strcmp(var_list->keyword, s) ){ int type = var_list->type; /* type of entry */ int v; void *p = var_list->variable; /* address of variable */ if( !(p) ) break; switch(type){ case FLAG_K: v = *(int *)(p); DEBUG1( "Fix_Rm_Rp_info: VAR %s FLAG %d", var_list->keyword, v); Set_flag_value(&PC_entry_line_list, var_list->keyword, v); break; case INTEGER_K: v = *(int *)(p); DEBUG1( "Fix_Rm_Rp_info: VAR %s INT %d", var_list->keyword, v); Set_decimal_value(&PC_entry_line_list, var_list->keyword, v); break; case STRING_K: t = *(char **)(p); DEBUG1( "Fix_Rm_Rp_info: VAR %s= '%s'", var_list->keyword, t ); if( t ){ Set_str_value(&PC_entry_line_list, var_list->keyword, t); } break; default: break; } break; } } } Free_line_list( &list ); } DEBUG1("Fix_Rm_Rp_info: Printer '%s', Queue '%s', Lp '%s', Rp '%s', Rh '%s'", Printer_DYN, Queue_name_DYN, Lp_device_DYN, RemotePrinter_DYN, RemoteHost_DYN ); if(DEBUGL2)Dump_parms("Fix_Rm_Rp_info", Pc_var_list); } /*************************************************************************** * Get_all_printcap_entries( char *s ) * - get the remote host and remote printer information * - we assume this is called by clients trying to get remote host * connection information * - we may want to get the printcap information as a side effect * ***************************************************************************/ void Get_all_printcap_entries(void) { const char *s, *t; int i; /* * now check to see if we have an entry for the 'all:' printcap */ s = t = 0; DEBUG1("Get_all_printcap_entries: starting"); Free_line_list( &All_line_list ); if( (s = Select_pc_info(ALL, &PC_entry_line_list, &PC_alias_line_list, &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, 0, 0 )) ){ if( !(t = Find_str_value( &PC_entry_line_list, ALL )) ){ t = "all"; } DEBUG1("Get_all_printcap_entries: '%s' has '%s'",s,t); Split(&All_line_list,t,File_sep,0,0,0,1,0,0); } else { for( i = 0; i < PC_order_line_list.count; ++i ){ s = PC_order_line_list.list[i]; if( ISNULL(s) || !safestrcmp( ALL, s ) ) continue; if( safestrcmp(s,"*") && !ispunct( cval( s ) ) ){ Add_line_list(&All_line_list,s,0,0,0); } } } if(DEBUGL1)Dump_line_list("Get_all_printcap_entries- All_line_list", &All_line_list ); } void Show_formatted_info( void ) { char *s; char error[SMALLBUFFER]; DEBUG1("Show_formatted_info: getting printcap information for '%s'", Printer_DYN ); error[0] = 0; Fix_Rm_Rp_info(error,sizeof(error)); if( error[0] ){ WARNMSG( "%s: '%s'", Printer_DYN, error ); } if(DEBUGL1)Dump_line_list("Aliases",&PC_alias_line_list); s = Join_line_list_with_sep(&PC_alias_line_list,"|"); if( Write_fd_str( 1, s ) < 0 ) cleanup(0); if(s) free(s); s = 0; /* Escape_colons( &PC_entry_line_list ); */ s = Join_line_list_with_sep(&PC_entry_line_list,"\n :"); Expand_percent( &s ); if( s ){ if( Write_fd_str( 1, "\n :" ) < 0 ) cleanup(0); if( Write_fd_str( 1, s ) < 0 ) cleanup(0); } if( s ) free(s); s =0; if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0); } void Show_all_printcap_entries( void ) { char *s; int i; s = 0; Get_all_printcap_entries(); s = Join_line_list_with_sep(&PC_names_line_list,"\n :"); if( Write_fd_str( 1, "\n.names\n" ) < 0 ) cleanup(0); if( s && *s ){ if( Write_fd_str( 1, " :" ) < 0 ) cleanup(0); if( Write_fd_str( 1, s ) < 0 ) cleanup(0); if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0); } if(s) free(s); s = 0; s = Join_line_list_with_sep(&All_line_list,"\n :"); if( Write_fd_str( 1, "\n.all\n" ) < 0 ) cleanup(0); if( s && *s ){ if( Write_fd_str( 1, " :" ) < 0 ) cleanup(0); if( Write_fd_str( 1, s ) < 0 ) cleanup(0); if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0); } if( s ) free(s); s =0; if( Write_fd_str( 1,"\n#Printcap Information\n") < 0 ) cleanup(0); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,All_line_list.list[i]); Show_formatted_info(); } } lprng-3.8.B/src/common/lpd_dispatch.c0000644000131400013140000002206511531672131014465 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: lpd_dispatch.c,v 1.74 2004/09/24 20:19:58 papowell Exp $"; #include "lp.h" #include "errorcodes.h" #include "getqueue.h" #include "getprinter.h" #include "gethostinfo.h" #include "linksupport.h" #include "child.h" #include "fileopen.h" #include "permission.h" #include "proctitle.h" #include "lpd_rcvjob.h" #include "lpd_remove.h" #include "lpd_status.h" #include "lpd_control.h" #include "lpd_secure.h" #include "krb5_auth.h" #include "lpd_dispatch.h" static void Service_lpd( int talk, const char *from_addr ) NORETURN; void Dispatch_input(int *talk, char *input, const char *from_addr ) { switch( input[0] ){ default: fatal(LOG_INFO, _("Dispatch_input: bad request line '%s' from %s"), input, from_addr ); break; case REQ_START: /* simply send a 0 ACK and close connection - NOOP */ Write_fd_len( *talk, "", 1 ); break; case REQ_RECV: Receive_job( talk, input ); break; case REQ_DSHORT: case REQ_DLONG: case REQ_VERBOSE: Job_status( talk, input ); break; case REQ_REMOVE: Job_remove( talk, input ); break; case REQ_CONTROL: Job_control( talk, input ); break; case REQ_BLOCK: Receive_block_job( talk, input ); break; case REQ_SECURE: Receive_secure( talk, input ); break; } } void Service_all( struct line_list *args, int reportfd ) { int i, printable, held, move, printing_enabled, server_pid, change, error, done, do_service; char buffer[SMALLBUFFER], *pr, *forwarding; int first_scan; char *remove_prefix = 0; /* we start up servers while we can */ Name = "SERVICEALL"; setproctitle( "lpd %s", Name ); first_scan = Find_flag_value(args,FIRST_SCAN); Free_line_list(args); if(All_line_list.count == 0 ){ Get_all_printcap_entries(); } for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,0); Set_DYN(&Spool_dir_DYN,0); pr = All_line_list.list[i]; DEBUG1("Service_all: checking '%s'", pr ); if( Setup_printer( pr, buffer, sizeof(buffer), 0) ) continue; /* now check to see if there is a server and unspooler process active */ server_pid = 0; remove_prefix = 0; if( first_scan ){ remove_prefix = Fifo_lock_file_DYN; } server_pid = Read_pid_from_file( Printer_DYN ); DEBUG3("Service_all: printer '%s' checking server pid %d", Printer_DYN, server_pid ); if( server_pid > 0 && kill( server_pid, 0 ) == 0 ){ DEBUG3("Get_queue_status: server %d active", server_pid ); continue; } change = Find_flag_value(&Spool_control,CHANGE); printing_enabled = !(Pr_disabled(&Spool_control) || Pr_aborted(&Spool_control)); Free_line_list( &Sort_order ); if( Scan_queue( &Spool_control, &Sort_order, &printable,&held,&move, 1, &error, &done, 0, 0 ) ){ continue; } forwarding = Find_str_value(&Spool_control,FORWARDING); do_service = 0; if( !(Save_when_done_DYN || Save_on_error_DYN ) && (Done_jobs_DYN || Done_jobs_max_age_DYN) && (error || done ) ){ do_service = 1; } if( do_service || change || move || (printable && (printing_enabled||forwarding)) ){ if( Server_queue_name_DYN ){ pr = Server_queue_name_DYN; } else { pr = Printer_DYN;; } DEBUG1("Service_all: starting '%s'", pr ); plp_snprintf(buffer,sizeof(buffer), ".%s\n",pr ); if( Write_fd_str(reportfd,buffer) < 0 ) cleanup(0); } } Free_line_list( &Sort_order ); Errorcode = 0; cleanup(0); } /*************************************************************************** * Service_connection( struct line_list *args ) * Service the connection on the talk socket * 1. fork a connection * 2. Mother: close talk and return * 2 Child: close listen * 2 Child: read input line and decide what to do * ***************************************************************************/ void Service_connection( struct line_list *args, int talk ) { #ifdef IPP_STUBS char input[16]; int status; /* status of operation */ #endif /* IPP_STUBS */ char from_addr[128]; int permission; int port = 0; struct sockaddr sinaddr; memset( &sinaddr, 0, sizeof(sinaddr) ); Name = "SERVER"; setproctitle( "lpd %s", Name ); (void) plp_signal (SIGHUP, cleanup ); if( !talk ){ Errorcode = JABORT; fatal(LOG_ERR, "Service_connection: no talk fd"); } DEBUG1("Service_connection: listening fd %d", talk ); Free_line_list(args); /* make sure you use blocking IO */ Set_block_io(talk); { socklen_t len; len = sizeof( sinaddr ); if( getpeername( talk, &sinaddr, &len ) ){ logerr_die(LOG_DEBUG, _("Service_connection: getpeername failed") ); } } DEBUG1("Service_connection: family %d, " #ifdef AF_LOCAL "AF_LOCAL %d," #endif #ifdef AF_UNIX "AF_UNIX %d" #endif "%s" , sinaddr.sa_family, #ifdef AF_LOCAL AF_LOCAL, #endif #ifdef AF_UNIX AF_UNIX, #endif ""); if( sinaddr.sa_family == AF_INET ){ port = ((struct sockaddr_in *)&sinaddr)->sin_port; #if defined(IPV6) } else if( sinaddr.sa_family == AF_INET6 ){ port = ((struct sockaddr_in6 * )&sinaddr)->sin6_port; #endif } else if( sinaddr.sa_family == 0 #if defined(AF_LOCAL) || sinaddr.sa_family == AF_LOCAL #endif #if defined(AF_UNIX) || sinaddr.sa_family == AF_UNIX #endif ){ /* force the localhost address */ int len; void *s, *addr; memset( &sinaddr, 0, sizeof(sinaddr) ); Perm_check.unix_socket = 1; sinaddr.sa_family = Localhost_IP.h_addrtype; len = Localhost_IP.h_length; if( sinaddr.sa_family == AF_INET ){ addr = &(((struct sockaddr_in *)&sinaddr)->sin_addr); #if defined(IPV6) } else if( sinaddr.sa_family == AF_INET6 ){ addr = &(((struct sockaddr_in6 *)&sinaddr)->sin6_addr); #endif } else { fatal(LOG_INFO, _("Service_connection: BAD LocalHost_IP value")); addr = 0; } s = Localhost_IP.h_addr_list.list[0]; memmove(addr,s,len); } else { fatal(LOG_INFO, _("Service_connection: bad protocol family '%d'"), sinaddr.sa_family ); } inet_ntop_sockaddr( &sinaddr, from_addr, sizeof(from_addr) ); { int len = strlen(from_addr); plp_snprintf(from_addr+len,sizeof(from_addr)-len, " port %d", ntohs(port)); } DEBUG2("Service_connection: socket %d, from %s", talk, from_addr ); /* get the remote name and set up the various checks */ Get_remote_hostbyaddr( &RemoteHost_IP, &sinaddr, 0 ); Perm_check.remotehost = &RemoteHost_IP; Perm_check.host = &RemoteHost_IP; Perm_check.port = ntohs(port); /* read the permissions information */ if( Perm_filters_line_list.count ){ Free_line_list(&Perm_line_list); Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); Filterprintcap( &Perm_line_list, &Perm_filters_line_list, ""); } Perm_check.service = 'X'; permission = Perms_check( &Perm_line_list, &Perm_check, 0, 0 ); if( permission == P_REJECT ){ DEBUG1("Service_connection: no perms on talk socket '%d' from %s", talk, from_addr ); safefprintf(talk, "\001%s\n", _("no connect permissions")); cleanup(0); } #ifdef IPP_STUBS memset(input,0,sizeof(input)); do { int my_len = sizeof( input ) - 1; static int timeout; timeout = (Send_job_rw_timeout_DYN>0)?Send_job_rw_timeout_DYN: ((Connect_timeout_DYN>0)?Connect_timeout_DYN:10); DEBUG1( "Service_connection: doing peek for %d on fd %d, timeout %d", my_len, talk, timeout ); if( Set_timeout() ){ Set_timeout_alarm( timeout ); status = recv( talk, input, my_len, MSG_PEEK ); } else { status = -1; } Clear_timeout(); if( status <= 0 ){ logerr_die(LOG_DEBUG, _("Service_connection: peek of length %d failed"), my_len ); } DEBUG1("Service_connection: status %d 0x%02x%02x%02x%02x (%c%c%c%c)", status, cval(input+0), cval(input+1), cval(input+2), cval(input+3), cval(input+0), cval(input+1), cval(input+2), cval(input+3)); } while( status < 2 ); if( isalpha(cval(input+0)) && isalpha(cval(input+1)) && isalpha(cval(input+2)) ){ /* Service_ipp( talk, from_addr ); */ } else if( cval(input+0) == 0x80 ) { /* Service_ssh_ipp( talk, from_addr ); */ } #endif /* not IPP_STUBS */ Service_lpd( talk, from_addr ); } static void Service_lpd( int talk, const char *from_addr ) { char input[LINEBUFFER]; int status; int len = sizeof( input ) - 1; int timeout = (Send_job_rw_timeout_DYN>0)?Send_job_rw_timeout_DYN: ((Connect_timeout_DYN>0)?Connect_timeout_DYN:10); memset(input,0,sizeof(input)); DEBUG1( "Service_connection: starting read on fd %d, timeout %d", talk, timeout ); status = Link_line_read(ShortRemote_FQDN,&talk, timeout,input,&len); if( len >= 0 ) input[len] = 0; DEBUG1( "Service_connection: read status %d, len %d, '%s'", status, len, input ); if( len == 0 ){ DEBUG3( "Service_connection: zero length read" ); cleanup(0); } if( status ){ logerr_die(LOG_DEBUG, _("Service_connection: cannot read request from %s in %d seconds"), from_addr, timeout ); } if( len < 2 ){ fatal(LOG_INFO, _("Service_connection: short request line '%s', from '%s'"), input, from_addr ); } Dispatch_input(&talk,input,from_addr); cleanup(0); } lprng-3.8.B/src/common/stty.c0000644000131400013140000007324311531672132013037 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "stty.h" /**** ENDINCLUDE ****/ #if USE_STTY == TERMIO # ifdef HAVE_TERMIO_H # include # endif # ifdef HAVE_SYS_TERMIO_H # include # endif #endif #if USE_STTY == SGTTYB # include #endif #if USE_STTY == TERMIOS # include # ifdef USE_TERMIOX # if defined(_SCO_DS) && !defined(_SVID3) # define _SVID3 1 /* needed to enable #defines in SCO v5 termiox.h */ # endif # include # endif #endif #if !defined(TIOCEXCL) && defined(HAVE_SYS_TTOLD_H) && !defined(IRIX) # include #endif #if USE_STTY == SGTTYB # if !defined(B19200) # ifdef EXTA # define B19200 EXTA # else # define B19200 B9600 # endif /* !defined(EXTA) */ # endif /* !defined(B19200) */ #if !defined(B38400) #ifdef EXTB #define B38400 EXTB #else #define B38400 B9600 #endif /* !defined(EXTB) */ #endif /* !defined(B38400) */ static struct bauds { char *string; int baud; int speed; } bauds[] = { { "110", 110, B110, }, { "134", 134, B134, }, { "150", 150, B150, }, { "300", 300, B300, }, { "600", 600, B600, }, { "1200", 1200, B1200, }, { "1800", 1800, B1800, }, { "2400", 2400, B2400, }, { "4800", 4800, B4800, }, { "9600", 9600, B9600, }, { "19200", 19200, B19200, }, { "38400", 38400, B38400, }, #if defined(B57600) { "57600", 57600, B57600, }, #endif #if defined(B115200) { "115200", 115200, B115200, }, #endif #if defined(B230400) { "230400", 230400, B230400, }, #endif #if defined(B460800) { "460800", 460800, B460800, }, #endif #if defined(B500000) { "500000", 500000, B500000, }, #endif #if defined(B576000) { "576000", 576000, B576000, }, #endif #if defined(B921600) { "921600", 921600, B921600, }, #endif { (char *) 0, 0, 0 } }; /* * Set terminal modes. * * jmason: I've added support for some combination modes, * such as "pass8" and "parity". */ struct tchars termctrl; struct ltchars linectrl; struct sgttyb mode; static struct { char *string; int set; int reset; int lset; int lreset; } modes[] = { { "bs0", BS0, BS1, 0, 0 }, { "bs1", BS1, BS1, 0, 0 }, { "cbreak", CBREAK, 0, 0, 0 }, { "-cbreak", 0, CBREAK, 0, 0 }, { "cooked", 0, RAW, 0, 0 }, { "cr0", CR0, CR3, 0, 0 }, { "cr1", CR1, CR3, 0, 0 }, { "cr2", CR2, CR3, 0, 0 }, { "cr3", CR3, CR3, 0, 0 }, { "decctlq", 0, 0, LDECCTQ, 0 }, { "-decctlq", 0, 0, 0, LDECCTQ, }, { "echo", ECHO, 0, 0, 0 }, { "-echo", 0, ECHO, 0, 0 }, { "even", EVENP, 0, 0, 0 }, { "-even", 0, EVENP, 0, 0 }, { "ff0", FF0, FF1, 0, 0 }, { "ff1", FF1, FF1, 0, 0 }, { "lcase", LCASE, 0, 0, 0 }, { "-lcase", 0, LCASE, 0, 0 }, { "litout", 0, 0, LLITOUT, 0 }, { "-litout", 0, 0, 0, LLITOUT, }, { "nl", 0, CRMOD, 0, 0 }, { "-nl", CRMOD, 0, 0, 0 }, { "nl0", NL0, NL3, 0, 0 }, { "nl1", NL1, NL3, 0, 0 }, { "nl2", NL2, NL3, 0, 0 }, { "nl3", NL3, NL3, 0, 0 }, { "noflsh", 0, 0, LNOFLSH, 0 }, { "-noflsh", 0, 0, 0, LNOFLSH, }, { "nohang", 0, 0, LNOHANG, 0 }, { "-nohang", 0, 0, 0, LNOHANG, }, { "odd", ODDP, 0, 0, 0 }, { "-odd", 0, ODDP, 0, 0 }, { "raw", RAW, 0, 0, 0 }, { "-raw", 0, RAW, 0, 0 }, { "tab0", TAB0, XTABS, 0, 0 }, { "tab1", TAB1, XTABS, 0, 0 }, { "tab2", TAB2, XTABS, 0, 0 }, { "tabs", 0, XTABS, 0, 0 }, { "-tabs", XTABS, 0, 0, 0 }, { "tandem", TANDEM, 0, 0, 0 }, { "-tandem", 0, TANDEM, 0, 0 }, #ifndef IS_NEXT { "tilde", 0, 0, LTILDE, 0 }, { "-tilde", 0, 0, 0, LTILDE, }, #endif { "tn300", CR1, ALLDELAY, 0, 0 }, { "tty33", CR1, ALLDELAY, 0, 0 }, { "tty37", FF1 + CR2 + TAB1 + NL1, ALLDELAY, 0, 0 }, { "vt05", NL2, ALLDELAY, 0, 0 }, /* jmason modes and synonyms: */ { "evenp", EVENP, 0, 0, 0 }, { "-evenp", 0, EVENP, 0, 0 }, { "parity", EVENP, 0, 0, 0 }, { "-parity", 0, EVENP|ODDP, 0, 0 }, { "oddp", ODDP, 0, 0, 0 }, { "-oddp", 0, ODDP, 0, 0 }, #ifdef LPASS8 { "pass8", 0, 0, LPASS8, 0 }, { "-pass8", 0, 0, 0, LPASS8, }, #endif {0} }; static struct special { char *name; char *cp; char def; } special[] = { { "stop", &termctrl.t_stopc, CSTOP }, { "start", &termctrl.t_startc, CSTART }, { 0, 0, 0 } }; void Do_stty( int fd ) { int i, count; int localmode; int linedisc; char *arg, *option; struct line_list l; Init_line_list(&l); Split(&l,Stty_command_DYN,Whitespace,0,0,0,0,0,0); Check_max(&l,1); l.list[l.count] = 0; DEBUG3("Do_stty: using SGTTYB, fd %d", fd ); if( ioctl( fd, TIOCGETP, &mode) < 0 || ioctl( fd, TIOCGETC, &termctrl) < 0 || ioctl( fd, TIOCLGET, &localmode) < 0 || ioctl( fd, TIOCGLTC, &linectrl) < 0 ){ logerr_die(LOG_INFO, "cannot get tty parameters"); } DEBUG2("stty: before mode 0x%x, lmode 0x%x, speed 0x%x", mode.sg_flags, localmode, mode.sg_ispeed); if( Baud_rate_DYN ){ for( i = 0; bauds[i].baud && Baud_rate_DYN != bauds[i].baud; i++); if( i == 0) { fatal(LOG_INFO, "illegal baud rate %d", Baud_rate_DYN ); } mode.sg_ispeed = mode.sg_ospeed = bauds[i].speed; } for( count = 0; count < l.count; ++count ){ arg = l.list[count]; for( i = 0; modes[i].string && safestrcasecmp( modes[i].string, arg); i++); if( modes[i].string ){ DEBUG3("stty: modes %s, mc 0x%x ms 0x%x lc 0x%x ls 0x%x", modes[i].string, modes[i].reset, modes[i].set, modes[i].lreset, modes[i].lset); mode.sg_flags &= ~modes[i].reset; mode.sg_flags |= modes[i].set; localmode &= ~modes[i].lreset; localmode |= modes[i].lset; continue; } for( i = 0; special[i].name && safestrcasecmp( special[i].name, arg); i++); if( special[i].name) { ++count; option = l.list[count]; if( option == 0) { fatal(LOG_INFO, "stty: missing parameter for %s", arg); } if( option[0] == '^') { if( option[1] == '?') { *special[i].cp = 0177; } else { *special[i].cp = 037 & option[1]; } } else { *special[i].cp = option[0]; } DEBUG3("stty: special %s %s", arg, option); continue; } for( i = 0; bauds[i].string && safestrcasecmp( bauds[i].string, arg); i++); if( bauds[i].string) { DEBUG3("stty: speed %s", arg); mode.sg_ispeed = mode.sg_ospeed = bauds[i].speed; continue; } if( !safestrcasecmp( "new", arg)) { DEBUG3("stty: ldisc %s", arg); linedisc = NTTYDISC; if( ioctl( fd, TIOCSETD, &linedisc) < 0) logerr_die(LOG_INFO, "stty: TIOCSETD ioctl failed"); continue; } if( !safestrcasecmp( "old", arg)) { DEBUG3("stty: ldisc %s", arg); linedisc = 0; if( ioctl( fd, TIOCSETD, &linedisc) < 0) logerr_die(LOG_INFO, "stty: TIOCSETD ioctl failed"); continue; } fatal(LOG_INFO, "unknown mode: %s\n", arg); } DEBUG2("stty: after mode 0x%x, lmode 0x%x, speed 0x%x", mode.sg_flags, localmode, mode.sg_ispeed); if( ioctl( fd, TIOCSETN, &mode) < 0 || ioctl( fd, TIOCSETC, &termctrl) < 0 || ioctl( fd, TIOCSLTC, &linectrl) < 0 || ioctl( fd, TIOCLSET, &localmode) < 0) { logerr_die(LOG_NOTICE, "cannot set tty parameters"); } Free_line_list(&l); } #endif #if USE_STTY == TERMIO /* the folks who are responsible for include files * must be the lowest paid/motivated ones in * OS development... (mj) */ #if !defined(TOSTOP) && defined(_TOSTOP) #define TOSTOP _TOSTOP #endif static struct bauds { char *string; int baud; int speed; } bauds[] = { { "110", 110, B110, }, { "134", 134, B134, }, { "150", 150, B150, }, { "300", 300, B300, }, { "600", 600, B600, }, { "1200", 1200, B1200, }, { "1800", 1800, B1800, }, { "2400", 2400, B2400, }, { "4800", 4800, B4800, }, { "9600", 9600, B9600, }, { "19200", 19200, B19200, }, { "38400", 38400, B38400, }, #if defined(B57600) { "57600", 57600, B57600, }, #endif #if defined(B115200) { "115200", 115200, B115200, }, #endif #if defined(B230400) { "230400", 230400, B230400, }, #endif #if defined(B460800) { "460800", 460800, B460800, }, #endif #if defined(B500000) { "500000", 500000, B500000, }, #endif #if defined(B576000) { "576000", 576000, B576000, }, #endif #if defined(B921600) { "921600", 921600, B921600, }, #endif { (char *) 0, 0, 0 } }; struct termio tio; static struct { char *string; int iset; int ireset; int oset; int oreset; int cset; int creset; int lset; int lreset; } tmodes[] = { /* input modes */ { "ignbrk", IGNBRK, 0, 0, 0, 0, 0, 0, 0 }, { "-ignbrk", 0, IGNBRK, 0, 0, 0, 0, 0, 0 }, { "brkint", BRKINT, 0, 0, 0, 0, 0, 0, 0 }, { "-brkint", 0, BRKINT, 0, 0, 0, 0, 0, 0 }, { "ignpar", IGNPAR, 0, 0, 0, 0, 0, 0, 0 }, { "-ignpar", 0, IGNPAR, 0, 0, 0, 0, 0, 0 }, { "parmrk", PARMRK, 0, 0, 0, 0, 0, 0, 0 }, { "-parmrk", 0, PARMRK, 0, 0, 0, 0, 0, 0 }, { "inpck", INPCK, 0, 0, 0, 0, 0, 0, 0 }, { "-inpck", 0, INPCK, 0, 0, 0, 0, 0, 0 }, { "istrip", ISTRIP, 0, 0, 0, 0, 0, 0, 0 }, { "-istrip", 0, ISTRIP, 0, 0, 0, 0, 0, 0 }, { "inlcr", INLCR, 0, 0, 0, 0, 0, 0, 0 }, { "-inlcr", 0, INLCR, 0, 0, 0, 0, 0, 0 }, { "igncr", IGNCR, 0, 0, 0, 0, 0, 0, 0 }, { "-igncr", 0, IGNCR, 0, 0, 0, 0, 0, 0 }, { "icrnl", ICRNL, 0, 0, 0, 0, 0, 0, 0 }, { "-icrnl", 0, ICRNL, 0, 0, 0, 0, 0, 0 }, { "lcase", IUCLC, 0, 0, 0, 0, 0, 0, 0 }, { "iuclc", IUCLC, 0, 0, 0, 0, 0, 0, 0 }, { "-lcase", 0, IUCLC, 0, 0, 0, 0, 0, 0 }, { "-iuclc", 0, IUCLC, 0, 0, 0, 0, 0, 0 }, { "ixon", IXON, 0, 0, 0, 0, 0, 0, 0 }, { "-ixon", 0, IXON, 0, 0, 0, 0, 0, 0 }, { "ixany", IXANY, 0, 0, 0, 0, 0, 0, 0 }, { "-ixany", 0, IXANY, 0, 0, 0, 0, 0, 0 }, { "ixoff", IXOFF, 0, 0, 0, 0, 0, 0, 0 }, { "-ixoff", 0, IXOFF, 0, 0, 0, 0, 0, 0 }, { "decctlq", IXANY, 0, 0, 0, 0, 0, 0, 0 }, { "-decctlq", 0, IXANY, 0, 0, 0, 0, 0, 0 }, { "tandem", IXOFF, 0, 0, 0, 0, 0, 0, 0 }, { "-tandem", 0, IXOFF, 0, 0, 0, 0, 0, 0 }, #ifdef IMAXBEL { "imaxbel", IMAXBEL, 0, 0, 0, 0, 0, 0, 0 }, { "-maxbel", 0, IMAXBEL, 0, 0, 0, 0, 0, 0 }, #endif /* output modes */ { "opost", 0, 0, OPOST, 0, 0, 0, 0, 0 }, { "-opost", 0, 0, 0, OPOST, 0, 0, 0, 0 }, { "olcuc", 0, 0, OLCUC, 0, 0, 0, 0, 0 }, { "-olcuc", 0, 0, 0, OLCUC, 0, 0, 0, 0 }, { "onlcr", 0, 0, ONLCR, 0, 0, 0, 0, 0 }, { "-onlcr", 0, 0, 0, ONLCR, 0, 0, 0, 0 }, { "ocrnl", 0, 0, OCRNL, 0, 0, 0, 0, 0 }, { "-ocrnl", 0, 0, 0, OCRNL, 0, 0, 0, 0 }, { "onocr", 0, 0, ONOCR, 0, 0, 0, 0, 0 }, { "-onocr", 0, 0, 0, ONOCR, 0, 0, 0, 0 }, { "onlret", 0, 0, ONLRET, 0, 0, 0, 0, 0 }, { "-onlret", 0, 0, 0, ONLRET, 0, 0, 0, 0 }, { "ofill", 0, 0, OFILL, 0, 0, 0, 0, 0 }, { "-ofill", 0, 0, 0, OFILL, 0, 0, 0, 0 }, { "ofdel", 0, 0, OFDEL, 0, 0, 0, 0, 0 }, { "-ofdel", 0, 0, 0, OFDEL, 0, 0, 0, 0 }, { "nl0", 0, 0, NL0, NLDLY, 0, 0, 0, 0 }, { "nl1", 0, 0, NL1, NLDLY, 0, 0, 0, 0 }, { "cr0", 0, 0, CR1, CRDLY, 0, 0, 0, 0 }, { "cr1", 0, 0, CR1, CRDLY, 0, 0, 0, 0 }, { "cr2", 0, 0, CR2, CRDLY, 0, 0, 0, 0 }, { "cr3", 0, 0, CR3, CRDLY, 0, 0, 0, 0 }, { "tab0", 0, 0, TAB0, TABDLY, 0, 0, 0, 0 }, { "tab1", 0, 0, TAB1, TABDLY, 0, 0, 0, 0 }, { "tab2", 0, 0, TAB2, TABDLY, 0, 0, 0, 0 }, { "tab3", 0, 0, TAB3, TABDLY, 0, 0, 0, 0 }, { "bs0", 0, 0, BS0, BSDLY, 0, 0, 0, 0 }, { "bs1", 0, 0, BS1, BSDLY, 0, 0, 0, 0 }, { "vt0", 0, 0, VT0, VTDLY, 0, 0, 0, 0 }, { "vt1", 0, 0, VT1, VTDLY, 0, 0, 0, 0 }, { "ff0", 0, 0, FF0, FFDLY, 0, 0, 0, 0 }, { "ff1", 0, 0, FF1, FFDLY, 0, 0, 0, 0 }, { "nopost", 0, 0, 0, OPOST, 0, 0, 0, 0 }, { "-nopost", 0, 0, OPOST, 0, 0, 0, 0, 0 }, { "fill", 0, 0, OFILL, OFDEL, 0, 0, 0, 0 }, { "-fill", 0, 0, 0, OFILL | OFDEL, 0, 0, 0, 0 }, { "nul-fill", 0, 0, OFILL, OFDEL, 0, 0, 0, 0 }, { "del-fill", 0, 0, OFILL | OFDEL, 0, 0, 0, 0, 0 }, #ifdef XTABS { "tabs", 0, 0, 0, XTABS | TABDLY, 0, 0, 0, 0 }, { "-tabs", 0, 0, XTABS, TABDLY, 0, 0, 0, 0 }, #endif /* control modes */ { "cs5", 0, 0, 0, 0, CS5, CSIZE, 0, 0 }, { "cs6", 0, 0, 0, 0, CS6, CSIZE, 0, 0 }, { "cs7", 0, 0, 0, 0, CS7, CSIZE, 0, 0 }, { "cs8", 0, 0, 0, 0, CS8, CSIZE, 0, 0 }, { "cstopb", 0, 0, 0, 0, CSTOPB, 0, 0, 0 }, { "-cstopb", 0, 0, 0, 0, 0, CSTOPB, 0, 0 }, { "cread", 0, 0, 0, 0, CREAD, 0, 0, 0 }, { "-cread", 0, 0, 0, 0, 0, CREAD, 0, 0 }, { "parenb", 0, 0, 0, 0, PARENB, 0, 0, 0 }, { "-parenb", 0, 0, 0, 0, 0, PARENB, 0, 0 }, { "parodd", 0, 0, 0, 0, PARODD, 0, 0, 0 }, { "-parodd", 0, 0, 0, 0, 0, PARODD, 0, 0 }, { "hupcl", 0, 0, 0, 0, HUPCL, 0, 0, 0 }, { "-hupcl", 0, 0, 0, 0, 0, HUPCL, 0, 0 }, { "clocal", 0, 0, 0, 0, CLOCAL, 0, 0, 0 }, { "-clocal", 0, 0, 0, 0, 0, CLOCAL, 0, 0 }, #ifdef LOBLK { "loblk", 0, 0, 0, 0, LOBLK, 0, 0, 0 }, { "-loblk", 0, 0, 0, 0, 0, LOBLK, 0, 0 }, #endif { "parity", 0, 0, 0, 0, PARENB | CS7, PARODD | CSIZE, 0, 0 }, { "-parity", 0, 0, 0, 0, CS8, PARENB | CSIZE, 0, 0 }, { "evenp", 0, 0, 0, 0, PARENB | CS7, PARODD | CSIZE, 0, 0 }, { "-evenp", 0, 0, 0, 0, CS8, PARENB | CSIZE, 0, 0 }, { "oddp", 0, 0, 0, 0, PARENB | PARODD | CS7, CSIZE, 0, 0 }, { "-oddp", 0, 0, 0, 0, CS8, PARENB | PARODD | CSIZE, 0, 0 }, { "stopb", 0, 0, 0, 0, CSTOPB, 0, 0, 0 }, { "-stopb", 0, 0, 0, 0, 0, CSTOPB, 0, 0 }, { "hup", 0, 0, 0, 0, HUPCL, 0, 0, 0 }, { "-hup", 0, 0, 0, 0, 0, HUPCL, 0, 0 }, #ifdef CRTSCTS { "crtscts", 0, 0, 0, 0, CRTSCTS, 0, 0, 0 }, { "-crtscts", 0, 0, 0, 0, 0, CRTSCTS, 0, 0 }, #endif /* local modes */ { "isig", 0, 0, 0, 0, 0, 0, ISIG, 0 }, { "-isig", 0, 0, 0, 0, 0, 0, 0, ISIG }, { "noisig", 0, 0, 0, 0, 0, 0, 0, ISIG }, { "-noisig", 0, 0, 0, 0, 0, 0, ISIG, 0 }, { "icanon", 0, 0, 0, 0, 0, 0, ICANON, 0 }, { "-icanon", 0, 0, 0, 0, 0, 0, 0, ICANON }, { "cbreak", 0, 0, 0, 0, 0, 0, ICANON, 0 }, { "-cbreak", 0, 0, 0, 0, 0, 0, 0, ICANON }, { "xcase", 0, 0, 0, 0, 0, 0, XCASE, 0 }, { "-xcase", 0, 0, 0, 0, 0, 0, 0, XCASE }, { "echo", 0, 0, 0, 0, 0, 0, ECHO, 0 }, { "-echo", 0, 0, 0, 0, 0, 0, 0, ECHO }, { "echoe", 0, 0, 0, 0, 0, 0, ECHOE, 0 }, { "-echoe", 0, 0, 0, 0, 0, 0, 0, ECHOE }, { "crterase", 0, 0, 0, 0, 0, 0, ECHOE, 0 }, { "-crterase", 0, 0, 0, 0, 0, 0, 0, ECHOE }, { "echok", 0, 0, 0, 0, 0, 0, ECHOK, 0 }, { "-echok", 0, 0, 0, 0, 0, 0, 0, ECHOK }, { "lfkc", 0, 0, 0, 0, 0, 0, ECHOK, 0 }, { "-lfkc", 0, 0, 0, 0, 0, 0, 0, ECHOK }, { "echonl", 0, 0, 0, 0, 0, 0, ECHONL, 0 }, { "-echonl", 0, 0, 0, 0, 0, 0, 0, ECHONL }, { "noflsh", 0, 0, 0, 0, 0, 0, NOFLSH, 0 }, { "-noflsh", 0, 0, 0, 0, 0, 0, 0, NOFLSH }, { "tostop", 0, 0, 0, 0, 0, 0, TOSTOP, 0 }, { "-tostop", 0, 0, 0, 0, 0, 0, 0, TOSTOP }, #ifdef ECHOCTL { "echoctl", 0, 0, 0, 0, 0, 0, ECHOCTL, 0 }, { "-echoctl", 0, 0, 0, 0, 0, 0, 0, ECHOCTL }, { "ctlecho", 0, 0, 0, 0, 0, 0, ECHOCTL, 0 }, { "-ctlecho", 0, 0, 0, 0, 0, 0, 0, ECHOCTL }, #endif #ifdef ECHOPRT { "echoprt", 0, 0, 0, 0, 0, 0, ECHOPRT, 0 }, { "-echoprt", 0, 0, 0, 0, 0, 0, 0, ECHOPRT }, { "prterase", 0, 0, 0, 0, 0, 0, ECHOPRT, 0 }, { "-prterase", 0, 0, 0, 0, 0, 0, 0, ECHOPRT }, #endif #ifdef ECHOKE { "echoke", 0, 0, 0, 0, 0, 0, ECHOKE, 0 }, { "-echoke", 0, 0, 0, 0, 0, 0, 0, ECHOKE }, { "crtkill", 0, 0, 0, 0, 0, 0, ECHOKE, 0 }, { "-crtkill", 0, 0, 0, 0, 0, 0, 0, ECHOKE }, #endif /* convenience modes */ { "lcase", IUCLC, 0, OLCUC, 0, 0, 0, XCASE, 0 }, { "-lcase", 0, IUCLC, 0, OLCUC, 0, 0, 0, XCASE }, { "nl", 0, ICRNL, 0, ONLCR, 0, 0, 0, 0 }, { "-nl", ICRNL, INLCR | IGNCR, ONLCR, OCRNL | ONLRET, 0, 0, 0, 0 }, { "litout", 0, 0, OPOST, 0, CS8, CSIZE | PARENB, 0, 0 }, { "-litout", 0, 0, 0, OPOST, CS7 | PARENB, CSIZE, 0, 0 }, { "pass8", 0, ISTRIP, 0, 0, CS8, CSIZE | PARENB, 0, 0 }, { "-pass8", ISTRIP, 0, 0, 0, CS7 | PARENB, CSIZE, 0, 0 }, { "raw", 0, -1, 0, OPOST, CS8, CSIZE | PARENB, 0, ISIG | ICANON | XCASE, }, #ifdef IMAXBEL { "-raw", BRKINT | IGNPAR | ISTRIP | ICRNL | IXON | IMAXBEL, 0, OPOST, 0, CS7 | PARENB, CSIZE, ISIG | ICANON, 0 }, { "sane", BRKINT | IGNPAR | ISTRIP | ICRNL | IXON | IMAXBEL, IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF, OPOST | ONLCR, OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL | NLDLY | CRDLY| TABDLY | BSDLY | VTDLY | FFDLY, CS7 | PARENB | CREAD, CSIZE | PARODD | CLOCAL, ISIG | ICANON | ECHO | ECHOK, XCASE | ECHOE | ECHONL | NOFLSH}, #endif /* IMAXBEL */ { "cooked", BRKINT | IGNPAR | ISTRIP | ICRNL | IXON, 0, OPOST, 0, CS7 | PARENB, CSIZE, ISIG | ICANON, 0 }, {0}, }; void Do_stty( int fd ) { int i, count; char *arg; struct line_list l; Init_line_list(&l); Split(&l,Stty_command_DYN,Whitespace,0,0,0,0,0,0); Check_max(&l,1); l.list[l.count] = 0; DEBUG3("Do_stty: using TERMIO, fd %d", fd ); if( ioctl( fd, TCGETA, &tio) < 0) { logerr_die(LOG_INFO, "cannot get tty parameters"); } DEBUG2("stty: before imode 0x%x, omode 0x%x, cmode 0x%x, lmode 0x%x", tio.c_iflag, tio.c_oflag, tio.c_cflag, tio.c_lflag); if( Baud_rate_DYN ){ for( i = 0; bauds[i].baud && Baud_rate_DYN != bauds[i].baud; i++); if( i == 0) { fatal(LOG_INFO, "illegal baud rate %d", Baud_rate_DYN); } tio.c_cflag &= ~CBAUD; tio.c_cflag |= bauds[i].speed; } for( count = 0; count < l.count; ++count ){ arg = l.list[count]; for( i = 0; tmodes[i].string && safestrcasecmp( tmodes[i].string, arg); i++); if( tmodes[i].string) { DEBUG3("stty: modes %s, ic 0x%x is 0x%x oc 0x%x os 0x%x cc 0x%x cs 0x%x lc 0x%x ls 0x%x", tmodes[i].string, tmodes[i].ireset, tmodes[i].iset, tmodes[i].oreset, tmodes[i].oset, tmodes[i].creset, tmodes[i].cset, tmodes[i].lreset, tmodes[i].lset); tio.c_iflag &= ~tmodes[i].ireset; tio.c_iflag |= tmodes[i].iset; tio.c_oflag &= ~tmodes[i].oreset; tio.c_oflag |= tmodes[i].oset; tio.c_cflag &= ~tmodes[i].creset; tio.c_cflag |= tmodes[i].cset; tio.c_lflag &= ~tmodes[i].lreset; tio.c_lflag |= tmodes[i].lset; continue; } for( i = 0; bauds[i].string && safestrcasecmp( bauds[i].string, arg); i++); if( bauds[i].string) { DEBUG3("stty: speed %s", arg); tio.c_cflag &= ~CBAUD; tio.c_cflag |= bauds[i].speed; continue; } fatal(LOG_INFO, "unknown mode: %s\n", arg); } if( Read_write_DYN && (tio.c_cflag & ICANON) == 0) { /* VMIN & VTIME: suggested by Michael Joosten * only do this if ICANON is off -- Martin Forssen */ DEBUG2("setting port to read/write with unbuffered reads"); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; } DEBUG2("stty: before imode 0x%x, omode 0x%x, cmode 0x%x, lmode 0x%x", tio.c_iflag, tio.c_oflag, tio.c_cflag, tio.c_lflag); if( ioctl( fd, TCSETA, &tio) < 0) { logerr_die(LOG_NOTICE, "cannot set tty parameters"); } Free_line_list(&l); } #endif #if USE_STTY == TERMIOS #ifndef HAVE_TCSETATTR #define tcgetattr(fd,tdat) (ioctl( (fd), TCGETS, (tdat))) #define tcsetattr(fd,flags,tdat) (ioctl( (fd), TCSETS, (tdat))) /* ignore the flags arg. */ #endif static struct bauds { const char *string; int baud; int speed; } bauds[] = { { "B50", 50, B50, }, { "50", 50, B50, }, { "B75", 75, B75, }, { "75", 75, B75, }, { "B110", 110, B110, }, { "110", 110, B110, }, { "B134", 134, B134, }, { "134", 134, B134, }, { "B150", 150, B150, }, { "150", 150, B150, }, { "B300", 300, B300, }, { "300", 300, B300, }, { "B600", 600, B600, }, { "600", 600, B600, }, { "B1200", 1200, B1200, }, { "1200", 1200, B1200, }, { "B1800", 1800, B1800, }, { "1800", 1800, B1800, }, { "B2400", 2400, B2400, }, { "2400", 2400, B2400, }, { "B4800", 4800, B4800, }, { "4800", 4800, B4800, }, { "B9600", 9600, B9600, }, { "9600", 9600, B9600, }, { "B19200", 19200, B19200, }, { "19200", 19200, B19200, }, { "B38400", 38400, B38400, }, { "38400", 38400, B38400, }, #ifdef EXTA {"EXTA", EXTA, EXTA}, {"EXTB", EXTB, EXTB}, #endif #if defined(B57600) { "57600", 57600, B57600, }, { "B57600", 57600, B57600, }, #endif #if defined(B115200) { "115200", 115200, B115200, }, { "B115200", 115200, B115200, }, #endif #if defined(B230400) { "230400", 230400, B230400, }, { "B230400", 230400, B230400, }, #endif #if defined(B460800) { "460800", 460800, B460800, }, { "B460800", 460800, B460800, }, #endif #if defined(B500000) { "500000", 500000, B500000, }, { "B500000", 500000, B500000, }, #endif #if defined(B576000) { "576000", 576000, B576000, }, { "B576000", 576000, B576000, }, #endif #if defined(B921600) { "921600", 921600, B921600, }, { "B921600", 921600, B921600, }, #endif { (char *) 0, 0, 0 } }; struct s_term_dat { const char *name; unsigned int or_dat; unsigned int and_dat; }; #undef FLAGS #ifndef _UNPROTO_ #define FLAGS(X) { #X, X , 0 }, { "-" #X, 0, X } #else #define __string(X) "X" #define FLAGS(X) { __string(X), X , 0 }, { "-" __string(X), 0, X } #endif /* c_iflag bits */ static struct s_term_dat c_i_dat[] = { FLAGS(IGNBRK), FLAGS(BRKINT), FLAGS(IGNPAR), FLAGS(PARMRK), FLAGS(INPCK), FLAGS(ISTRIP), FLAGS(INLCR), FLAGS(IGNCR), FLAGS(ICRNL), #ifdef IUCLC FLAGS(IUCLC), {"lcase", IUCLC, 0}, {"-lcase", 0, IUCLC }, #endif FLAGS(IXON), FLAGS(IXANY), FLAGS(IXOFF), #ifdef IMAXBEL FLAGS(IMAXBEL), #else /* work out what they do and simulate with IFLAGONE|IFLAGTWO */ #endif /* jmason addition: */ {"PASS8", 0, ISTRIP}, {"-PASS8", ISTRIP, 0}, {0, 0, 0} }; /* c_oflag bits */ static struct s_term_dat c_o_dat[] = { FLAGS(OPOST), #ifdef OLCUC FLAGS(OLCUC), #endif #ifdef ONLCR FLAGS(ONLCR), {"crmod", ONLCR, 0}, {"-crmod", 0, ONLCR}, #endif #ifdef OCRNL FLAGS(OCRNL), #endif #ifdef ONOCR FLAGS(ONOCR), #endif #ifdef ONLRET FLAGS(ONLRET), #endif #ifdef OFILL FLAGS(OFILL), #endif #ifdef OFDEL FLAGS(OFDEL), #endif #ifdef NLDLY {"NL0", 0, NLDLY}, {"NL1", NL1, NLDLY}, #endif #ifdef CRDLY {"CR0", CR0, CRDLY}, {"CR1", CR1, CRDLY}, {"CR2", CR2, CRDLY}, {"CR3", CR3, CRDLY}, #endif #ifdef TABDLY {"TAB0", TAB0, TABDLY}, #ifdef TAB1 {"TAB1", TAB1, TABDLY}, #endif #ifdef TAB2 {"TAB2", TAB2, TABDLY}, #endif {"TAB3", TAB3, TABDLY}, #endif #ifdef BSDLY {"BS0", BS0, BSDLY}, {"BS1", BS1, BSDLY}, #endif #ifdef VTDLY {"VT0", VT0, VTDLY}, {"VT1", VT1, VTDLY}, #endif #ifdef FFDLY {"FF0", FF0, FFDLY}, {"FF1", FF1, FFDLY}, #endif /* jmason addition: */ #ifdef TABDLY {"TABS", TAB3, TABDLY}, #endif {0, 0, 0} }; /* c_cflag bit meaning */ static struct s_term_dat c_c_dat[] = { {"CS5", CS5, CSIZE}, {"CS6", CS6, CSIZE}, {"CS7", CS7, CSIZE}, {"CS8", CS8, CSIZE}, {"CSTOPB", CSTOPB, 0}, {"-CSTOPB", 0, CSTOPB}, {"CREAD", CREAD, 0}, {"-CREAD", 0, CREAD}, {"PARENB", PARENB, 0}, {"-PARENB", 0, PARENB}, {"PARODD", PARODD, 0}, {"-PARODD", 0, PARODD}, {"HUPCL", HUPCL, 0}, {"-HUPCL", 0, HUPCL}, {"CLOCAL", CLOCAL, 0}, {"-CLOCAL", 0, CLOCAL}, #ifdef CRTSCTS /* work out what they do and simulate with IFLAGONE|IFLAGTWO */ {"CRTSCTS", CRTSCTS, 0}, {"-CRTSCTS", 0, CRTSCTS}, #endif /* jmason additions, from SunOS stty(1v) combination modes: */ {"even", PARENB | CS7, PARODD | CSIZE}, {"-even", CS8, PARENB | CSIZE}, {"EVENP", PARENB | CS7, PARODD | CSIZE}, {"-EVENP", CS8, PARENB | CSIZE}, {"PARITY", PARENB | CS7, PARODD | CSIZE}, {"-PARITY", CS8, PARENB | CSIZE}, {"odd", PARODD| PARENB | CS7, CSIZE}, {"-odd", CS8, PARENB | PARODD | CSIZE}, {"ODDP", PARODD | PARENB | CS7, CSIZE}, {"-ODDP", CS8, PARENB | PARODD | CSIZE}, {"PASS8", CS8, PARENB | CSIZE}, {"-PASS8", PARENB | CS7, CSIZE}, {0, 0, 0} }; /* c_lflag bits */ static struct s_term_dat c_l_dat[] = { {"ISIG", ISIG, 0}, {"-ISIG", 0, ISIG}, {"cooked", ICANON, 0}, {"-raw", ICANON, 0}, {"cbreak", ICANON, 0}, {"ICANON", ICANON, 0}, {"-ICANON", 0, ICANON}, {"raw", 0, ICANON}, {"-cooked", 0, ICANON}, #ifdef XCASE {"XCASE", XCASE, 0}, {"-XCASE", 0, XCASE}, #endif {"ECHO", ECHO, 0}, {"-ECHO", 0, ECHO}, {"ECHOE", ECHOE, 0}, {"-ECHOE", 0, ECHOE}, {"ECHOK", ECHOK, 0}, {"-ECHOK", 0, ECHOK}, {"ECHONL", ECHONL, 0}, {"-ECHONL", 0, ECHONL}, {"NOFLSH", NOFLSH, 0}, {"-NOFLSH", 0, NOFLSH}, {"TOSTOP", TOSTOP, 0}, {"-TOSTOP", 0, TOSTOP}, {"IEXTEN", IEXTEN, 0}, {"-IEXTEN", 0, IEXTEN}, #ifdef ECHOCTL {"ECHOCTL", ECHOCTL, 0}, {"-ECHOCTL", 0, ECHOCTL}, {"CTLECHO", ECHOCTL, 0}, {"-CTLECHO", 0, ECHOCTL}, #else /* work out what they do and simulate with IFLAGONE|IFLAGTWO */ #endif #ifdef ECHOPRT {"ECHOPRT", ECHOPRT, 0}, {"-ECHOPRT", 0, ECHOPRT}, {"PRTERASE", ECHOPRT, 0}, {"-PRTERASE", 0, ECHOPRT}, /* ditto etc. -- you get the story */ #endif #ifdef ECHOKE {"ECHOKE", ECHOKE, 0}, {"-ECHOKE", 0, ECHOKE}, {"CRTKILL", ECHOKE, 0}, {"-CRTKILL", 0, ECHOKE}, #endif #ifdef FLUSHO {"FLUSHO", FLUSHO, 0}, {"-FLUSHO", 0, FLUSHO}, #endif #ifdef PENDIN {"PENDIN", PENDIN, 0}, {"-PENDIN", 0, PENDIN}, #endif { 0 ,0 ,0 } }; #ifdef USE_TERMIOX /* termiox bits */ static struct s_term_dat tx_x_dat[] = { {"RTSXOFF", RTSXOFF, 0}, {"-RTSXOFF", 0, RTSXOFF}, {"CTSXON", CTSXON, 0}, {"-CTSXON", 0, CTSXON} }; struct termiox tx_dat; #endif /* USE_TERMIOX */ struct termios t_dat; static struct special { const char *name; char *cp; } special[] = { { "stop", (char *)&(t_dat.c_cc[VSTOP]) }, { "start", (char *)&(t_dat.c_cc[VSTART]) }, { 0, 0 } }; void Do_stty( int fd ) { #ifdef USE_TERMIOX int termiox_fail = 0; #endif int i,count; char *arg, *option; struct line_list l; Init_line_list(&l); Split(&l,Stty_command_DYN,Whitespace,0,0,0,0,0,0); Check_max(&l,1); l.list[l.count] = 0; DEBUG3("Do_stty: using TERMIOS, fd %d", fd ); if( tcgetattr( fd, &t_dat) < 0 ){ logerr_die(LOG_INFO, "cannot get tty parameters"); } #ifdef USE_TERMIOX if( ioctl( fd, TCGETX, &tx_dat) < 0 ){ DEBUG1("stty: TCGETX failed"); termiox_fail = 1; } #endif DEBUG2("stty: before iflag 0x%x, oflag 0x%x, cflag 0x%x lflag 0x%x", (int)t_dat.c_iflag, (int)t_dat.c_oflag, (int)t_dat.c_cflag, (int)t_dat.c_lflag); if( Baud_rate_DYN ){ for( i = 0; bauds[i].baud && Baud_rate_DYN != bauds[i].baud; i++); if( i == 0 ){ fatal(LOG_INFO, "illegal baud rate %d", Baud_rate_DYN ); } DEBUG2("stty: before baudrate : cflag 0x%x",(int)t_dat.c_cflag); #ifdef HAVE_CFSETISPEED DEBUG2("Do_stty: using cfsetispeed/cfsetospeed"); /* POSIX baudrate manipulation */ cfsetispeed( &t_dat, bauds[i].speed); cfsetospeed( &t_dat, bauds[i].speed); #else DEBUG2("Do_stty: setting tdat.c_cflag"); t_dat.c_cflag &= ~CBAUD; t_dat.c_cflag |= bauds[i].speed; #endif DEBUG2("stty: after baudrate : cflag 0x%x",(int)t_dat.c_cflag); } for( count = 0; count < l.count; ++count ){ arg = l.list[count]; for( i = 0; bauds[i].string && safestrcasecmp( bauds[i].string, arg); i++); if( bauds[i].string ){ #ifdef HAVE_CFSETISPEED DEBUG2("Do_stty: using cfsetispeed/cfsetospeed"); /* POSIX baudrate manipulation */ cfsetispeed( &t_dat, bauds[i].speed); cfsetospeed( &t_dat, bauds[i].speed); #else DEBUG2("Do_stty: setting tdat.c_cflag"); t_dat.c_cflag &= ~CBAUD; t_dat.c_cflag |= bauds[i].speed; #endif continue; } for( i = 0; c_i_dat[i].name && safestrcasecmp( c_i_dat[i].name, arg); i++); if( c_i_dat[i].name ){ DEBUG3("stty: c_iflag %s, ms 0x%x mc 0x%x", c_i_dat[i].name, c_i_dat[i].or_dat, c_i_dat[i].and_dat); t_dat.c_iflag &= ~(c_i_dat[i].and_dat); t_dat.c_iflag |= c_i_dat[i].or_dat; continue; } for( i = 0; c_o_dat[i].name && safestrcasecmp( c_o_dat[i].name, arg); i++); if( c_o_dat[i].name ){ DEBUG3("stty: c_oflag %s, ms 0x%x mc 0x%x", c_o_dat[i].name, c_o_dat[i].or_dat, c_o_dat[i].and_dat); t_dat.c_oflag &= ~(c_o_dat[i].and_dat); t_dat.c_oflag |= c_o_dat[i].or_dat; continue; } for( i = 0; c_c_dat[i].name && safestrcasecmp( c_c_dat[i].name, arg); i++); if( c_c_dat[i].name ){ DEBUG3("stty: c_cflag %s, ms 0x%x mc 0x%x", c_c_dat[i].name, c_c_dat[i].or_dat, c_c_dat[i].and_dat); t_dat.c_cflag &= ~(c_c_dat[i].and_dat); t_dat.c_cflag |= c_c_dat[i].or_dat; continue; } for( i = 0; c_l_dat[i].name && safestrcasecmp( c_l_dat[i].name, arg); i++); if( c_l_dat[i].name ){ DEBUG3("stty: c_lflag %s, ms 0x%x mc 0x%x", c_l_dat[i].name, c_l_dat[i].or_dat, c_l_dat[i].and_dat); t_dat.c_lflag &= ~(c_l_dat[i].and_dat); t_dat.c_lflag |= c_l_dat[i].or_dat; continue; } for( i = 0; special[i].name && safestrcasecmp( special[i].name, arg); i++); if( special[i].name ){ ++count; option = l.list[count]; if( option == 0 ){ fatal(LOG_INFO, "stty: missing parameter for %s", arg); } if( option[0] == '^' ){ if( option[1] == '?' ){ *special[i].cp = 0177; } else { *special[i].cp = 037 & option[1]; } } else { *special[i].cp = option[0]; } DEBUG3("stty: special %s %s", arg, option); continue; } #ifdef USE_TERMIOX for( i = 0; tx_x_dat[i].name && safestrcasecmp( tx_x_dat[i].name, arg); i++); if( tx_x_dat[i].name ){ DEBUG3("stty: tx_xflag %s, ms 0x%x mc 0x%x", tx_x_dat[i].name, tx_x_dat[i].or_dat, tx_x_dat[i].and_dat); tx_dat.x_hflag &= ~(tx_x_dat[i].and_dat); tx_dat.x_hflag |= tx_x_dat[i].or_dat; continue; } #endif /* USE_TERMIOX */ fatal(LOG_INFO, "unknown mode: %s\n", arg); } if( Read_write_DYN && (t_dat.c_lflag & ICANON) == 0 ){ /* only do this if ICANON is off -- Martin Forssen */ DEBUG2("setting port to read/write with unbuffered reads( MIN=1, TIME=0)"); t_dat.c_cc[VMIN] = 1; t_dat.c_cc[VTIME] = 0; } DEBUG2("stty: after iflag 0x%x, oflag 0x%x, cflag 0x%x lflag 0x%x", (int)t_dat.c_iflag, (int)t_dat.c_oflag, (int)t_dat.c_cflag, (int)t_dat.c_lflag); if( tcsetattr( fd, TCSANOW, &t_dat) < 0 ){ logerr_die(LOG_NOTICE, "cannot set tty parameters"); } #ifdef USE_TERMIOX if( termiox_fail == 0 && ioctl( fd, TCSETX, &tx_dat) < 0 ){ logerr_die(LOG_NOTICE, "cannot set tty parameters (termiox)"); } #endif Free_line_list(&l); } #endif lprng-3.8.B/src/common/copyright.c0000644000131400013140000000173311531672131014036 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" /**** ENDINCLUDE ****/ const char *Copyright[] = { PACKAGE_NAME "-" PACKAGE_VERSION #if defined(KERBEROS) ", Kerberos5" #endif ", Copyright 1988-2003 Patrick Powell, ", "", "locking uses: " #ifdef HAVE_FCNTL "fcntl (preferred)" #else #ifdef HAVE_LOCKF "lockf" #else "flock (does NOT work over NFS)" #endif #endif , "stty uses: " #if USE_STTY == SGTTYB "sgttyb" #endif #if USE_STTY == TERMIO "termio" #endif #if USE_STTY == TERMIOS "termios" #endif , #ifdef SSL_ENABLE "with SSL" #else "without SSL" #endif , "", #include "license.h" #include "copyright.h" 0 }; lprng-3.8.B/src/common/lpd_logger.c0000644000131400013140000002475211531672131014152 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "child.h" #include "errorcodes.h" #include "fileopen.h" #include "getopt.h" #include "getprinter.h" #include "getqueue.h" #include "linksupport.h" #include "proctitle.h" #include "lpd_logger.h" #include "lpd_worker.h" /*************************************************************************** * Setup_logger() * * We will have a process that sits and listens for log data, and then * forwards it to the destination. This process will have some odd properities. * * 1. It will never update its destination. This means you will have to * kill the logger to get it to accept a new destination. ***************************************************************************/ static void Logger( struct line_list *, int ) NORETURN; /* * Start_logger - helper function to setup logger process */ pid_t Start_logger( int log_fd ) { struct line_list args; int fd = Logger_fd; pid_t pid; Init_line_list(&args); Set_str_value(&args,CALL,"logger"); Logger_fd = -1; pid = Start_worker( "logger", Logger, &args, log_fd); Logger_fd = fd; DEBUG1("Start_logger: log_fd %d, status_pid %d", log_fd, pid ); return(pid); } static int Dump_queue_status(int outfd) { int i, count, fd; char *s, *sp, *pr; struct line_list info; struct job job; char buffer[SMALLBUFFER]; /* char *esc_lf_2 = Escape("\n", 2); */ /* char *esc_lf_2 = "%25250a"; */ const char *esc_lf_1 = "%250a"; struct stat statb; s = sp = 0; Init_job(&job); Init_line_list(&info); if(All_line_list.count == 0 ){ Get_all_printcap_entries(); } DEBUGF(DLOG2)("Dump_queue_status: writing to fd %d", outfd ); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN,0); pr = All_line_list.list[i]; DEBUGF(DLOG2)("Dump_queue_status: checking '%s'", pr ); if( Setup_printer( pr, buffer, sizeof(buffer), 0 ) ) continue; Free_line_list( &Sort_order ); if( Scan_queue( &Spool_control, &Sort_order, 0,0,0,0,0,0,0,0 ) ){ continue; } Free_line_list(&info); Set_str_value(&info,PRINTER,Printer_DYN); Set_str_value(&info,HOST,FQDNHost_FQDN); Set_decimal_value(&info,PROCESS,getpid()); Set_str_value(&info,UPDATE_TIME,Time_str(0,0)); if( Write_fd_str( outfd, "DUMP=" ) < 0 ){ return(1); } s = Join_line_list(&info,"\n"); sp = Escape(s, 1); if( Write_fd_str( outfd, sp ) < 0 ){ return(1); } if( s ) free(s); s = 0; if( sp ) free(sp); sp = 0; if( Write_fd_str( outfd, "VALUE=" ) < 0 ){ return(1); } if( Write_fd_str( outfd, "QUEUE%3d" ) < 0 ){ return(1); } if( (fd = Checkread( Queue_control_file_DYN, &statb )) > 0 ){ while( (count = ok_read(fd, buffer, sizeof(buffer)-1)) > 0 ){ buffer[count] = 0; s = Escape(buffer,3); if( Write_fd_str( outfd, s ) < 0 ){ return(1); } if(s) free(s); s = 0; } close(fd); } if( Write_fd_str( outfd, esc_lf_1 ) < 0 ){ return(1); } if( Write_fd_str( outfd, "PRSTATUS%3d" ) < 0 ){ return(1); } if( (fd = Checkread( Queue_status_file_DYN, &statb )) > 0 ){ while( (count = ok_read(fd, buffer, sizeof(buffer)-1)) > 0 ){ buffer[count] = 0; s = Escape(buffer,3); if( Write_fd_str( outfd, s ) < 0 ){ return(1); } if(s) free(s); s = 0; } close(fd); } if( Write_fd_str( outfd, esc_lf_1 ) < 0 ){ return(1); } for( count = 0; count < Sort_order.count; ++count ){ Free_job(&job); Get_job_ticket_file( 0, &job, Sort_order.list[count] ); if( job.info.count == 0 ) continue; if( Write_fd_str( outfd, "UPDATE%3d" ) < 0 ){ return(1); } s = Join_line_list(&job.info,"\n"); sp = Escape(s, 3); if( Write_fd_str( outfd, sp ) < 0 ){ return(1); } if( s ) free(s); s = 0; if( sp ) free(sp); sp = 0; if( Write_fd_str( outfd, esc_lf_1 ) < 0 ){ return(1); } } if( Write_fd_str( outfd, "\n" ) < 0 ){ return(1); } } if( Write_fd_str( outfd, "END\n" ) < 0 ){ return(1); } Set_DYN(&Printer_DYN,0); Free_line_list( &Sort_order ); Free_line_list(&info); Free_job(&job); if( s ) free(s); s = 0; if( sp ) free(sp); sp = 0; return(0); } static void Logger( struct line_list *args, int readfd ) { char *s, *path, *tempfile; int writefd,m, timeout; time_t start_time, current_time; int elapsed, left, err; struct timeval timeval, *tp; fd_set readfds, writefds; /* for select() */ char inbuffer[LARGEBUFFER]; char outbuffer[LARGEBUFFER]; int outlen = 0, input_read = 0; char host[SMALLBUFFER], errmsg[SMALLBUFFER]; int status_fd = -1; int input_fd = -1; struct stat statb; int errlen = sizeof(errmsg); Errorcode = JABORT; Name = "LOG2"; setproctitle( "lpd %s", Name ); DEBUGFC(DLOG2)Dump_line_list("Logger - args", args ); timeout = Logger_timeout_DYN; path = Logger_path_DYN; /* we copy to a local buffer */ host[0] = 0; safestrncpy(host, Logger_destination_DYN ); /* OK, we try to open a connection to the logger */ if( !(s = safestrchr( host, '%')) ){ int len = strlen(host); plp_snprintf(host+len, sizeof(host)-len, "%%2001" ); } Free_line_list(args); writefd = -2; /* now we set up the IO file */ Set_nonblock_io(readfd); DEBUGF(DLOG2)("Logger: host '%s'", host ); time( &start_time ); status_fd = Make_temp_fd( &tempfile ); input_fd = Checkread( tempfile, &statb ); unlink(tempfile); while( 1 ){ tp = 0; left = 0; /* try to see if more output is left */ if( outlen == 0 && input_read ){ if( (m = ok_read( input_fd, inbuffer, sizeof(inbuffer)-1 )) > 0 ){ inbuffer[m] = 0; memcpy( outbuffer, inbuffer, m+1 ); outlen = m; DEBUGF(DLOG2)("Logger: queue status '%s'", outbuffer ); } else if( m < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: read error %s", tempfile); } if( m < (int)sizeof(inbuffer)-1 ){ /* we can truncate the files */ if( lseek( status_fd, 0, SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: lseek failed write file '%s'", tempfile); } if( lseek( input_fd, 0, SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: lseek failed read file '%s'", tempfile); } if( ftruncate( status_fd, 0 ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: ftruncate failed file '%s'", tempfile); } input_read = 0; } } /* now lets see if the input has been closed * do not exit until you have sent last buffer information */ if( readfd < 0 && outlen == 0 ){ DEBUGF(DLOG2)("Logger: exiting - no work to do"); Errorcode = 0; break; } /* the destination is not on line yet * try to reopen */ if( writefd < 0 ){ time( ¤t_time ); elapsed = current_time - start_time; left = timeout - elapsed; DEBUGF(DLOG2)("Logger: writefd fd %d, max timeout %d, left %d", writefd, timeout, left ); if( left <= 0 || writefd == -2 ){ writefd = Link_open(host, Connect_timeout_DYN, 0, 0, errmsg, errlen ); DEBUGF(DLOG2)("Logger: open fd %d", writefd ); if( writefd >= 0 ){ Set_nonblock_io( writefd ); if( lseek( status_fd, 0, SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: lseek failed write file '%s'", tempfile); } if( lseek( input_fd, 0, SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: lseek failed read file '%s'", tempfile); } if( ftruncate( status_fd, 0 ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: ftruncate failed file '%s'", tempfile); } if( Dump_queue_status(status_fd) ){ DEBUGF(DLOG2)("Logger: Dump_queue_status failed - %s", Errormsg(errno) ); Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: cannot write file '%s'", tempfile); } input_read = 1; /* we try again */ continue; } else { writefd = -1; } time( &start_time ); time( ¤t_time ); DEBUGF(DLOG2)("Logger: writefd now fd %d", writefd ); } if( writefd < 0 && timeout > 0 ){ memset( &timeval, 0, sizeof(timeval) ); elapsed = current_time - start_time; left = timeout - elapsed; timeval.tv_sec = left; tp = &timeval; DEBUGF(DLOG2)("Logger: timeout now %d", left ); } } FD_ZERO( &writefds ); FD_ZERO( &readfds ); m = 0; if( writefd >= 0 ){ if( outlen ){ FD_SET( writefd, &writefds ); if( m <= writefd ) m = writefd+1; } FD_SET( writefd, &readfds ); if( m <= writefd ) m = writefd+1; } if( readfd >= 0 ){ FD_SET( readfd, &readfds ); if( m <= readfd ) m = readfd+1; } errno = 0; DEBUGF(DLOG2)("Logger: starting select, timeout '%s', left %d", tp?"yes":"no", left ); m = select( m, &readfds, &writefds, NULL, tp ); err = errno; DEBUGF(DLOG2)("Logger: select returned %d, errno '%s'", m, Errormsg(err) ); if( m < 0 ){ if( err != EINTR ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: select error"); } } else if( m > 0 ){ if( writefd >=0 && FD_ISSET( writefd, &readfds ) ){ /* we have EOF on the file descriptor */ DEBUGF(DLOG2)("Logger: eof on writefd fd %d", writefd ); close( writefd ); outlen = 0; writefd = -2; } if( readfd >=0 && FD_ISSET( readfd, &readfds ) ){ DEBUGF(DLOG2)("Logger: read possible on fd %d", readfd ); inbuffer[0] = 0; m = ok_read( readfd, inbuffer, sizeof(inbuffer)-1 ); if( m >= 0) inbuffer[m] = 0; DEBUGF(DLOG2)("Logger: read count %d '%s'", m, inbuffer ); if( m > 0 && writefd >= 0 ){ if( Write_fd_len( status_fd, inbuffer, m ) ){ logerr_die(LOG_INFO, "Logger: write error on tempfile fd %d", status_fd); } input_read = 1; } else if( m == 0 ) { /* we have a 0 length read - this is EOF */ Errorcode = 0; DEBUGF(DLOG1)("Logger: eof on input fd %d", readfd); close(readfd); readfd = -1; } else if( m < 0 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Logger: read error on input fd %d", readfd); } } if( writefd >=0 && FD_ISSET( writefd, &writefds ) && outlen ){ DEBUGF(DLOG2)("Logger: write possible on fd %d, outlen %d", writefd, outlen ); m = write( writefd, outbuffer, outlen); DEBUGF(DLOG2)("Logger: last write %d", m ); if( m < 0 ){ /* we have EOF on the file descriptor */ logerr(LOG_INFO, "Logger: error writing on writefd fd %d", writefd ); close( writefd ); writefd = -2; } else if( m > 0 ){ memmove(outbuffer, outbuffer+m, outlen-m+1 ); outlen -= m; } } } } cleanup(0); } lprng-3.8.B/src/common/errormsg.c0000644000131400013140000005002211531672131013661 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "errormsg.h" #include "errorcodes.h" #include "child.h" #include "getopt.h" #include "getqueue.h" /**** ENDINCLUDE ****/ #if defined(HAVE_SYSLOG_H) # include #endif /****************************************************************************/ static void use_syslog( int kind, char *msg ); /**************************************************************************** * char *Errormsg( int err ) * returns a printable form of the * errormessage corresponding to the valie of err. * This is the poor man's version of sperror(), not available on all systems * Patrick Powell Tue Apr 11 08:05:05 PDT 1995 ****************************************************************************/ /****************************************************************************/ #ifndef HAVE_STRERROR const char * Errormsg ( int err ) { if( err == 0 ){ return "No Error"; } else { static char msgbuf[32]; /* holds "errno=%d". */ (void) plp_snprintf(msgbuf, sizeof(msgbuf), "errno=%d", err); return msgbuf; } } #endif struct msgkind { int var; const char *str; }; static struct msgkind msg_name[] = { {LOG_CRIT, " (CRIT)"}, {LOG_ERR, " (ERR)"}, {LOG_WARNING, " (WARN)"}, {LOG_NOTICE, " (NOTICE)"}, {LOG_INFO, " (INFO)"}, {LOG_DEBUG, ""}, {0,0} }; static const char * putlogmsg(int kind) { int i; static char b[32]; b[0] = 0; if( kind < 0 ) return(b); for (i = 0; msg_name[i].str; ++i) { if ( msg_name[i].var == kind) { return (msg_name[i].str); } } /* SAFE USE of SNPRINTF */ (void) plp_snprintf(b, sizeof(b), "", kind); return (b); } static void use_syslog(int kind, char *msg) { /* testing mode indicates that this is not being used * in the "real world", so don't get noisy. */ /* we get rid of first set of problems - stupid characters */ char buffer[SMALLBUFFER]; plp_snprintf(buffer,sizeof(buffer)-1, "%s",msg); msg = buffer; #ifndef HAVE_SYSLOG_H /* Note: some people would open "/dev/console", as default Bad programmer, BAD! You should parameterize this and set it up as a default value. This greatly aids in testing for portability. Patrick Powell Tue Apr 11 08:07:47 PDT 1995 */ int Syslog_fd; if (Syslog_fd = open( Syslog_device_DYN, O_WRONLY|O_APPEND|O_NOCTTY, Spool_file_perms_DYN )) > 0 ) ){ int len; Max_open( Syslog_fd); len = safestrlen(msg); msg[len] = '\n'; msg[len+1] = 0; Write_fd_len( Syslog_fd, msg, len+1 ); close( Syslog_fd ); msg[len] = 0; } #else /* HAVE_SYSLOG_H */ # ifdef HAVE_OPENLOG /* use the openlog facility */ openlog(Name, LOG_PID | LOG_NOWAIT, SYSLOG_FACILITY ); syslog(kind, "%s", msg); closelog(); # else (void) syslog(SYSLOG_FACILITY | kind, "%s", msg); # endif /* HAVE_OPENLOG */ #endif /* HAVE_SYSLOG_H */ } static void log_backend (int kind, char *log_buf) { char stamp_buf[2*SMALLBUFFER]; int n; char *s; /* plp_block_mask omask; / **/ int err = errno; /* plp_block_all_signals (&omask); / **/ /* put the error message into the status file as well */ /* * Now build up the state info: timestamp, hostname, argv[0], pid, etc. * Don't worry about efficiency here -- it shouldn't happen very often * (unless we're debugging). */ stamp_buf[0] = 0; /* remove trailing \n */ if( (s = strrchr(log_buf, '\n')) && cval(s+1) == 0 ){ *s = 0; } if( Is_server || DEBUGL1 ){ /* log stuff */ if( (LOG_EMERG < LOG_INFO && kind <= LOG_INFO ) || ( LOG_EMERG > LOG_INFO && kind >= LOG_INFO )){ setstatus( 0, "%s", log_buf ); use_syslog(kind, log_buf); } n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf( s, n, "%s", Time_str(0,0) ); if (ShortHost_FQDN ) { n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf( s, n, " %s", ShortHost_FQDN ); } if(Debug || DbgFlag){ n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf(s, n, " [%ld]", (long)getpid()); n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; if(Name) (void) plp_snprintf(s, n, " %s", Name); n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf(s, n, " %s", putlogmsg(kind) ); } n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf(s, n, " %s", log_buf ); } else { (void) plp_snprintf(stamp_buf, sizeof(stamp_buf), "%s", log_buf ); } if( safestrlen(stamp_buf) > (int)sizeof(stamp_buf) - 8 ){ stamp_buf[sizeof(stamp_buf)-8] = 0; strcpy(stamp_buf+safestrlen(stamp_buf),"..."); } n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n; (void) plp_snprintf(s, n, "\n" ); /* use writes here: on HP/UX, using f p rintf really screws up. */ /* if stdout or stderr is dead, you have big problems! */ Write_fd_str( 2, stamp_buf ); /* plp_unblock_all_signals ( &omask ); / **/ errno = err; } /***************************************************** * Put the printer name at the start of the log buffer *****************************************************/ static void prefix_printer( char *log_buf, int len ) { log_buf[0] = 0; if( Printer_DYN ){ plp_snprintf( log_buf, len-4, "%s: ", Printer_DYN ); } } /* VARARGS2 */ #ifdef HAVE_STDARGS void logmsg(int kind, const char *msg,...) #else void logmsg(va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int kind; char *msg; #endif int n; char *s; int err = errno; static int in_log; char log_buf[SMALLBUFFER]; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (kind, int); VA_SHIFT (msg, char *); if( in_log == 0 ){ ++in_log; prefix_printer(log_buf, sizeof(log_buf)); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n-4; (void) plp_vsnprintf(s, n, msg, ap); log_backend (kind,log_buf); in_log = 0; } VA_END; errno = err; } /* VARARGS2 */ #ifdef HAVE_STDARGS void fatal (int kind, const char *msg,...) #else void fatal (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int kind; char *msg; #endif int n; char *s; char log_buf[SMALLBUFFER]; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (kind, int); VA_SHIFT (msg, char *); if( in_log == 0 ){ ++in_log; prefix_printer(log_buf, sizeof(log_buf)); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n-4; (void) plp_vsnprintf(s, n, msg, ap); log_backend (kind, log_buf); in_log = 0; } VA_END; cleanup(0); } /* VARARGS2 */ #ifdef HAVE_STDARGS void logerr (int kind, const char *msg,...) #else void logerr (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int kind; char *msg; #endif int err = errno; char log_buf[SMALLBUFFER]; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (kind, int); VA_SHIFT (msg, char *); if( in_log == 0 ){ int n; char *s; ++in_log; prefix_printer(log_buf, sizeof(log_buf)-4); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n-4; (void) plp_vsnprintf(s, n, msg, ap); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n-4; if( err ) (void) plp_snprintf(s, n, " - %s", Errormsg (err)); log_backend (kind, log_buf); in_log = 0; } VA_END; errno = err; } /* VARARGS2 */ #ifdef HAVE_STDARGS void logerr_die (int kind, const char *msg,...) #else void logerr_die (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int kind; char *msg; #endif int err = errno; char log_buf[SMALLBUFFER]; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (kind, int); VA_SHIFT (msg, char *); if( in_log == 0 ){ int n; char *s; ++in_log; prefix_printer(log_buf, sizeof(log_buf)); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n; (void) plp_vsnprintf(s, n, msg, ap); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n; if( err ) (void) plp_snprintf(s, n, " (errno %d)", err); if( err ) (void) plp_snprintf(s, n, " - %s", Errormsg (err)); log_backend (kind, log_buf); in_log = 0; } cleanup(0); VA_END; } /*************************************************************************** * Diemsg( char *m1, *m2, ...) * print error message to stderr, and die ***************************************************************************/ /* VARARGS1 */ #ifdef HAVE_STDARGS void Diemsg (const char *msg,...) #else void Diemsg (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif char buffer[SMALLBUFFER]; char *s; int n; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (msg, char *); if( in_log == 0 ){ ++in_log; buffer[0] = 0; n = safestrlen(buffer); s = buffer + n; n = sizeof(buffer) - n; (void) plp_snprintf(s, n, "Fatal error - "); n = safestrlen(buffer); s = buffer + n; n = sizeof(buffer) - n; (void) plp_vsnprintf(s, n, msg, ap); n = safestrlen(buffer); s = buffer + n; n = sizeof(buffer) - n; (void) plp_snprintf(s, n, "\n" ); /* ignore error, we are dying anyways */ Write_fd_str( 2, buffer ); in_log = 0; } cleanup(0); VA_END; } /*************************************************************************** * Warnmsg( char *m1, *m2, ...) * print warning message to stderr ***************************************************************************/ /* VARARGS1 */ #ifdef HAVE_STDARGS void Warnmsg (const char *msg,...) #else void Warnmsg (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif char buffer[SMALLBUFFER]; char *s = buffer; int n; int err = errno; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (msg, char *); if( in_log ) return; ++in_log; buffer[0] = 0; n = safestrlen(buffer); s = buffer+n; n = sizeof(buffer)-n; (void) plp_snprintf(s, n, "Warning - "); n = safestrlen(buffer); s = buffer+n; n = sizeof(buffer)-n; (void) plp_vsnprintf(s, n, msg, ap); n = safestrlen(buffer); s = buffer+n; n = sizeof(buffer)-n; (void) plp_snprintf(s, n, "\n"); Write_fd_str( 2, buffer ); in_log = 0; errno = err; VA_END; } /*************************************************************************** * Message( char *m1, *m2, ...) * print warning message to stderr ***************************************************************************/ /* VARARGS1 */ #ifdef HAVE_STDARGS void Message (const char *msg,...) #else void Message (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif char buffer[SMALLBUFFER]; char *s = buffer; int n; int err = errno; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (msg, char *); if( in_log ) return; ++in_log; buffer[0] = 0; n = safestrlen(buffer); s = buffer+n; n = sizeof(buffer)-n; (void) plp_vsnprintf(s, n, msg, ap); n = safestrlen(buffer); s = buffer+n; n = sizeof(buffer)-n; (void) plp_snprintf(s, n, "\n"); Write_fd_str( 2, buffer ); in_log = 0; errno = err; VA_END; } /* VARARGS1 */ #ifdef HAVE_STDARGS void logDebug (const char *msg,...) #else void logDebug (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif int err = errno; char log_buf[SMALLBUFFER]; static int in_log; VA_LOCAL_DECL VA_START (msg); VA_SHIFT (msg, char *); if( in_log == 0 ){ int n; char *s; ++in_log; prefix_printer(log_buf, sizeof(log_buf)); n = safestrlen(log_buf); s = log_buf+n; n = sizeof(log_buf)-n; (void) plp_vsnprintf(s, n, msg, ap); log_backend(LOG_DEBUG, log_buf); in_log = 0; } errno = err; VA_END; } /*************************************************************************** * char *Sigstr(n) * Return a printable form the the signal ***************************************************************************/ struct signame { const char *str; int value; }; #undef PAIR #ifndef _UNPROTO_ # define PAIR(X) { #X , X } #else # define __string(X) "X" # define PAIR(X) { __string(X) , X } #endif struct signame signals[] = { { "NO SIGNAL", 0 }, #ifdef SIGHUP PAIR(SIGHUP), #endif #ifdef SIGINT PAIR(SIGINT), #endif #ifdef SIGQUIT PAIR(SIGQUIT), #endif #ifdef SIGILL PAIR(SIGILL), #endif #ifdef SIGTRAP PAIR(SIGTRAP), #endif #ifdef SIGIOT PAIR(SIGIOT), #endif #ifdef SIGABRT PAIR(SIGABRT), #endif #ifdef SIGEMT PAIR(SIGEMT), #endif #ifdef SIGFPE PAIR(SIGFPE), #endif #ifdef SIGKILL PAIR(SIGKILL), #endif #ifdef SIGBUS PAIR(SIGBUS), #endif #ifdef SIGSEGV PAIR(SIGSEGV), #endif #ifdef SIGSYS PAIR(SIGSYS), #endif #ifdef SIGPIPE PAIR(SIGPIPE), #endif #ifdef SIGALRM PAIR(SIGALRM), #endif #ifdef SIGTERM PAIR(SIGTERM), #endif #ifdef SIGURG PAIR(SIGURG), #endif #ifdef SIGSTOP PAIR(SIGSTOP), #endif #ifdef SIGTSTP PAIR(SIGTSTP), #endif #ifdef SIGCONT PAIR(SIGCONT), #endif #ifdef SIGCHLD PAIR(SIGCHLD), #endif #ifdef SIGCLD PAIR(SIGCLD), #endif #ifdef SIGTTIN PAIR(SIGTTIN), #endif #ifdef SIGTTOU PAIR(SIGTTOU), #endif #ifdef SIGIO PAIR(SIGIO), #endif #ifdef SIGPOLL PAIR(SIGPOLL), #endif #ifdef SIGXCPU PAIR(SIGXCPU), #endif #ifdef SIGXFSZ PAIR(SIGXFSZ), #endif #ifdef SIGVTALRM PAIR(SIGVTALRM), #endif #ifdef SIGPROF PAIR(SIGPROF), #endif #ifdef SIGWINCH PAIR(SIGWINCH), #endif #ifdef SIGLOST PAIR(SIGLOST), #endif #ifdef SIGUSR1 PAIR(SIGUSR1), #endif #ifdef SIGUSR2 PAIR(SIGUSR2), #endif {0,0} /* that's all */ }; #ifndef NSIG # define NSIG 32 #endif const char *Sigstr (int n) { static char buf[40]; const char *s = 0; if( n == 0 ){ return( "No signal"); } if (n < NSIG && n >= 0) { #if defined(HAVE_SYS_SIGLIST) # if !defined(HAVE_SYS_SIGLIST_DEF) extern const char *sys_siglist[]; # endif s = sys_siglist[n]; #else # if defined(HAVE__SYS_SIGLIST) # if !defined(HAVE__SYS_SIGLIST_DEF) extern const char *_sys_siglist[]; # endif s = _sys_siglist[n]; # else int i; for( i = 0; signals[i].str && signals[i].value != n; ++i ); s = signals[i].str; # endif #endif } if( s == 0 ){ s = buf; (void) plp_snprintf(buf, sizeof(buf), "signal %d", n); } return(s); } /*************************************************************************** * Decode_status (plp_status_t *status) * returns a printable string encoding return status ***************************************************************************/ const char *Decode_status (plp_status_t *status) { static char msg[LINEBUFFER]; int n; *msg = 0; /* just in case! */ if (WIFEXITED (*status)) { n = WEXITSTATUS(*status); if( n > 0 && n < 32 ) n += JFAIL-1; (void) plp_snprintf(msg, sizeof(msg), "exit status %d (%s)", WEXITSTATUS(*status), Server_status(n) ); } else if (WIFSTOPPED (*status)) { (void) strcpy(msg, "stopped"); } else { (void) plp_snprintf(msg, sizeof(msg), "died%s", WCOREDUMP (*status) ? " and dumped core" : ""); if (WTERMSIG (*status)) { (void) plp_snprintf(msg + safestrlen (msg), sizeof(msg)-safestrlen(msg), ", %s", Sigstr ((int) WTERMSIG (*status))); } } return (msg); } /*************************************************************************** * char *Server_status( int d ) * translate the server status; ***************************************************************************/ static struct signame statname[] = { PAIR(JSUCC), PAIR(JFAIL), PAIR(JABORT), PAIR(JREMOVE), PAIR(JHOLD), PAIR(JNOSPOOL), PAIR(JNOPRINT), PAIR(JSIGNAL), PAIR(JFAILNORETRY), PAIR(JSUSP), PAIR(JTIMEOUT), PAIR(JWRERR), PAIR(JRDERR), PAIR(JCHILD), PAIR(JNOWAIT), {0,0} }; const char *Server_status( int d ) { const char *s; int i; static char msg[LINEBUFFER]; if( d > 0 && d < 32 ) d += 31; for( i = 0; (s = statname[i].str) && statname[i].value != d; ++i ); if( s == 0 ){ s = msg; plp_snprintf( msg, sizeof(msg), "UNKNOWN STATUS '%d'", d ); } return(s); } /* * Error status on STDERR */ /* VARARGS2 */ #ifdef HAVE_STDARGS void setstatus (struct job *job,const char *fmt,...) #else void setstatus (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *fmt; #endif char msg_b[SMALLBUFFER]; static int insetstatus; struct stat statb; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (fmt, char *); if( Doing_cleanup || fmt == 0 || *fmt == 0 || insetstatus ) return; insetstatus = 1; (void) plp_vsnprintf( msg_b, sizeof(msg_b)-4, fmt, ap); DEBUG1("setstatus: msg '%s'", msg_b); if( !Is_server ){ if( Verbose || !Is_lpr ){ (void) plp_vsnprintf(msg_b, sizeof(msg_b)-2, fmt, ap); strcat( msg_b,"\n" ); if( Write_fd_str( 2, msg_b ) < 0 ) cleanup(0); } else { Add_line_list(&Status_lines,msg_b,0,0,0); } } else { if( Status_fd <= 0 || ( Max_status_size_DYN > 0 && fstat( Status_fd, &statb ) != -1 && (statb.st_size / 1024 ) > Max_status_size_DYN ) ){ Status_fd = Trim_status_file( Status_fd, Queue_status_file_DYN, Max_status_size_DYN, Min_status_size_DYN ); } send_to_logger( Status_fd, Mail_fd, job, PRSTATUS, msg_b ); } insetstatus = 0; VA_END; } /*************************************************************************** * void setmessage (struct job *job,char *header, char *fmt,...) * put the message out (if necessary) to the logger ***************************************************************************/ /* VARARGS2 */ #ifdef HAVE_STDARGS void setmessage (struct job *job,const char *header, const char *fmt,...) #else void setmessage (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *header; char *fmt; #endif char msg_b[SMALLBUFFER]; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (header, char *); VA_SHIFT (fmt, char *); if( Doing_cleanup ) return; (void) plp_vsnprintf( msg_b, sizeof(msg_b)-4, fmt, ap); DEBUG1("setmessage: msg '%s'", msg_b); if( Is_server ){ send_to_logger( -1, -1, job, header, msg_b ); } else { strcat( msg_b,"\n" ); if( Write_fd_str( 2, msg_b ) < 0 ) cleanup(0); } VA_END; } /*************************************************************************** * send_to_logger( struct job *job, char *msg ) * This will try and send to the logger. ***************************************************************************/ void send_to_logger( int send_to_status_fd, int send_to_mail_fd, struct job *job, const char *header, char *msg_b ) { char *s, *t; char *id, *tstr; int num,pid; char out_b[4*SMALLBUFFER]; struct line_list l; if( !Is_server || Doing_cleanup ) return; Init_line_list(&l); if(DEBUGL4){ char buffer[32]; plp_snprintf(buffer,sizeof(buffer)-5, "%s", msg_b ); if( msg_b ) safestrncat( buffer,"..."); LOGDEBUG("send_to_logger: Logger_fd fd %d, send_to_status_fd %d, send_to_mail fd %d, header '%s', body '%s'", Logger_fd, send_to_status_fd, send_to_mail_fd, header, buffer ); } if( send_to_status_fd <= 0 && send_to_mail_fd <= 0 && Logger_fd <= 0 ) return; s = t = id = tstr = 0; num = 0; if( job ){ Set_str_value(&l,IDENTIFIER, (id = Find_str_value(&job->info,IDENTIFIER)) ); Set_decimal_value(&l,NUMBER, (num = Find_decimal_value(&job->info,NUMBER)) ); } Set_str_value(&l,UPDATE_TIME,(tstr=Time_str(0,0))); Set_decimal_value(&l,PROCESS,(pid=getpid())); plp_snprintf( out_b, sizeof(out_b), "%s at %s ## %s=%s %s=%d %s=%d\n", msg_b, tstr, IDENTIFIER, id, NUMBER, num, PROCESS, pid ); if( send_to_status_fd > 0 && Write_fd_str( send_to_status_fd, out_b ) < 0 ){ DEBUG4("send_to_logger: write to send_to_status_fd %d failed - %s", send_to_status_fd, Errormsg(errno) ); } if( send_to_mail_fd > 0 && Write_fd_str( send_to_mail_fd, out_b ) < 0 ){ DEBUG4("send_to_logger: write to send_to_mail_fd %d failed - %s", send_to_mail_fd, Errormsg(errno) ); } if( Logger_fd > 0 ){ Set_str_value(&l,PRINTER,Printer_DYN); Set_str_value(&l,HOST,FQDNHost_FQDN); s = Escape(msg_b,1); Set_str_value(&l,VALUE,s); if(s) free(s); s = 0; t = Join_line_list(&l,"\n"); s = Escape(t,1); if(t) free(t); t = 0; t = safestrdup4(header,"=",s,"\n",__FILE__,__LINE__); Write_fd_str( Logger_fd, t ); if( s ) free(s); s = 0; if( t ) free(t); t = 0; } Free_line_list(&l); } lprng-3.8.B/src/common/child.c0000644000131400013140000002205011531672131013104 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "getqueue.h" #include "getopt.h" #include "gethostinfo.h" #include "proctitle.h" #include "linksupport.h" #include "child.h" /**** ENDINCLUDE ****/ /* * Historical compatibility */ #ifdef HAVE_SYS_IOCTL_H # include #endif /* * This avoids some problems * when you have things redefined in system include files. * Don't even think about how this came about - simply mutter * the mantra 'Portablility at any cost...' and be happy. */ #if !defined(TIOCNOTTY) && defined(HAVE_SYS_TTOLD_H) && !defined(IRIX) # include #endif /* * Patrick Powell * We will normally want to wait for children explitly. * Most of the time they can die, but we do not care. * However, some times we want them to cause a BREAK condition * on a system call. */ pid_t plp_waitpid (pid_t pid, plp_status_t *statusPtr, int options) { int report; memset(statusPtr,0,sizeof(statusPtr[0])); DEBUG2("plp_waitpid: pid %ld, options %d", (long)pid, options ); report = waitpid(pid, statusPtr, options ); DEBUG2("plp_waitpid: returned %d, status %s", report, Decode_status( statusPtr ) ); return report; } /*************************************************************************** * Commentary: * When we fork a child, then we need to clean it up. * Note that the forking operation should either be to create * a subchild which will be in the process group, or one * that will be in the same process group * * We will keep a list of the children which will be in the new * process group. When we exit, during cleanup, we will * kill all of these off. Note that we may have to dynamically allocate * memory to keep the list. * * Killchildren( signal ) - kill all children of this process ***************************************************************************/ static void Dump_pinfo( const char *title, struct line_list *p ) { int i, pid; LOGDEBUG("*** Dump_pinfo %s - count %d ***", title, p->count ); for( i = 0; i < p->count; ++i ){ pid = Cast_ptr_to_int(p->list[i]); LOGDEBUG(" pid %d", pid ); } LOGDEBUG("*** done ***"); } int Countpid(void) { int i, j, pid; if(DEBUGL4)Dump_pinfo("Countpid - before",&Process_list); for( i = j = 0; i < Process_list.count; ++i ){ pid = Cast_ptr_to_int(Process_list.list[i]); if( kill(pid, 0) == 0 ){ DEBUG4("Countpid: pid %d active", pid ); Process_list.list[j++] = Cast_int_to_voidstar(pid); } } Process_list.count = j; if(DEBUGL4)Dump_pinfo("Countpid - after", &Process_list); return( Process_list.count ); } void Killchildren( int sig ) { int pid, i, j; DEBUG2("Killchildren: pid %d, signal %s, count %d", (int)getpid(),Sigstr(sig), Process_list.count ); for( i = j = 0; i < Process_list.count; ++i ){ pid = Cast_ptr_to_int(Process_list.list[i]); DEBUG2("Killchildren: pid %d, signal '%s'", pid, Sigstr(sig) ); killpg(pid,sig); killpg(pid,SIGCONT); kill(pid,sig); kill(pid,SIGCONT); if( kill(pid, sig) == 0 ){ DEBUG4("Killchildren: pid %d still active", pid ); Process_list.list[j++] = Cast_int_to_voidstar(pid); } } Process_list.count = j; if(DEBUGL2)Dump_pinfo("Killchildren - after",&Process_list); } /* * dofork: fork a process and set it up as a process group leader */ pid_t dofork( int new_process_group ) { pid_t pid; int i; const char *s; pid = fork(); if( pid == 0 ){ /* you MUST put the process in another process group; * if you have a filter, and it does a 'killpg()' signal, * if you do not have it in a separate group the effects * are catastrophic. Believe me on this one... */ if( new_process_group ){ #if defined(HAVE_SETSID) i = setsid(); s = "setsid()"; #else # if defined(HAVE_SETPGID) i = setpgid(0,getpid()); s = "setpgid(0,getpid())"; # else # if defined(HAVE_SETPGRP_0) i = setpgrp(0,getpid()); s = "setpgrp(0,getpid())"; # else i = setpgrp(); s = "setpgrp()"; # endif # endif #endif if( i < 0 ){ logerr_die(LOG_ERR, "dofork: %s failed", s ); } #ifdef TIOCNOTTY /* BSD: non-zero process group id, so it cannot get control terminal */ /* you MUST be able to turn off the control terminal this way */ if ((i = open ("/dev/tty", O_RDWR, 0600 )) >= 0) { if( ioctl (i, TIOCNOTTY, (void *)0 ) < 0 ){ logerr_die(LOG_ERR, "dofork: TIOCNOTTY failed" ); } (void)close(i); } #endif /* BSD: We have lost the controlling terminal at this point; * we are now the process group leader and cannot get one * unless we use the TIOCTTY ioctl call * Solaris && SYSV: We have lost the controlling terminal at this point; * we are now the process group leader, * we may get control tty unless we open devices with * the O_NOCTTY flag; if you do not have this open flag * you are in trouble. * See: UNIX Network Programming, W. Richard Stevens, * Section 2.6, Daemon Processes * Advanced Programming in the UNIX environment, * W. Richard Stevens, Section 9.5 */ } /* we do not want to copy our parent's exit jobs or temp files */ Process_list.count = 0; Free_line_list( &Process_list ); Clear_tempfile_list(); /* * We need to make sure that LPD forked processes do not have blocked * signals. The only two that I block are SIGCHLD and SIGUSR1. * These, unfortunately, are precisely the ones that cause problems. * Also, SIGALRM is used, but it is never blocked. */ if( Is_server ){ plp_block_mask oblock; plp_unblock_all_signals( &oblock ); } } else if( pid != -1 ){ Check_max(&Process_list,1); Process_list.list[Process_list.count++] = Cast_int_to_voidstar(pid); } return( pid ); } /* * routines to call on exit */ plp_signal_t cleanup_USR1 (int passed_signal) { DEBUG4("cleanup_USR1: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode); cleanup(SIGUSR1); } plp_signal_t cleanup_HUP (int passed_signal) { DEBUG4("cleanup_HUP: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode); cleanup(SIGHUP); } plp_signal_t cleanup_INT (int passed_signal) { DEBUG4("cleanup_INT: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode); cleanup(SIGINT); } plp_signal_t cleanup_QUIT (int passed_signal) { DEBUG4("cleanup_QUIT: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode); cleanup(SIGQUIT); } plp_signal_t cleanup_TERM (int passed_signal) { DEBUG4("cleanup_TERM: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode); cleanup(SIGTERM); } void Max_open( int fd ) { if( fd > 0 ){ #if 0 if( fd > Max_fd+10 ){ fatal(LOG_ERR, "Max_open: fd %d and old Max_fd %d", fd, Max_fd); } #endif if( fd > Max_fd ) Max_fd = fd; } } static void Dump_unfreed_mem(const char *title); plp_signal_t cleanup (int passed_signal) { plp_block_mask oblock; int i; int signalv = passed_signal; plp_block_all_signals( &oblock ); /**/ DEBUG2("cleanup: signal %s, Errorcode %d", Sigstr(passed_signal), Errorcode ); #if defined(__CYGWIN__) if( getpid() == Server_pid ) { char *path = safestrdup3( Lockfile_DYN,".", Lpd_port_DYN, __FILE__, __LINE__ ); unlink(path); if( path ) free(path); path = 0; } #endif /* shut down all logging stuff */ Doing_cleanup = 1; /* first we try to close all the output ports */ for( i = 3; i < Max_fd; ++i ){ #ifdef DMALLOC extern int dmalloc_outfile_fd; if( i == dmalloc_outfile_fd ) continue; #endif close(i); } Remove_tempfiles(); /* then we do exit cleanup */ if( passed_signal == 0 ){ signalv = SIGINT; } else if( passed_signal == SIGUSR1 ){ passed_signal = 0; signalv = SIGINT; Errorcode = 0; } /* kill children of this process */ Killchildren( signalv ); Killchildren( SIGINT ); Killchildren( SIGHUP ); Killchildren( SIGQUIT ); Process_list.count = 0; DEBUG1("cleanup: done, exit(%d)", Errorcode); if( Errorcode == 0 ){ Errorcode = passed_signal; } Dump_unfreed_mem("**** cleanup"); exit(Errorcode); } static void Dump_unfreed_mem(const char *title) { char buffer[SMALLBUFFER]; buffer[0] = 0; plp_snprintf(buffer,sizeof(buffer), "*** Dump_unfreed_mem: %s, pid %ld\n", title, (long)getpid() ); #if defined(DMALLOC) { extern int dmalloc_outfile_fd; extern char *dmalloc_logpath; if( dmalloc_logpath && dmalloc_outfile_fd < 0 ){ dmalloc_outfile_fd = open( dmalloc_logpath, O_WRONLY | O_CREAT | O_TRUNC, 0666); Max_open( dmalloc_outfile_fd ); } plp_snprintf(buffer,sizeof(buffer), "*** Dump_unfreed_mem: %s, pid %ld\n", title, (long)getpid() ); Write_fd_str(dmalloc_outfile_fd, buffer ); if(Outbuf) free(Outbuf); Outbuf = 0; if(Inbuf) free(Inbuf); Inbuf = 0; Clear_tempfile_list(); { struct line_list **l; for( l = Allocs; *l; ++l ) Free_line_list(*l); } Process_list.count = 0; Free_line_list(&Process_list); Clear_all_host_information(); Clear_var_list( Pc_var_list, 0 ); Clear_var_list( DYN_var_list, 0 ); dmalloc_log_unfreed(); Write_fd_str(dmalloc_outfile_fd, "***\n" ); exit(Errorcode); } #endif } lprng-3.8.B/src/common/lpd_jobs.c0000644000131400013140000026770511531672131013637 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "accounting.h" #include "child.h" #include "errorcodes.h" #include "fileopen.h" #include "gethostinfo.h" #include "getopt.h" #include "getprinter.h" #include "getqueue.h" #include "linksupport.h" #include "lockfile.h" #include "lpd_remove.h" #include "merge.h" #include "permission.h" #include "printjob.h" #include "proctitle.h" #include "sendjob.h" #include "sendmail.h" #include "stty.h" #include "openprinter.h" #include "lpd_jobs.h" #include "lpd_rcvjob.h" #include "lpd_worker.h" #if defined(USER_INCLUDE) # include USER_INCLUDE #else # if defined(CHOOSER_ROUTINE) # error No 'USER_INCLUDE' file with function prototypes specified You need an include file with function prototypes # endif #endif /**** ENDINCLUDE ****/ static int Fork_subserver( struct line_list *server_info, int use_subserver, struct line_list *parms ); static void Wait_for_subserver( int timeout, int pid_to_wait_for, struct line_list *servers /*, struct line_list *order */ ); static void Update_status( int fd, struct job *job, int status ); static int Check_print_perms( struct job *job ); static void Setup_user_reporting( struct job *job ); static void Filter_files_in_job( struct job *job, int outfd, char *user_filter ); static int Move_job(int fd, struct job *job, struct line_list *sp, char *errmsg, int errlen ); /*************************************************************************** * Commentary: * Patrick Powell Thu May 11 09:26:48 PDT 1995 * * Job processing algorithm * * 1. Check to see if there is already a spooler process active. * The active file will contain the PID of the active spooler process. * 2. Build the job queue * 3. For each job in the job queue, service them. * * MULTIPLE Servers for a Single Queue. * In the printcap, the "sv" flag sets the Server_names_DYN variable with * the list of servers to be used for this queue. The "ss" flag sets * the Server_queue_name_DYN flag with the queue that this is a server for. * * Under normal conditions, the following process hierarchy is used: * * server process - printer 'spool queue' * subserver process - first printer in 'Server_name' * subserver process - second printer in 'Server_name' * ... * * The server process does the following: * for each printer in the Server_name list * sort them by the last order that you had in the control file * for each printer in the Server_name list * check the status of the queue, and gets the control file * information and the numbers of jobs waiting. * for each printer in the Server_name list * if printable jobs and printing enabled * start up a subserver * * while(1){ * for all printable jobs do * check to see if there is a queue for them to be * printed on and the the queue is not busy; * if( job does not need a server ) then * do whatever is needed; * update job status(); * else if( no jobs to print and no servers active ) then * break; * else if( no jobs to print or server active ) then * wait for server to exit(); * if( pid is for server printing job) * update job status(); * update server status(); * else * dofork(0) a server process; * record pid of server doing work; * endif * } * * We then check to see if we are a slave (sv) to a master spool queue; * if we are and we are not a child process of the 'master' server, * we exit. * * Note: if we spool something to a slave queue, then we need to start * the master server to make the slave printer work. * * Note: the slave queue processes * will not close the masters lock files; this means a new master * cannot start serving the queue until all the slaves are dead. * Why this action do you ask? The reason is that it is difficult * for a new master to inherit slaves from a dead master. * * It turns out that many implementations of some network * based databased systems and other network database routines are broken, * and have memory leaks or never close file descriptors. Up to the point * where the loop for checking the queue starts, there is a known number * of file descriptors open, and dynamically allocated memory. * After this, it is difficult to predict just what is going to happen. * By forking a 'subserver' process, we firewall the actual memory and * file descriptor screwups into the subserver process. * * When the subserver exits, it returns an error code that the server * process then interprets. This error code is used to either remove the job * or retry it. * * Note that there are conditions under which a job cannot be removed. * We simply abort at that point and let higher level authority (admins) * deal with this. * ***************************************************************************/ /* * Signal handler to set flags and terminate system calls * NOTE: use 'volatile' so that the &*()()&* optimizing compilers * handle the value correctly. */ static volatile int Susr1, Chld; static void Sigusr1(void) { ++Susr1; (void) plp_signal_break(SIGUSR1, (plp_sigfunc_t)Sigusr1); return; } static void Sigchld(void) { ++Chld; signal( SIGCHLD, SIG_DFL ); return; } /*************************************************************************** * Update_spool_info() * get updated spool control file information ***************************************************************************/ static void Update_spool_info( struct line_list *sp ) { struct line_list info; char *sc; Init_line_list(&info); Set_str_value(&info,SPOOLDIR, Find_str_value(sp,SPOOLDIR) ); Set_str_value(&info,PRINTER, Find_str_value(sp,PRINTER) ); Set_str_value(&info,QUEUE_CONTROL_FILE, Find_str_value(sp,QUEUE_CONTROL_FILE) ); Set_str_value(&info,HF_NAME, Find_str_value(sp,HF_NAME) ); Set_str_value(&info,IDENTIFIER, Find_str_value(sp,IDENTIFIER) ); Set_str_value(&info,SERVER, Find_str_value(sp,SERVER) ); Set_str_value(&info,DONE_TIME, Find_str_value(sp,DONE_TIME) ); sc = Find_str_value(&info,QUEUE_CONTROL_FILE); DEBUG1("Update_spool_info: file '%s'", sc ); Free_line_list(sp); Get_spool_control(sc,sp); Merge_line_list(sp,&info,Hash_value_sep,1,1); Free_line_list(&info); } static int cmp_server( const void *left, const void *right, const void *p ) { struct line_list *l, *r; int tr, tl; l = ((struct line_list **)left)[0]; r = ((struct line_list **)right)[0]; tl = Find_flag_value(l,DONE_TIME); tr = Find_flag_value(r,DONE_TIME); if(DEBUGL5)Dump_line_list("cmp_server - l",l); if(DEBUGL5)Dump_line_list("cmp_server - r",r); DEBUG5("cmp_server: tl %d, tr %d, cmp %d, p %d", tl, tr, tl - tr, (int)(p!=0) ); return( tl - tr ); } static void Get_subserver_pc( char *printer, struct line_list *subserver_info, int done_time ) { int printable, held, move, err, done; char *path; char buffer[SMALLBUFFER]; printable = held = move = err = done = 0; DEBUG1("Get_subserver_pc: '%s'", printer ); buffer[0] = 0; if( Setup_printer( printer, buffer, sizeof(buffer), 1 ) ){ Errorcode = JABORT; fatal(LOG_ERR, "Get_subserver_pc: '%s' - '%s'", printer, buffer); } Set_str_value(subserver_info,PRINTER,Printer_DYN); Set_str_value(subserver_info,SPOOLDIR,Spool_dir_DYN); path = Make_pathname( Spool_dir_DYN, Queue_control_file_DYN ); Set_str_value(subserver_info,QUEUE_CONTROL_FILE,path); if( path ) free(path); path = 0; Update_spool_info( subserver_info ); DEBUG1("Get_subserver_pc: scanning '%s'", Spool_dir_DYN ); Scan_queue( subserver_info, 0, &printable, &held, &move, 1, &err, &done, 0, 0); Set_flag_value(subserver_info,PRINTABLE,printable); Set_flag_value(subserver_info,HELD,held); Set_flag_value(subserver_info,MOVE,move); Set_flag_value(subserver_info,DONE_TIME,done_time); if( !(Save_when_done_DYN || Save_on_error_DYN ) && (Done_jobs_DYN || Done_jobs_max_age_DYN) && (err || done ) ){ Set_flag_value(subserver_info,DONE_REMOVE,1); } DEBUG1("Get_subserver_pc: printable %d, held %d, move %d, done_remove %d, fowarding '%s'", printable, held, move, Find_flag_value(subserver_info,DONE_REMOVE), Find_str_value(subserver_info,FORWARDING) ); } /*************************************************************************** * Dump_subserver_info() * dump the server information list ***************************************************************************/ static void Dump_subserver_info( const char *title, struct line_list *l) { char buffer[LINEBUFFER]; int i; LOGDEBUG("*** Dump_subserver_info: '%s' - %d subservers", title, l->count ); for( i = 0; i < l->count; ++i ){ plp_snprintf(buffer,sizeof(buffer), "server %d",i); Dump_line_list_sub(buffer,(struct line_list *)l->list[i]); } } /*************************************************************************** * Get_subserver_info() * hack up the server information list into a list of servers ***************************************************************************/ static void Get_subserver_info( struct line_list *order, char *list, char *old_order) { struct line_list server_order, server, *pl; int i; char *s; Unescape( old_order ); /* this is ugly - we make it forwards compatible */ Init_line_list(&server_order); Init_line_list(&server); DEBUG1("Get_subserver_info: old_order '%s', list '%s'",old_order, list); Split(&server_order,old_order,File_sep,0,0,0,1,0,0); Split(&server_order, list,File_sep,0,0,0,1,0,0); if(DEBUGL1)Dump_line_list("Get_subserver_info - starting",&server_order); /* get the info of printers */ for( i = 0; i < server_order.count; ++i ){ s = server_order.list[i]; DEBUG1("Get_subserver_info: doing '%s'",s); if( Find_str_value(&server,s) ){ DEBUG1("Get_subserver_info: already done '%s'",s); continue; } pl = malloc_or_die(sizeof(pl[0]),__FILE__,__LINE__); Init_line_list(pl); Get_subserver_pc( s, pl, i+1 ); Check_max(order,1); DEBUG1("Get_subserver_info: adding to list '%s' at %d",s,order->count); order->list[order->count++] = (char *)pl; Set_str_value(&server,s,s); pl = 0; } Free_line_list(&server_order); Free_line_list(&server); if(DEBUGL1)Dump_subserver_info("Get_subserver_info - starting order",order); } /*************************************************************************** * Make_temp_copy - make a temporary copy in the directory ***************************************************************************/ static char *Make_temp_copy( char *srcfile, char *destdir ) { char buffer[LARGEBUFFER]; char *path = 0; struct stat statb; int srcfd, destfd, fail, n, len, count; fail = 0; srcfd = destfd = -1; DEBUG3("Make_temp_copy: '%s' to '%s'", srcfile, destdir); destfd = Make_temp_fd_in_dir(&path, destdir); unlink(path); if( link( srcfile, path ) == -1 ){ DEBUG3("Make_temp_copy: link '%s' to '%s' failed, '%s'", srcfile, path, Errormsg(errno) ); srcfd = Checkread(srcfile, &statb ); if( srcfd < 0 ){ logerr(LOG_INFO, "Make_temp_copy: open '%s' failed", srcfile ); fail = 1; goto error; } while( (n = ok_read(srcfd,buffer,sizeof(buffer))) > 0 ){ for( count = len = 0; len < n && (count = write(destfd, buffer+len,n-len)) > 0; len += count ); if( count < 0 ){ logerr(LOG_INFO, "Make_temp_copy: copy to '%s' failed", path ); fail = 1; goto error; } } } error: if( fail ){ unlink(path); path = 0; } if( srcfd >= 0 ) close(srcfd); srcfd = -1; if( destfd >= 0 ) close(destfd); destfd = -1; return( path ); } /*************************************************************************** * Do_queue_jobs: process the job queue ***************************************************************************/ static int Done_count; static time_t Done_time; int Do_queue_jobs( char *name, int subserver ) { int master = 0; /* this is the master */ int opened_logfile = 0; /* we have not opened the log file */ int lock_fd; /* fd for files */ char buffer[SMALLBUFFER], *savename = 0, errmsg[SMALLBUFFER], *save_move_dest; char *path, *s, *id, *tempfile, *transfername, *openname, *new_dest, *move_dest, *pr, *hf_name, *forwarding; struct stat statb; int i, j, mod, fd, pid, printable, held, move, destinations, destination, use_subserver, job_to_do, working, printing_enabled, all_done, job_index, change, in_tempfd, out_tempfd, len, chooser_did_not_find_server, error, done, done_remove, check_for_done; struct line_list servers, tinfo, *sp, chooser_list, chooser_env; plp_block_mask oblock; struct job job; int jobs_printed = 0; int errlen = sizeof(errmsg); Init_line_list(&tinfo); lock_fd = -1; Init_job(&job); Init_line_list(&servers); Init_line_list(&chooser_list); Init_line_list(&chooser_env); id = transfername = 0; in_tempfd = out_tempfd = -1; Name = "(Server)"; Set_DYN(&Printer_DYN,name); DEBUG1("Do_queue_jobs: called with name '%s', subserver %d", Printer_DYN, subserver ); name = Printer_DYN; if(DEBUGL4){ int fdx; fdx = dup(0); LOGDEBUG("Do_queue_jobs: start next fd %d",fdx); close(fdx); }; begin: Set_DYN(&Printer_DYN,name); DEBUG1("Do_queue_jobs: begin name '%s'", Printer_DYN ); tempfile = 0; Free_listof_line_list( &servers ); if( lock_fd != -1 ) close( lock_fd ); lock_fd = -1; Errorcode = JABORT; /* you need to have a spool queue */ if( Setup_printer( Printer_DYN, buffer, sizeof(buffer), 0 ) ){ cleanup(0); } if(DEBUGL4){ int fdx; fdx = dup(0); LOGDEBUG("Do_queue_jobs: after Setup_printer next fd %d",fdx); close(fdx); }; setproctitle( "lpd %s '%s'", Name, Printer_DYN ); again: /* block signals */ plp_block_one_signal(SIGCHLD, &oblock); plp_block_one_signal(SIGUSR1, &oblock); (void) plp_signal(SIGCHLD, SIG_DFL); (void) plp_signal(SIGUSR1, (plp_sigfunc_t)Sigusr1); Susr1 = 0; path = Make_pathname( Spool_dir_DYN, Queue_lock_file_DYN ); DEBUG1( "Do_queue_jobs: checking lock file '%s'", path ); lock_fd = Checkwrite( path, &statb, O_RDWR, 1, 0 ); if( lock_fd < 0 ){ logerr_die(LOG_ERR, _("Do_queue_jobs: cannot open lockfile '%s'"), path ); } if(path) free(path); path = 0; /* This code is very tricky, and may cause some headaches First, you want to make sure that you have an active process to do the unspooling. If you CAN lock the lock file, then you are the active process. If you CANNOT lock the lock file then some other process is the active process. If some other process is the active process then you want to make sure that you signal it. When the process is exiting then it will first truncate lock file and then close it. We make the brutal assumption that from the time that the process truncates the log file until it exits will be less than the time taken for this process to read the file and send a signal. We help a bit by having the exiting process sleep 2 seconds - i.e. - we make sure that it will take a fairish time. This makes sure that processes that read the PID before it is truncated will send the signal to an existing processes. */ while( Do_lock( lock_fd, 0 ) < 0 ){ pid = Read_pid( lock_fd ); DEBUG1( "Do_queue_jobs: server process '%d' may be active", pid ); if( pid == 0 || kill( pid, SIGUSR1 ) ){ plp_usleep(1000); continue; } Errorcode = 0; cleanup(0); } pid = getpid(); DEBUG1( "Do_queue_jobs: writing lockfile '%s' with pid '%d'", Queue_lock_file_DYN, pid ); Write_pid( lock_fd, pid, (char *)0 ); /* we now now new queue status so we force update */ if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } if( Log_file_DYN && !opened_logfile ){ fd = Trim_status_file( -1, Log_file_DYN, Max_log_file_size_DYN, Min_log_file_size_DYN ); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); } opened_logfile = 1; } s = Find_str_value(&Spool_control,DEBUG); if(!s) s = New_debug_DYN; Parse_debug( s, 0); if( Server_queue_name_DYN ){ if( subserver == 0 ){ /* you really need to start up the master queue */ name = Server_queue_name_DYN; DEBUG1("Do_queue_jobs: starting up master queue '%s'", name ); goto begin; } Name = "(Sub)"; } /* set up the server name information */ Check_max(&servers,1); sp = malloc_or_die(sizeof(sp[0]),__FILE__,__LINE__); memset(sp,0,sizeof(sp[0])); Set_str_value(sp,PRINTER,Printer_DYN); Set_str_value(sp,SPOOLDIR,Spool_dir_DYN); Set_str_value(sp,QUEUE_CONTROL_FILE,Queue_control_file_DYN); servers.list[servers.count++] = (char *)sp; Update_spool_info(sp); change = Find_flag_value(&Spool_control,CHANGE); if( change ){ Set_flag_value(sp,CHANGE,0); Set_flag_value(&Spool_control,CHANGE,0); Set_spool_control(0, Queue_control_file_DYN, &Spool_control); } master = 0; if( !ISNULL(Server_names_DYN) ){ DEBUG1( "Do_queue_jobs: Server_names_DYN '%s', Server_order '%s'", Server_names_DYN, Srver_order(&Spool_control) ); if( Server_queue_name_DYN ){ Errorcode = JABORT; fatal(LOG_ERR, "Do_queue_jobs: serving '%s' and subserver for '%s'", Server_queue_name_DYN, Server_names_DYN ); } /* save the Printer_DYN name */ savename = safestrdup(Printer_DYN,__FILE__,__LINE__); /* we now get the subserver information */ Get_subserver_info( &servers, Server_names_DYN, Srver_order(&Spool_control) ); /* reset the main printer */ if( Setup_printer( savename, buffer, sizeof(buffer), 0 ) ){ cleanup(0); } if(savename) free(savename); savename = 0; master = 1; /* start the queues that need it */ for( i = 1; i < servers.count; ++i ){ sp = (void *)servers.list[i]; pr = Find_str_value(sp,PRINTER); DEBUG1("Do_queue_jobs: subserver '%s' checking for independent action", pr ); if( (s = Find_str_value(sp,SERVER)) ){ DEBUG1("Do_queue_jobs: subserver '%s' active server '%s'", pr,s ); } printable = !Pr_disabled(sp) && !Pr_aborted(sp) && Find_flag_value(sp,PRINTABLE); move = Find_flag_value(sp,MOVE); forwarding = Find_str_value(sp,FORWARDING); change = Find_flag_value(sp,CHANGE); DEBUG1("Do_queue_jobs: subserver '%s', printable %d, move %d, forwarding '%s'", pr, printable, move, forwarding ); /* now see if we need to clean up the old jobs */ done_remove = Find_flag_value(sp,DONE_REMOVE); if( printable || move || change || forwarding || done_remove ){ pid = Fork_subserver( &servers, i, 0 ); jobs_printed = 1; } Set_flag_value(sp,CHANGE,0); } } if(DEBUGL3)Dump_subserver_info("Do_queue_jobs - after setup",&servers); if(DEBUGL4){ int fdx; fdx = dup(0); LOGDEBUG("Do_queue_jobs: after subservers next fd %d",fdx);close(fdx);}; /* get new job values */ if( Scan_queue( &Spool_control, &Sort_order, &printable, &held, &move, 1, &error, &done, 0, 0 ) ){ Errorcode = JFAIL; fatal(LOG_ERR, "Do_queue_jobs: cannot read queue directory '%s'", Spool_dir_DYN ); } DEBUG1( "Do_queue_jobs: printable %d, held %d, move %d, err %d, done %d", printable, held, move, error, done ); if(DEBUGL1){ i = dup(0); LOGDEBUG("Do_queue_jobs: after Scan_queue next fd %d", i); close(i); } /* remove junk fields from job information */ fd = -1; for( i = 0; i < Sort_order.count; ++i ){ /* fix up the sort stuff */ if( fd > 0 ) close(fd); fd = -1; Free_job(&job); Get_job_ticket_file(&fd, &job,Sort_order.list[i] ); if( !job.info.count ) continue; if(DEBUGL3)Dump_job("Do_queue_jobs - info", &job); /* debug output */ mod = 0; if( Find_flag_value(&job.info,SERVER ) ){ Set_decimal_value(&job.info,SERVER,0); mod = 1; } if((destinations = Find_flag_value(&job.info,DESTINATIONS))){ if( Find_str_value(&job.info,DESTINATION ) ){ Set_str_value(&job.info,DESTINATION,0); mod = 1; } for( j = 0; j < destinations; ++j ){ Get_destination(&job,j); if( Find_flag_value(&job.destination,SERVER) ){ mod = 1; Set_decimal_value(&job.destination,SERVER,0); Update_destination(&job); } } } if( mod ) Set_job_ticket_file(&job, 0, fd ); } if( fd > 0 ) close(fd); fd = -1; Free_job(&job); check_for_done = 1; fd = -1; while(1){ DEBUG1( "Do_queue_jobs: MAIN LOOP" ); if(DEBUGL4){ int fdx; fdx = dup(0); LOGDEBUG("Do_queue_jobs: MAIN LOOP next fd %d",fdx); close(fdx); }; Unlink_tempfiles(); if( fd > 0 ) close(fd); fd = -1; /* check for changes to spool control information */ plp_unblock_all_signals( &oblock ); plp_set_signal_mask( &oblock, 0 ); if( (Done_jobs_DYN > 0 && Done_count > Done_jobs_DYN) || (Done_jobs_max_age_DYN > 0 && Done_time && (time(0) - Done_time) > Done_jobs_max_age_DYN) ){ Susr1 = 1; } DEBUG1( "Do_queue_jobs: Susr1 before scan %d, check_for_done %d", Susr1, check_for_done ); while( Susr1 ){ Susr1 = 0; Done_time = 0; Done_count = 0; DEBUG1( "Do_queue_jobs: rescanning" ); Get_spool_control( Queue_control_file_DYN, &Spool_control); if( Scan_queue( &Spool_control, &Sort_order, &printable, &held, &move, 1, &error, &done, 0, 0 ) ){ logerr_die(LOG_ERR, "Do_queue_jobs: cannot read queue '%s'", Spool_dir_DYN ); } DEBUG1( "Do_queue_jobs: printable %d, held %d, move %d, error %d, done %d", printable, held, move, error, done ); for( i = 0; i < servers.count; ++i ){ sp = (void *)servers.list[i]; Update_spool_info( sp ); change = Find_flag_value(sp,CHANGE); pid = Find_flag_value(sp,SERVER); if( i > 0 && change && pid == 0 ){ pid = Fork_subserver( &servers, i, 0 ); jobs_printed = 1; } Set_flag_value(sp,CHANGE,0); } if(DEBUGL1) Dump_subserver_info( "Do_queue_jobs - rescan", &servers ); /* check for changes to spool control information */ plp_unblock_all_signals( &oblock); plp_set_signal_mask( &oblock, 0); DEBUG1( "Do_queue_jobs: Susr1 at end of scan %d", Susr1 ); /* now check to see if you remove jobs */ check_for_done = 0; if( !(Save_when_done_DYN || Save_on_error_DYN ) && (Done_jobs_DYN || Done_jobs_max_age_DYN) && (error || done) ){ check_for_done = 1; } } if(DEBUGL4) Dump_line_list("Do_queue_jobs - sort order printable", &Sort_order ); Remove_done_jobs(); /* make sure you can print */ printing_enabled = !(Pr_disabled(&Spool_control) || Pr_aborted(&Spool_control)); forwarding = Find_str_value(&Spool_control,FORWARDING); DEBUG3("Do_queue_jobs: printing_enabled '%d', forwarding '%s'", printing_enabled, forwarding ); openname = transfername = hf_name = id = move_dest = new_dest = 0; destination = use_subserver = job_to_do = -1; working = destinations = chooser_did_not_find_server = 0; if(DEBUGL2) Dump_subserver_info("Do_queue_jobs- checking for server", &servers ); for( j = 0; j < servers.count; ++j ){ sp = (void *)servers.list[j]; pid = Find_flag_value(sp,SERVER); pr = Find_str_value(sp,PRINTER); DEBUG2("Do_queue_jobs: printer '%s', server %d", pr, pid ); if( pid ){ ++working; } } fd = -1; for( job_index = 0; job_to_do < 0 && job_index < Sort_order.count; ++job_index ){ if( fd > 0 ) close(fd); fd = -1; /* * This is a very special case: * if we have a Chooser AND we have :sv=xx,xx,xx AND * none of the destinations are available to the first job * then the chooser_did_not_find_server flag will be set * If the 'chooser_scan_queue' flag is set, then we will keep * scanning the queue to see if any job can be sent */ DEBUG1("Do_queue_jobs: chooser_did_not_find_server %d, Chooser_scan_queue_DYN %d", chooser_did_not_find_server, Chooser_scan_queue_DYN ); if( chooser_did_not_find_server && !Chooser_scan_queue_DYN ){ break; } Free_job(&job); id = move_dest = new_dest = 0; destination = use_subserver = job_to_do = -1; destinations = 0; if( !Sort_order.list[job_index] ) continue; DEBUG3("Do_queue_jobs: job_index [%d] '%s'", job_index, Sort_order.list[job_index] ); Get_job_ticket_file( &fd, &job, Sort_order.list[job_index] ); if(DEBUGL4)Dump_job("Do_queue_jobs: job ",&job); if( job.info.count == 0 ) continue; /* check to see if active */ if( (pid = Find_flag_value(&job.info,SERVER)) ){ DEBUG3("Do_queue_jobs: [%d] active %d", job_index, pid ); continue; } /* get printable status */ /* Setup_cf_info( &job, 1 ); */ Job_printable(&job,&Spool_control,&printable,&held,&move,&error,&done); if( (!(printable && (printing_enabled || forwarding)) && !move) || held ){ DEBUG3("Do_queue_jobs: [%d] not processable", job_index ); /* free( Sort_order.list[job_index] ); Sort_order.list[job_index] = 0; */ continue; } if( Check_print_perms(&job) == P_REJECT ){ Set_str_value(&job.info,ERROR,"no permission to print"); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); if( Set_job_ticket_file( &job, 0, fd ) ){ /* you cannot update job ticket file!! */ setstatus( &job, _("cannot update job ticket file for '%s'"), id); fatal(LOG_ERR, _("Do_queue_jobs: cannot update job ticket file for '%s'"), id); } if( !(Save_on_error_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( &job, _("removing job '%s' - no permissions"), id); Remove_job( &job ); free( Sort_order.list[job_index] ); Sort_order.list[job_index] = 0; } continue; } { double jobsize = Find_double_value(&job.info,SIZE); if( jobsize == 0 && Discard_zero_length_jobs_DYN ){ Set_str_value(&job.info,ERROR,"not printing zero length job"); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); if( Set_job_ticket_file( &job, 0, fd ) ){ /* you cannot update job ticket file!! */ setstatus( &job, _("cannot update job ticket file for '%s'"), id); fatal(LOG_ERR, _("Do_queue_jobs: cannot update job ticket file for '%s'"), id); } if( !(Save_on_error_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( &job, _("removing job '%s' - no permissions"), id); Remove_job( &job ); free( Sort_order.list[job_index] ); Sort_order.list[job_index] = 0; } continue; } } /* get destination information */ destinations = Find_flag_value(&job.info,DESTINATIONS); if( !destinations ){ move_dest = new_dest = Find_str_value(&job.info,MOVE); if( !new_dest ) move_dest = new_dest = Frwarding(&Spool_control); } else { all_done = 0; for( j = 0; !new_dest && j < destinations; ++j ){ Get_destination(&job,j); if( Find_flag_value(&job.destination,SERVER) ){ break; } if( Find_flag_value(&job.destination,DONE_TIME ) ){ ++all_done; continue; } if( Find_flag_value(&job.destination,ERROR_TIME) || Find_flag_value(&job.destination,HOLD_TIME) ){ continue; } if( (move_dest = new_dest = Find_str_value( &job.destination, MOVE)) ){ destination = j; break; } if( Find_flag_value(&job.destination, PRINTABLE ) && printing_enabled ){ new_dest = Find_str_value( &job.destination,DEST); destination = j; break; } } if( !new_dest ){ printable = 0; } if( all_done == destinations ){ DEBUG3("Do_queue_jobs: destinations %d, done %d", destinations, all_done ); Update_status( fd, &job, JSUCC ); continue; } } DEBUG3("Do_queue_jobs: new_dest '%s', printable %d, master %d, destinations %d, destination %d", new_dest, printable, master, destinations, destination ); if( move_dest ){ sp = (void *)servers.list[0]; /* we will start a process up to do move */ use_subserver = 0; job_to_do = job_index; } else if( printing_enabled && printable ){ /* * find the subserver with a class that will print this job * if master = 1, then we start with 1 */ int printers_available = 0; Free_line_list( &chooser_list ); Free_line_list( &chooser_env ); DEBUG1("Do_queue_jobs: chooser '%s', chooser_routine %lx", Chooser_DYN, Cast_ptr_to_long(Chooser_routine_DYN) ); for( j = master; use_subserver < 0 && j < servers.count; ++j ){ sp = (void *)servers.list[j]; s = Find_str_value(sp,PRINTER); DEBUG1("Do_queue_jobs: checking '%s'", s ); if( Pr_disabled(sp) || Pr_aborted(sp) || Sp_disabled(sp) || Find_flag_value(sp,SERVER)){ DEBUG1("Do_queue_jobs: cannot use [%d] '%s'", j, s ); continue; } if( Get_hold_class(&job.info,sp) ){ DEBUG1("Do_queue_jobs: cannot use [%d] '%s' class conflict", j, s ); /* we found a server that was not available */ continue; } if( Chooser_DYN == 0 && Chooser_routine_DYN == 0 ){ use_subserver = j; job_to_do = job_index; } else { char *t; /* add to the list of possible servers */ ++printers_available; Set_flag_value(&chooser_list,s,j); if( !Chooser_routine_DYN ){ /* get the environment values for the possible server */ t = Join_line_list_with_sep(sp,"\n"); Set_str_value(&chooser_env,s,t); if( t ) free(t); t = 0; t = Find_str_value( &chooser_env,"PRINTERS" ); if( t ){ t = safestrdup3(t,",",s,__FILE__,__LINE__); Set_str_value( &chooser_env,"PRINTERS",t ); if( t ) free(t); t = 0; } else { Set_str_value( &chooser_env,"PRINTERS",s ); } } } } /* we now have to find out if we really need to call the chooser * if we are working and a single queue, then we do not need to call the chooser * if :sv= p1,p2 but none are available then we do not need to call the chooser * if :sv == "" - then we do need to call the chooser * if :sv == p1,p2 and at least one is available - then we do need to call the chooser */ DEBUG1("Do_queue_jobs: Chooser %s, working %d, master %d", Chooser_DYN, working, master); if( (Chooser_routine_DYN || Chooser_DYN) && working && master == 0 ){ chooser_did_not_find_server = 1; } else if( servers.count > 1 && printers_available == 0 ){ chooser_did_not_find_server = 1; } else if( Chooser_routine_DYN ){ #if defined(CHOOSER_ROUTINE) extern int CHOOSER_ROUTINE( struct line_list *servers, struct line_list *available, int *use_subserver ); /* return status for job */ DEBUG1("Do_queue_jobs: using CHOOSER_ROUTINE %s", STR(CHOOSER_ROUTINE) ); j = CHOOSER_ROUTINE( &servers, &chooser_list, &use_subserver ); if( j ){ setstatus(&job, "CHOOSER_ROUTINE exit status %s", Server_status(j)); chooser_did_not_find_server = 1; if( j != JFAIL && j != JABORT ){ Update_status( fd, &job, j ); } if( j == JABORT ){ Errorcode = JABORT; fatal(LOG_ERR, "Do_queue_jobs: Chooser_routine aborted" ); } } else if( use_subserver >= 0 ){ /* we use this subserver */ job_to_do = job_index; } else { /* we did not find a server queue */ chooser_did_not_find_server = 1; } #else Errorcode = JABORT; fatal(LOG_ERR,"Do_queue_jobs: 'chooser_routine' select and no routine defined"); #endif } else if( Chooser_DYN ){ if( in_tempfd > 0 ) close( in_tempfd ); in_tempfd = -1; if( out_tempfd > 0 ) close( out_tempfd ); out_tempfd = -1; in_tempfd = Make_temp_fd(0); out_tempfd = Make_temp_fd(0); s = Find_str_value( &chooser_env,"PRINTERS" ); if( s && (Write_fd_str( in_tempfd, s ) < 0 || Write_fd_str( in_tempfd, "\n" ) < 0) ){ Errorcode = JABORT; logerr_die(LOG_ERR, "Do_queue_jobs: write(%d) failed", in_tempfd); } /* we invoke the chooser with the list * of printers we have found in the order */ if( lseek(in_tempfd,0,SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Do_queue_jobs: fseek(%d) failed", out_tempfd); } j = Filter_file( Send_query_rw_timeout_DYN, in_tempfd, out_tempfd, "CHOOSER", Chooser_DYN, Filter_options_DYN, &job, &chooser_env, 1 ); if( j ){ setstatus(&job, "CHOOSER exit status %s", Server_status(j)); chooser_did_not_find_server = 1; if( j != JFAIL && j != JABORT ){ Update_status( fd, &job, j ); } if( j == JABORT ){ Errorcode = JABORT; fatal(LOG_ERR, "Do_queue_jobs: Chooser aborted" ); } } else { if( lseek(out_tempfd,0,SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Do_queue_jobs: fseek(%d) failed", out_tempfd); } len = Read_fd_len_timeout( Send_query_rw_timeout_DYN, out_tempfd, buffer,sizeof(buffer)-1 ); if( len >= 0 ){ buffer[len] = 0; } else { Errorcode = JFAIL; logerr_die(LOG_INFO, "Do_queue_jobs: read(%d) failed", out_tempfd); } while( isspace(cval(buffer)) ){ memmove(buffer,buffer+1,safestrlen(buffer+1)+1); } if( (s = strpbrk(buffer,Whitespace)) ){ *s = 0; } if( buffer[0] ){ /* we found a server queue */ setstatus(&job, "CHOOSER selected '%s'", buffer); if( Find_str_value( &chooser_list,buffer ) ){ use_subserver = Find_flag_value(&chooser_list,buffer); job_to_do = job_index; } else if( strchr( buffer,'@') ){ /* we are routing to a remote queue not in list */ use_subserver = 0; job_to_do = job_index; Set_str_value( &job.info,NEW_DEST,buffer); new_dest = Find_str_value( &job.info,NEW_DEST); sp = (void *)servers.list[0]; /* we will start a process up to do move */ use_subserver = 0; job_to_do = job_index; } else { logmsg(LOG_ERR, "Do_queue_jobs: CHOOSER selection '%s' not a subserver", buffer ); } } else { /* we did not find a server queue */ chooser_did_not_find_server = 1; } } } if( in_tempfd >= 0 ) close( in_tempfd ); in_tempfd = -1; if( out_tempfd >= 0 ) close( out_tempfd ); out_tempfd = -1; Free_line_list( &chooser_env ); Free_line_list( &chooser_list ); } } /* first, we see if there is no work and no server active */ DEBUG1("Do_queue_jobs: job_to_do %d, use_subserver %d, working %d, move_dest %s", job_to_do, use_subserver, working, move_dest ); if( job_to_do < 0 && !working && chooser_did_not_find_server == 0 ){ DEBUG1("Do_queue_jobs: nothing to do"); if( fd > 0 ) close(fd); fd = -1; break; } /* now we see if we have to wait */ if( use_subserver < 0 ){ if( fd > 0 ) close(fd); fd = -1; if( chooser_did_not_find_server ){ setstatus(0, "chooser did not find subserver, waiting %d sec", Chooser_interval_DYN ); Wait_for_subserver( Chooser_interval_DYN, -1, &servers ); } else if( working ){ if( servers.count > 1 ){ setstatus(0, "waiting for server queue process to exit" ); } else { setstatus(0, "waiting for subserver to exit" ); } Wait_for_subserver( 0, -1, &servers ); } continue; } /* * get the job information */ hf_name = Find_str_value(&job.info,HF_NAME); id = Find_str_value(&job.info,IDENTIFIER); if( !id ){ Errorcode = JABORT; fatal(LOG_ERR, _("Do_queue_jobs: LOGIC ERROR - no identifer '%s'"), hf_name); } /* * check for circular forwarding of jobs */ if( Max_move_count_DYN > 0 && Find_flag_value(&job.info,MOVE_COUNT) > Max_move_count_DYN ){ Errorcode = JABORT; fatal(LOG_ERR, _("Do_queue_jobs: FORWARDING LOOP - '%s'"), hf_name); } /* * set the job ticket file information */ if( destination >= 0 ){ plp_snprintf(buffer,sizeof(buffer), "DEST%d",destination ); Set_str_value(&job.info,DESTINATION,buffer); } DEBUG1("Do_queue_jobs: setting %s SERVER %d", id, (int)getpid() ); Set_decimal_value(&job.info,SERVER,getpid()); Set_flag_value(&job.info,START_TIME,time((void *)0)); sp = (void *)servers.list[use_subserver]; pr = Find_str_value(sp,PRINTER); DEBUG1("Do_queue_jobs: starting job '%s' on '%s', use_subserver %d, move_dest '%s'", id, pr, use_subserver, move_dest ); if( Set_job_ticket_file( &job, 0, fd ) ){ /* you cannot update job ticket file!! */ setstatus( &job, _("cannot update job ticket file '%s'"), hf_name); fatal(LOG_ERR, _("Do_queue_jobs: cannot update job ticket file '%s'"), hf_name); } if( Status_file_DYN ){ int fd = -1; DEBUG1("Do_queue_jobs: trimming status file '%s'/'%s'", Spool_dir_DYN, Status_file_DYN ); fd = Trim_status_file( -1, Status_file_DYN, Max_status_size_DYN, Min_status_size_DYN ); if( fd > 0 ) close(fd); fd = -1; } /* * at this point, if use_subserver != 0, then we can start up * a subserver process. We can move the job to the spool queue of the * subserver process. This job should have all of the characteristics * of a new job for this queue */ if( use_subserver > 0 ){ if( !Move_job( fd, &job, sp, buffer, sizeof(buffer)) ){ /* now we deal with the job in the original queue */ Set_str_value(sp,IDENTIFIER,id); setstatus(&job, "starting subserver '%s'", pr ); pid = Fork_subserver( &servers, use_subserver, 0 ); } jobs_printed = 1; if( fd > 0 ) close(fd); fd = -1; continue; } else if( move_dest ){ /* * we are moving a job to another queue. This can be done * by either linking or copying files. The destination can be either * a local queue or a remote printer */ static struct line_list new_sp; /* we are going to set a pointer to this */ Init_line_list(&new_sp); savename = safestrdup(Printer_DYN,__FILE__,__LINE__); save_move_dest = safestrdup(move_dest,__FILE__,__LINE__); move_dest = save_move_dest; /* * is it a remote printer? */ if( safestrchr(move_dest ,'@') ){ hf_name = Find_str_value(&job.info,HF_NAME); id = Find_str_value(&job.info,IDENTIFIER); DEBUG1( "Do_queue_jobs: move_dest '%s', hf_name '%s', id '%s'", move_dest, hf_name, id ); if( use_subserver ){ Errorcode = JABORT; fatal(LOG_ERR, _("Do_queue_jobs: LOGIC ERROR! new_dest and use_subserver == %d"), use_subserver ); } sp = (void *)servers.list[0]; Merge_line_list(&new_sp,sp,Hash_value_sep,1,1); Set_str_value(&new_sp,HF_NAME,hf_name); Set_str_value(&new_sp,IDENTIFIER,id); servers.list[0] = (void *)&new_sp; Free_line_list(&tinfo); Set_str_value(&tinfo,HF_NAME,hf_name); Set_str_value(&tinfo,NEW_DEST,new_dest); Set_str_value(&tinfo,MOVE_DEST,move_dest); if( fd > 0 ) close(fd); fd = -1; if( (pid = Fork_subserver( &servers, 0, &tinfo )) < 0 ){ setstatus( &job, _("sleeping, waiting for processes to exit")); plp_sleep(1); } else { Wait_for_subserver( 0, pid, &servers ); } if(DEBUGL4)Dump_line_list("Do_queue_jobs - sp after wait", sp ); Free_line_list(&new_sp); servers.list[0] = (void *)sp; } else if( Setup_printer( move_dest, errmsg, errlen, 1 ) ){ /* we failed to find the destination directory */ plp_snprintf(buffer,sizeof(buffer), "dest '%s' setup failed - %s'", move_dest, errmsg ); Set_str_value(&job.info,ERROR,buffer); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_job_ticket_file(&job, 0, fd ); } else { /* we have found the destination directory, reset to original */ Set_str_value(&new_sp,PRINTER,Printer_DYN); Set_str_value(&new_sp,SPOOLDIR,Spool_dir_DYN); if( Setup_printer( savename, errmsg, errlen, 1 ) ){ /* could not get back to the original */ Errorcode = JABORT; fatal(LOG_ERR, "Do_queue_jobs: move_dest subserver '%s' setup failed '%s'", savename, errmsg ); } if( !safestrcmp( Printer_DYN, move_dest ) ){ /* we are moving to the same spool queue */ plp_snprintf(buffer,sizeof(buffer), "loop moving '%s' to '%s'", move_dest, Printer_DYN ); Set_str_value(&job.info,ERROR,buffer); Set_nz_flag_value(&job.info,ERROR_TIME,time(0)); Set_job_ticket_file(&job, 0, fd ); } else if( !Move_job( fd, &job, &new_sp, buffer, sizeof(buffer)) ){ Set_flag_value(&job.info,DONE_TIME,time((void *)0)); setstatus( &job, "%s@%s: job '%s' moved", Printer_DYN, FQDNHost_FQDN, id ); /* send a request to start the queue server */ plp_snprintf( buffer, sizeof(buffer), "%s\n", move_dest ); DEBUG1("Do_queue_jobs: sending '%s' to LPD", move_dest ); if( Write_fd_str( Lpd_request, buffer ) < 0 ){ Errorcode = JABORT; logerr_die(LOG_ERR, _("Do_queue_jobs: write to fd '%d' failed"), Lpd_request ); } } } if( fd > 0 ) close(fd); fd = -1; if(savename) free(savename); savename = 0; if(save_move_dest) free(save_move_dest); save_move_dest = 0; move_dest = 0; Free_line_list(&new_sp); jobs_printed = 1; continue; } else { /* if( !Find_flag_value(sp,SERVER) ) */ Free_line_list(&tinfo); hf_name = Find_str_value(&job.info,HF_NAME); id = Find_str_value(&job.info,IDENTIFIER); Set_str_value(&tinfo,HF_NAME,hf_name); Set_str_value(&tinfo,NEW_DEST,new_dest); Set_str_value(&tinfo,MOVE_DEST,move_dest); Set_str_value(sp,HF_NAME,hf_name); Set_str_value(sp,IDENTIFIER,id); if( (pid = Fork_subserver( &servers, 0, &tinfo )) < 0 ){ setstatus( &job, _("sleeping, waiting for processes to exit")); plp_sleep(1); Set_str_value(sp,HF_NAME,0); Set_str_value(sp,IDENTIFIER,0); } jobs_printed = 1; } if( fd > 0 ) close(fd); fd = -1; } /* now we reset the server order */ Errorcode = JSUCC; Free_job(&job); Free_line_list(&tinfo); if( Server_names_DYN ){ if( jobs_printed ) setstatus( 0, "no more jobs to process in load balance queue" ); jobs_printed = 0; for( i = 1; i < servers.count; ++i ){ sp = (void *)servers.list[i]; s = Find_str_value(sp,PRINTER); Add_line_list(&tinfo,s,0,0,0); } s = Join_line_list_with_sep(&tinfo,","); Set_str_value(&Spool_control,SERVER_ORDER,s); Set_spool_control(0, Queue_control_file_DYN, &Spool_control); if(s) free(s); s = 0; Free_line_list(&tinfo); } Free_listof_line_list(&servers); /* truncate and close the lock file then wait a short time for signal */ ftruncate( lock_fd, 0 ); close( lock_fd ); lock_fd = -1; /* force status update */ if( Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } plp_unblock_all_signals( &oblock); plp_usleep(500); DEBUG1( "Do_queue_jobs: Susr1 at end %d", Susr1 ); if( Susr1 ){ DEBUG1("Do_queue_jobs: SIGUSR1 just before exit" ); Susr1 = 0; goto again; } cleanup(0); } /*************************************************************************** * Remote_job() * Send a job to a remote server. This code is actually trickier * than it looks, as the Send_job code takes most of the heat. * ***************************************************************************/ static int Remote_job( struct job *job, int lpd_bounce, char *move_dest, char *id ) { int status, tempfd, n, fd; double job_size; char buffer[SMALLBUFFER], *s, *tempfile, *oldid, *newid, *old_lp_value, *hf_name; struct line_list *lp, *firstfile; struct job jcopy; struct stat statb; DEBUG1("Remote_job: %s", id ); /* setmessage(job,STATE,"SENDING"); */ status = 0; Init_job(&jcopy); Set_str_value(&job->info,PRSTATUS,0); Set_str_value(&job->info,ERROR,0); Set_flag_value(&job->info,ERROR_TIME,0); Setup_user_reporting(job); if( Accounting_remote_DYN && Accounting_file_DYN && Accounting_start_DYN ){ status = Do_accounting( 0, Accounting_start_DYN, job, Connect_interval_DYN ); DEBUG1("Remote_job: accounting status %s", Server_status(status) ); if( status ){ /* * special case when job has been removed while attempting to print */ fd = -1; hf_name = Find_str_value(&job->info,HF_NAME); safestrncpy(buffer,hf_name); Get_job_ticket_file( &fd, job, buffer ); if( job->info.count ){ switch(status){ case JHOLD: Set_flag_value(&job->info,HOLD_TIME,time((void *)0)); break; case JREMOVE: Set_flag_value(&job->info,REMOVE_TIME,time((void *)0)); break; default: plp_snprintf(buffer,sizeof(buffer), "accounting check failed '%s'", Server_status(status)); setstatus(job, "%s", buffer ); Set_str_value(&job->info,ERROR,buffer); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); break; } Set_job_ticket_file(job, 0, fd ); } close(fd); goto exit; } } Errorcode = status = 0; Copy_job(&jcopy,job); if(DEBUGL2)Dump_job("Remote_job - jcopy", &jcopy ); if( lpd_bounce ){ if(DEBUGL2) Dump_job( "Remote_job - before filtering", &jcopy ); tempfd = Make_temp_fd(&tempfile); old_lp_value = safestrdup(Find_str_value( &PC_entry_line_list, "lp" ), __FILE__,__LINE__ ); Set_str_value( &PC_entry_line_list, LP, tempfile ); Print_job( tempfd, -1, &jcopy, 0, 0, 0 ); Set_str_value( &PC_entry_line_list, LP, old_lp_value ); if( old_lp_value ) free(old_lp_value); old_lp_value = 0; if( fstat( tempfd, &statb ) ){ logerr(LOG_INFO, "Remote_job: fstatb failed" ); status = JFAIL; } if( (close(tempfd) == -1 ) ){ status = JFAIL; logerr(LOG_INFO, "Remote_job: close(%d) failed", tempfd); } if( statb.st_size == 0 ){ logmsg( LOG_ERR, "Remote_job: zero length job after filtering"); status = JABORT; } if( status ) goto exit; job_size = statb.st_size; Free_listof_line_list(&jcopy.datafiles); lp = malloc_or_die(sizeof(lp[0]),__FILE__,__LINE__); memset(lp,0,sizeof(lp[0])); Check_max(&jcopy.datafiles,1); jcopy.datafiles.list[jcopy.datafiles.count++] = (void *)lp; Set_str_value(lp,OPENNAME,tempfile); firstfile = (void *)(job->datafiles.list[0]); s = Find_str_value( firstfile, DFTRANSFERNAME ); Set_str_value(lp,DFTRANSFERNAME,s); Set_str_value(lp,"N","(lpd_filter)"); Set_flag_value(lp,COPIES,1); Set_double_value(lp,SIZE,job_size); Fix_bq_format( 'f', lp ); } else if( !move_dest ) { int err = Errorcode; Errorcode = 0; if( Generate_banner_DYN ){ Add_banner_to_job( &jcopy ); } Filter_files_in_job( &jcopy, -1, 0 ); status = Errorcode; Errorcode = err; if( status ){ goto done; } } /* fix up the control file */ Fix_control( &jcopy, Control_filter_DYN, Xlate_format_DYN, 1 ); oldid = Find_str_value(&job->info,IDENTIFIER ); newid = Find_str_value(&jcopy.destination,IDENTIFIER ); if( newid == 0 ){ newid = Find_str_value(&jcopy.info,IDENTIFIER ); } n = Find_flag_value( &jcopy.info, DATAFILE_COUNT ); if( Max_datafiles_DYN > 0 && n > Max_datafiles_DYN ){ Errorcode = JABORT; fatal(LOG_ERR, _("Remote_job: %d datafiles and only allowed %d"), n, Max_datafiles_DYN ); } setmessage(job,STATE,"SENDING OLDID=%s NEWID=%s DEST=%s@%s", oldid, newid, RemotePrinter_DYN, RemoteHost_DYN ); if(DEBUGL3)Dump_job("Remote_job - after Fix_control", &jcopy ); status = Send_job( &jcopy, job, Connect_timeout_DYN, Connect_interval_DYN, Max_connect_interval_DYN, Send_job_rw_timeout_DYN, 0 ); DEBUG1("Remote_job: %s, status '%s'", id, Link_err_str(status) ); buffer[0] = 0; if(DEBUGL2)Dump_job("Remote_job - final jcopy value", &jcopy ); done: fd = -1; hf_name = Find_str_value(&job->info,HF_NAME); safestrncpy(buffer,hf_name); Get_job_ticket_file( &fd, job, buffer ); if( job->info.count == 0 ){ /* * you have removed the job! */ goto exit; } s = 0; if( status ){ s = Find_str_value(&jcopy.info,ERROR); if( !s ){ Set_str_value(&job->info,ERROR,"Mystery error from Send_job"); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } } s = 0; Free_job(&jcopy); switch( status ){ case JSUCC: case JABORT: case JFAIL: case JREMOVE: break; case LINK_ACK_FAIL: plp_snprintf(buffer,sizeof(buffer), _("link failure while sending job '%s'"), id ); s = buffer; status = JFAIL; break; case LINK_PERM_FAIL: plp_snprintf(buffer,sizeof(buffer), _("no permission to spool job '%s'"), id ); s = buffer; status = JREMOVE; break; default: plp_snprintf(buffer,sizeof(buffer), _("failed to send job '%s'"), id ); s = buffer; status = JFAIL; break; } if( s ){ if( !Find_str_value(&job->info,ERROR) ){ Set_str_value(&job->info,ERROR,s); } if( !Find_flag_value(&job->info,ERROR_TIME) ){ Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } } Set_str_value(&job->info,PRSTATUS,Server_status(status)); Set_job_ticket_file(job, 0, fd ); close(fd); fd = -1; if( Accounting_remote_DYN && Accounting_file_DYN ){ if( Accounting_end_DYN ){ Do_accounting( 1, Accounting_end_DYN, job, Connect_interval_DYN ); } } exit: return( status ); } /*************************************************************************** * Local_job() * Send a job to a local printer. ***************************************************************************/ static int Local_job( struct job *job, char *id ) { int status, fd, status_fd, pid, poll_for_status; char *old_lp_value; char buffer[SMALLBUFFER]; status_fd = fd = -1; DEBUG1("Local_job: starting %s", id ); setmessage(job,STATE,"PRINTING"); Errorcode = status = 0; Set_str_value(&job->info,PRSTATUS,0); Set_str_value(&job->info,ERROR,0); Set_flag_value(&job->info,ERROR_TIME,0); Setup_user_reporting(job); setstatus(job, "subserver pid %ld starting", (long)getpid()); if( Accounting_file_DYN && Local_accounting_DYN ){ setstatus(job, "accounting at start"); if( Accounting_start_DYN ){ status = Do_accounting( 0, Accounting_start_DYN, job, Connect_interval_DYN ); } DEBUG1("Local_job: accounting status %s", Server_status(status) ); if( status ){ plp_snprintf(buffer,sizeof(buffer), "accounting check failed '%s'", Server_status(status)); setstatus(job, "%s", buffer ); switch(status){ case JFAIL: break; case JHOLD: /* Set_flag_value(&job->info,HOLD_TIME,time((void *)0)); */ break; case JREMOVE: /* Set_flag_value(&job->info,REMOVE_TIME,time((void *)0)); */ break; default: Set_str_value(&job->info,ERROR,buffer); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); Set_job_ticket_file(job, 0, 0 ); break; } goto exit; } } Errorcode = status = 0; setstatus(job, "opening device '%s'", Lp_device_DYN); pid = 0; fd = Printer_open(Lp_device_DYN, &status_fd, job, Send_try_DYN, Connect_interval_DYN, Max_connect_interval_DYN, Connect_grace_DYN, Connect_timeout_DYN, &pid, &poll_for_status ); /* note: we NEVER return fd == 0 or horrible things have happened */ DEBUG1("Local_job: fd %d", fd ); if( fd <= 0 ){ status = JFAIL; goto exit; } setstatus(job, "printing job '%s'", id ); /* Print_job( output_device, status_device, job, timeout, poll_for_status, filter ) */ old_lp_value = safestrdup(Find_str_value( &PC_entry_line_list, LP ), __FILE__,__LINE__ ); Set_str_value( &PC_entry_line_list, LP, Lp_device_DYN ); status = Print_job( fd, status_fd, job, Send_job_rw_timeout_DYN, poll_for_status, 0 ); Set_str_value( &PC_entry_line_list, LP, old_lp_value ); if( old_lp_value ) free(old_lp_value); old_lp_value = 0; /* we close close device */ DEBUG1("Local_job: shutting down fd %d", fd ); fd = Shutdown_or_close( fd ); DEBUG1("Local_job: after shutdown fd %d, status_fd %d", fd, status_fd ); if( status_fd > 0 ){ /* we shut down this connection as well */ status_fd = Shutdown_or_close( status_fd ); /* we wait for eof on status_fd */ buffer[0] = 0; if( status_fd > 0 ){ Get_status_from_OF(job,"LP",pid, status_fd, buffer, sizeof(buffer)-1, Send_job_rw_timeout_DYN, 0, 0, Status_file_DYN ); } } if( fd > 0 ) close( fd ); fd = -1; if( status_fd > 0 ) close( status_fd ); status_fd = -1; if( pid > 0 ){ setstatus(job, "waiting for printer filter to exit"); status = Wait_for_pid( pid, "LP", 0, Send_job_rw_timeout_DYN ); } DEBUG1("Local_job: status %s", Server_status(status) ); Set_str_value(&job->info,PRSTATUS,Server_status(status)); if( Accounting_file_DYN && Local_accounting_DYN ){ setstatus(job, "accounting at end"); if( Accounting_end_DYN ){ Do_accounting( 1, Accounting_end_DYN, job, Connect_interval_DYN ); } } setstatus(job, "finished '%s', status '%s'", id, Server_status(status)); exit: if( fd != -1 ) close(fd); fd = -1; if( status_fd != -1 ) close(status_fd); status_fd = -1; return( status ); } static int Fork_subserver( struct line_list *server_info, int use_subserver, struct line_list *parms ) { char *pr; struct line_list *sp; int pid; struct line_list pl; Init_line_list(&pl); if( parms == 0 ) parms = &pl; sp = (void *)server_info->list[use_subserver]; Set_str_value(sp,PRSTATUS,0); Set_decimal_value(sp,SERVER,0); pr = Find_str_value(sp,PRINTER); Set_str_value(parms,PRINTER,pr); Set_flag_value(parms,SUBSERVER,use_subserver); DEBUG1( "Fork_subserver: starting '%s'", pr ); if(DEBUGL4)Dump_line_list("Fork_subserver - sp", sp ); if( use_subserver > 0 ){ pid = Start_worker( "queue", Service_queue, parms, 0 ); } else { pid = Start_worker( "printer", Service_worker, parms, 0 ); } if( pid > 0 ){ Set_decimal_value(sp,SERVER,pid); } else { logerr(LOG_ERR, _("Fork_subserver: fork failed") ); } Free_line_list(parms); return( pid ); } /*************************************************************************** * struct server_info *Wait_for_subserver( int timeout int pid, * struct line_list *servers, * wait for a server process to exit * if none present return 0 * look up the process in the process table * update the process table status * return the process table entry ***************************************************************************/ static void Wait_for_subserver( int timeout, int pid_to_wait_for, struct line_list *servers /*, struct line_list *order */ ) { pid_t pid; plp_status_t procstatus; int found, sigval, status, i, done, flags, fd; struct line_list *sp = 0; struct job job; char buffer[SMALLBUFFER], *pr, *hf_name, *id; flags = WNOHANG; if( pid_to_wait_for != -1 ){ flags = 0; } /* * wait for the process to finish or a signal to be delivered */ Init_job(&job); sigval = errno = 0; done = 0; fd = -1; again: DEBUG1("Wait_for_subserver: pid_to_wait_for %d, flags %d", pid_to_wait_for, flags ); if( fd > 0 ) close(fd); fd = -1; while( (pid = plp_waitpid( pid_to_wait_for, &procstatus, flags )) > 0 ){ ++done; if( fd > 0 ) close(fd); fd = -1; DEBUG1("Wait_for_subserver: pid %ld, status '%s'", (long)pid, Decode_status(&procstatus)); if( WIFSIGNALED( procstatus ) ){ sigval = WTERMSIG( procstatus ); DEBUG1("Wait_for_subserver: pid %ld terminated by signal '%s'", (long)pid, Sigstr( sigval ) ); switch( sigval ){ /* generated by the program */ case 0: case SIGINT: case SIGKILL: case SIGQUIT: case SIGTERM: case SIGUSR1: status = JFAIL; break; default: status = JSIGNAL; break; } } else { status = WEXITSTATUS( procstatus ); if( status > 0 && status < 32 ) status += JFAIL-1; } DEBUG1( "Wait_for_subserver: pid %ld final status %s", (long)pid, Server_status(status) ); if( status != JSIGNAL ){ plp_snprintf(buffer,sizeof(buffer), _("subserver pid %ld exit status '%s'"), (long)pid, Server_status(status)); } else { plp_snprintf(buffer,sizeof(buffer), _("subserver pid %ld died with signal '%s'"), (long)pid, Sigstr(sigval)); status = JABORT; } if(DEBUGL4) Dump_subserver_info("Wait_for_subserver", servers ); for( found = i = 0; !found && i < servers->count; ++i ){ if( fd > 0 ) close(fd); fd = -1; sp = (void *)servers->list[i]; if( pid == Find_flag_value(sp,SERVER) ){ DEBUG3("Wait_for_subserver: found %ld", (long)pid ); found = 1; ++done; Free_job(&job); Set_decimal_value(sp,SERVER,0); Set_flag_value(sp,DONE_TIME,time((void *)0)); /* we get the job ticket file information */ hf_name = Find_str_value(sp,HF_NAME); Get_job_ticket_file( &fd, &job, hf_name ); if( !job.info.count ) continue; /* Setup_cf_info( &job, 0 ); */ pr = Find_str_value(sp,PRINTER); id = Find_str_value(sp,IDENTIFIER); DEBUG1( "Wait_for_subserver: server pid %ld for '%s' for '%s' '%s' finished", (long)pid, pr, hf_name, id ); /* see if you can get the job ticket file and update the status */ Update_status( fd, &job, status ); Set_str_value(sp,HF_NAME,0); Set_str_value(sp,IDENTIFIER,0); Update_spool_info(sp); if( i == 0 ){ /* this is the information for the master spool queue */ Get_spool_control(Queue_control_file_DYN, &Spool_control ); } } } if( fd > 0 ) close(fd); fd = -1; Free_job(&job); /* sort server order */ if( Mergesort( servers->list+1, servers->count-1, sizeof( servers->list[0] ), cmp_server, 0 ) ){ fatal(LOG_ERR, _("Wait_for_subserver: Mergesort failed") ); } if(DEBUGL4) Dump_subserver_info( "Wait_for_subserver: after sorting", servers ); if( pid_to_wait_for != -1 ) break; } if( fd > 0 ) close(fd); fd = -1; if( !done ){ if( pid_to_wait_for != -1){ Errorcode = JABORT; fatal(LOG_ERR, _("Wait_for_subserver: LOGIC ERROR! waiting for pid %d failed"), pid_to_wait_for ); } /* we need to unblock signals and wait for event */ Chld = 0; Set_timeout_break( timeout ); (void) plp_signal(SIGCHLD, (plp_sigfunc_t)Sigchld); plp_sigpause(); Clear_timeout(); signal( SIGCHLD, SIG_DFL ); if( Chld ) goto again; } Free_job(&job); } /*************************************************************************** * int Decode_transfer_failure( int attempt, struct job *job, int status ) * When you get a job failure more than a certain number of times, * you check the 'Send_failure_action_DYN' variable * This can be abort, retry, or remove * If retry, you keep retrying; if abort you shut the queue down; * if remove, you remove the job and try again. ***************************************************************************/ static struct keywords keys[] = { {"succ", N_("succ"), INTEGER_K, (void *)0, JSUCC,0,0}, {"jsucc", N_("jsucc"), INTEGER_K, (void *)0, JSUCC,0,0}, {"success", N_("success"), INTEGER_K, (void *)0, JSUCC,0,0}, {"jsuccess", N_("jsuccess"), INTEGER_K, (void *)0, JSUCC,0,0}, {"abort", N_("abort"), INTEGER_K, (void *)0, JABORT,0,0}, {"jabort", N_("jabort"), INTEGER_K, (void *)0, JABORT,0,0}, {"hold", N_("hold"), INTEGER_K, (void *)0, JHOLD,0,0}, {"jhold", N_("jhold"), INTEGER_K, (void *)0, JHOLD,0,0}, {"remove", N_("remove"), INTEGER_K, (void *)0, JREMOVE,0,0}, {"jremove", N_("jremove"), INTEGER_K, (void *)0, JREMOVE,0,0}, { 0,0,0,0,0,0,0 } }; static int Decode_transfer_failure( int attempt, struct job *job ) { struct keywords *key; int result, n, len, c; char line[SMALLBUFFER], *outstr; result = JREMOVE; outstr = Send_failure_action_DYN; if( outstr ) while( isspace(cval(outstr)) ) ++outstr; DEBUG1("Decode_transfer_failure: send_failure_action '%s'", outstr ); if( outstr && cval(outstr) == '|' ){ /* check to see if it is a filter */ int out_tempfd, in_tempfd; outstr = 0; plp_snprintf( line, sizeof(line), "%d\n", attempt ); out_tempfd = Make_temp_fd( 0); in_tempfd = Make_temp_fd( 0); if( Write_fd_str(in_tempfd,line) < 0 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Decode_transfer_failure: write(%d) failed", in_tempfd); } if( lseek(in_tempfd,0,SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Decode_transfer_failure: fseek(%d) failed", in_tempfd); } n = Filter_file( Send_query_rw_timeout_DYN, in_tempfd, out_tempfd, "TRANSFER_FAILURE", Send_failure_action_DYN, Filter_options_DYN, job, 0, 1 ); DEBUG1("Decode_transfer_failure: exit status %s", Server_status(n)); if( n ){ result = n; setstatus( job, "send_failure_action filter exit status '%s'", Server_status(result) ); } else { if( lseek(out_tempfd,0,SEEK_SET) == -1 ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Decode_transfer_failure: fseek(%d) failed", out_tempfd); } len = ok_read( out_tempfd, line,sizeof(line)-1 ); if( len >= 0 ){ line[len] = 0; } else { Errorcode = JFAIL; logerr_die(LOG_INFO, "Decode_transfer_failure: read(%d) failed", out_tempfd); } while( (c = cval(line)) && strchr( Whitespace, c) ){ memmove( line, line+1, safestrlen(line+1)+1 ); } while( (len = safestrlen(line)) && (c = cval(line+len-1)) && strchr( Whitespace, c) ){ line[len-1] = 0; } setstatus( job, "send_failure_action filter returned '%s'", outstr ); } close( out_tempfd ); out_tempfd = -1; close( in_tempfd ); in_tempfd = -1; } if( outstr && *outstr ){ DEBUG1("Decode_transfer_failure: outstr '%s'", outstr ); for( key = keys; key->keyword; ++key ){ DEBUG1("Decode_transfer_failure: comparing '%s' to '%s'", outstr, key->keyword ); if( safestrcasecmp( key->keyword, outstr ) == 0 ){ result = key->maxval; break; } } } DEBUG1("Decode_transfer_failure: result '%s'", Server_status(result) ); setstatus( job, "send_failure_action '%s'", Server_status(result) ); return( result ); } static void Update_status( int fd, struct job *job, int status ) { char buffer[SMALLBUFFER]; char *id, *did, *strv, *hf_name; struct line_list *destination; int copy, copies, attempt, destinations, n, done = 0; did = 0; destinations = 0; destination = 0; Set_decimal_value(&job->info,SERVER,0); id = Find_str_value(&job->info,IDENTIFIER); if( !id ){ if(DEBUGL1)Dump_job("Update_status - no ID", job ); return; } destinations = Find_flag_value(&job->info,DESTINATIONS); DEBUG1("Update_status: id '%s', destinations %d", id, destinations ); if( destinations ){ did = Find_str_value(&job->info,DESTINATION ); DEBUG1("Update_status: id '%s', destinations %d, DESTINATION '%s'", id, destinations, did ); if( !Get_destination_by_name( job, did ) ){ destination = &job->destination; did = Find_str_value(destination,IDENTIFIER); if(!did) did = Find_str_value(destination,XXCFTRANSFERNAME); if(!did) did = Find_str_value(destination,HF_NAME); Set_decimal_value(destination,SERVER,0); } } setmessage(job,STATE,"EXITSTATUS %s", Server_status(status)); again: DEBUG1("Update_status: again - status '%s', id '%s', dest id '%s'", Server_status(status), id, did ); setmessage(job,STATE,"PROCESSSTATUS %s", Server_status(status)); switch( status ){ /* hold the destination stuff */ case JHOLD: if( destination ){ Set_flag_value(destination,HOLD_TIME,time((void *)0) ); Update_destination(job); } else { Set_flag_value(&job->info,HOLD_TIME, time((void *)0) ); Set_flag_value(&job->info,PRIORITY_TIME, 0 ); } Set_job_ticket_file( job, 0, fd ); break; case JSUCC: /* successful, remove job */ if(DEBUGL3)Dump_job("Update_status - JSUCC start", job ); if( destination ){ done = 0; copies = Find_flag_value(&job->info,SEQUENCE); Set_flag_value(&job->info,SEQUENCE,copies+1); copies = Find_flag_value(destination,COPIES); copy = Find_flag_value(destination,COPY_DONE); n = Find_flag_value(destination,DESTINATION); if( Find_str_value(destination,MOVE) ){ Set_flag_value(destination,DONE_TIME,time((void *)0)); setstatus( job, "%s@%s: route job '%s' moved", Printer_DYN, FQDNHost_FQDN, did ); done = 1; } else { ++copy; Set_flag_value(destination,COPY_DONE,copy); if( copies ){ setstatus( job, "%s@%s: route job '%s' printed copy %d of %d", Printer_DYN, FQDNHost_FQDN, id, copy, copies ); } if( copy >= copies ){ Set_flag_value(destination,DONE_TIME,time((void *)0)); done = 1; ++n; } } Update_destination(job); id = Find_str_value(&job->info,IDENTIFIER); if( done && n >= destinations ){ Set_flag_value(&job->info,DONE_TIME,time((void *)0)); setstatus( job, "%s@%s: job '%s' printed", Printer_DYN, FQDNHost_FQDN, id ); goto done_job; } Set_job_ticket_file( job, 0, fd ); break; } else { copies = Find_flag_value(&job->info,COPIES); copy = Find_flag_value(&job->info,COPY_DONE); id = Find_str_value(&job->info,IDENTIFIER); if( !id ){ Errorcode = JABORT; fatal(LOG_ERR, _("Update_status: no identifier for '%s'"), Find_str_value(&job->info,HF_NAME) ); } if( Find_str_value(&job->info,MOVE) ){ Set_flag_value(&job->info,DONE_TIME,time((void *)0)); setstatus( job, "%s@%s: job '%s' moved", Printer_DYN, FQDNHost_FQDN, id ); } else { ++copy; Set_flag_value(&job->info,COPY_DONE,copy); if( copies ){ setstatus( job, "%s@%s: job '%s' printed copy %d of %d", Printer_DYN, FQDNHost_FQDN, id, copy, copies ); } if( copy >= copies ){ Set_flag_value(&job->info,DONE_TIME,time((void *)0)); Sendmail_to_user( status, job ); setstatus( job, "%s@%s: job '%s' printed", Printer_DYN, FQDNHost_FQDN, id ); } else { Set_job_ticket_file( job, 0, fd ); break; } } done_job: hf_name = Find_str_value(&job->info,HF_NAME); DEBUG3("Update_status: done_job, id '%s', hf '%s'", id, hf_name ); if( hf_name ){ Set_flag_value(&job->info,REMOVE_TIME,time((void *)0)); Set_job_ticket_file( job, 0, fd ); if(DEBUGL3)Dump_job("Update_status - done_job", job ); if( (Save_when_done_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( job, _("job '%s' saved"), id ); ++Done_count; if( !Done_time ) Done_time = time(0); } else { if( Remove_job( job ) ){ setstatus( job, _("could not remove job '%s'"), id); } else { setstatus( job, _("job '%s' removed"), id ); } } } } break; case JTIMEOUT: case JFAIL: /* failed, retry ?*/ status = JFAIL; if( destination ){ attempt = Find_flag_value(destination,ATTEMPT); ++attempt; Set_flag_value(destination,ATTEMPT,attempt); Update_destination(job); } else { attempt = Find_flag_value(&job->info,ATTEMPT); ++attempt; Set_flag_value(&job->info,ATTEMPT,attempt); } DEBUG1( "Update_status: JFAIL - attempt %d, max %d", attempt, Send_try_DYN ); Set_job_ticket_file( job, 0, fd ); if( Send_try_DYN > 0 && attempt >= Send_try_DYN ){ char buf[60]; /* check to see what the failure action * should be - abort, failure; default is remove */ setstatus( job, _("job '%s', attempt %d, allowed %d"), id, attempt, Send_try_DYN ); status = Decode_transfer_failure( attempt, job ); switch( status ){ case JSUCC: strv = _("treating as successful"); break; case JFAIL: strv = _("retrying job"); break; case JFAILNORETRY: strv = _("no retry"); break; case JABORT: strv = _("aborting server"); break; case JREMOVE: strv = _("removing job - status JREMOVE"); break; case JHOLD: strv = _("holding job"); break; default: plp_snprintf( buf, sizeof(buf), _("unexpected status 0x%x"), status ); strv = buf; status = JABORT; break; } setstatus( job, _("job '%s', %s"), id, strv ); } if( status == JFAIL ){ if( Send_try_DYN > 0 ){ setstatus( job, _("job '%s' attempt %d, trying %d times"), id, attempt, Send_try_DYN ); } else { setstatus( job, _("job '%s' attempt %d, trying indefinitely"), id, attempt); } if( destination ){ Set_str_value(destination,ERROR,0); Set_flag_value(destination,ERROR_TIME,0); Set_str_value(destination,PRSTATUS,0); } else { Set_str_value(&job->info,ERROR,0); Set_flag_value(&job->info,ERROR_TIME,0); Set_str_value(&job->info,PRSTATUS,0); } Set_job_ticket_file( job, 0, fd ); } else { goto again; } break; case JFAILNORETRY: /* do not try again */ plp_snprintf( buffer, sizeof(buffer), _("failed, no retry") ); if( destination ){ attempt = Find_flag_value(destination,ATTEMPT); ++attempt; if( !Find_str_value(destination,ERROR) ){ Set_str_value(destination,ERROR,buffer); } if( !Find_flag_value(destination,ERROR_TIME) ){ Set_nz_flag_value(destination,ERROR_TIME,time(0)); } Set_flag_value(destination,ATTEMPT,attempt); Update_destination(job); Set_job_ticket_file( job, 0, fd ); } else { attempt = Find_flag_value(&job->info,ATTEMPT); ++attempt; Set_flag_value(&job->info,ATTEMPT,attempt); if( !Find_str_value(&job->info,ERROR) ){ Set_str_value(&job->info,ERROR,buffer); } if( !Find_flag_value(&job->info,ERROR_TIME) ){ Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } Set_nz_flag_value(&job->info,REMOVE_TIME, time( (void *)0) ); Set_job_ticket_file( job, 0, fd ); Sendmail_to_user( status, job ); if( (Save_on_error_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( job, _("job '%s' saved"), id ); ++Done_count; if( !Done_time ) Done_time = time(0); } else { setstatus( job, _("removing job '%s' - JFAILNORETRY"), id); if( Remove_job( job ) ){ setstatus( job, _("could not remove job '%s'"), id); } else { setstatus( job, _("job '%s' removed"), id ); } } } break; default: case JABORT: /* abort, do not try again */ plp_snprintf(buffer,sizeof(buffer), _("aborting operations") ); Set_flag_value(&job->info,PRIORITY_TIME,0); if( destination ){ if( !Find_str_value(destination,ERROR) ){ Set_str_value(destination,ERROR,buffer); } if( !Find_flag_value(destination,ERROR_TIME) ){ Set_nz_flag_value(destination,ERROR_TIME,time(0)); } strv = Find_str_value(destination,ERROR); Update_destination(job); setstatus( job, "job '%s', destination '%s', error '%s'", id,did,strv ); } else { if( !Find_str_value(&job->info,ERROR) ){ Set_str_value(&job->info,ERROR,buffer); } if( !Find_flag_value(&job->info,ERROR_TIME) ){ Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } strv = Find_str_value(&job->info,ERROR); setstatus( job, "job '%s' error '%s'",id, strv); Set_nz_flag_value(&job->info,REMOVE_TIME, time( (void *)0) ); Set_job_ticket_file( job, 0, fd ); Sendmail_to_user( status, job ); if( (Save_on_error_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( job, _("job '%s' saved"), id ); ++Done_count; if( !Done_time ) Done_time = time(0); } else { setstatus( job, _("removing job '%s' - JABORT"), id); if( Remove_job( job ) ){ setstatus( job, _("could not remove job '%s'"), id); } else { setstatus( job, _("job '%s' removed"), id ); } } } if( Stop_on_abort_DYN ){ setstatus( job, _("stopping printing on filter JABORT exit code") ); Set_flag_value( &Spool_control,PRINTING_ABORTED,1 ); Set_spool_control(0, Queue_control_file_DYN, &Spool_control); } break; case JREMOVE: /* failed, remove job */ if( destination ){ if( !Find_str_value(destination,ERROR) ){ plp_snprintf( buffer, sizeof(buffer), _("removing destination due to errors") ); Set_str_value(destination,ERROR,buffer); } if( !Find_flag_value(destination,ERROR_TIME) ){ Set_nz_flag_value(destination,ERROR_TIME,time(0)); } Update_destination(job); Set_job_ticket_file( job, 0, fd ); } else { if( !Find_str_value(&job->info,ERROR) ){ plp_snprintf( buffer, sizeof(buffer), _("too many errors") ); Set_str_value(&job->info,ERROR,buffer); } if( !Find_flag_value(&job->info,ERROR_TIME) ){ Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); } Set_nz_flag_value(&job->info,REMOVE_TIME, time( (void *)0) ); Set_job_ticket_file( job, 0, fd ); Sendmail_to_user( status, job ); if( (Save_on_error_DYN || Done_jobs_DYN || Done_jobs_max_age_DYN) ){ setstatus( job, _("job '%s' saved"), id ); ++Done_count; if( !Done_time ) Done_time = time(0); } else { setstatus( job, _("removing job '%s' - JREMOVE"), id); if( Remove_job( job ) ){ setstatus( job, _("could not remove job '%s'"), id); } else { setstatus( job, _("job '%s' removed"), id ); } } } break; } if(DEBUGL3)Dump_job("Update_status: exit result", job ); } /*************************************************************************** * int Check_print_perms * check the printing permissions ***************************************************************************/ static int Check_print_perms( struct job *job ) { char *s; int permission; memset( &Perm_check, 0, sizeof(Perm_check) ); Perm_check.service = 'P'; Perm_check.printer = Printer_DYN; Perm_check.user = Find_str_value(&job->info,LOGNAME); Perm_check.remoteuser = Perm_check.user; Perm_check.authuser = Find_str_value(&job->info,AUTHUSER); Perm_check.authfrom = Find_str_value(&job->info,AUTHFROM); Perm_check.authtype = Find_str_value(&job->info,AUTHTYPE); Perm_check.authca = Find_str_value(&job->info,AUTHCA); s = Find_str_value(&job->info,FROMHOST); if( s && Find_fqdn( &PermHost_IP, s ) ){ Perm_check.host = &PermHost_IP; } s = Find_str_value(&job->info,REMOTEHOST); if( s && Find_fqdn( &RemoteHost_IP, s ) ){ Perm_check.remotehost = &RemoteHost_IP; } else { Perm_check.remotehost = Perm_check.host; } Perm_check.unix_socket = Find_flag_value(&job->info,UNIXSOCKET); Perm_check.port = Find_flag_value(&job->info,REMOTEPORT); permission = Perms_check( &Perm_line_list,&Perm_check, job, 1 ); DEBUG3("Check_print_perms: permission '%s'", perm_str(permission) ); return( permission ); } static void Setup_user_reporting( struct job *job ) { char *host = Find_str_value(&job->info,MAILNAME); char *port = 0, *s; const char *protocol = "UDP"; int prot_num = SOCK_DGRAM; char errmsg[SMALLBUFFER]; DEBUG1("Setup_user_reporting: Allow_user_logging %d, host '%s'", Allow_user_logging_DYN, host ); if( !Allow_user_logging_DYN || host==0 || safestrchr(host,'@') || !safestrchr(host,'%') ){ return; } host = safestrdup(host,__FILE__,__LINE__); /* OK, we try to open a connection to the logger */ if( (s = safestrchr( host, '%')) ){ /* *s++ = 0; */ port = s; } if( (s = safestrchr( port, ',')) ){ *s++ = 0; protocol = s; if( safestrcasecmp( protocol, "TCP" ) == 0 ){ protocol = "TCP"; prot_num = SOCK_STREAM; } } DEBUG3("setup_logger_fd: host '%s', port '%s', protocol %d", host, port, prot_num ); Mail_fd = Link_open_type(host, 10, prot_num, 0, 0, errmsg, sizeof(errmsg) ); DEBUG3("Setup_user_reporting: Mail_fd '%d'", Mail_fd ); if( Mail_fd > 0 && prot_num == SOCK_STREAM && Exit_linger_timeout_DYN > 0 ){ Set_linger( Mail_fd, Exit_linger_timeout_DYN ); } if( host ) free(host); host = 0; } void Service_worker( struct line_list *args, int param_fd UNUSED ) { int pid, unspooler_fd, destinations, attempt, n, lpd_bounce; struct line_list *destination; char *s, *path, *hf_name, *new_dest, *move_dest, *id, *did; struct stat statb; char buffer[SMALLBUFFER]; struct job job; int fd = -1; Name="(Worker)"; destination = 0; attempt = 0; Init_job(&job); Set_DYN(&Printer_DYN, Find_str_value(args,PRINTER)); setproctitle( "lpd %s '%s'", Name, Printer_DYN ); DEBUG1("Service_worker: begin"); (void) plp_signal(SIGUSR1, (plp_sigfunc_t)cleanup_USR1); Errorcode = JABORT; /* you need to have a spool queue */ if( Setup_printer( Printer_DYN, buffer, sizeof(buffer), 0 ) ){ cleanup(0); } if(DEBUGL4){ int fd; fd = dup(0); LOGDEBUG("Service_worker: after Setup_printer next fd %d",fd); close(fd); }; pid = getpid(); DEBUG1( "Service_worker: pid %d", pid ); path = Make_pathname( Spool_dir_DYN, Queue_unspooler_file_DYN ); if( (unspooler_fd = Checkwrite( path, &statb, O_RDWR, 1, 0 )) < 0 ){ logerr_die(LOG_ERR, _("Service_worker: cannot open lockfile '%s'"), path ); } if(path) free(path); path = 0; Write_pid( unspooler_fd, pid, (char *)0 ); close(unspooler_fd); unspooler_fd = -1; DEBUG3("Service_worker: checking path '%s'", path ); hf_name = Find_str_value(args,HF_NAME); Get_job_ticket_file( &fd, &job, hf_name ); if( !job.info.count ){ DEBUG3("Service_worker: missing files"); Errorcode = 0; cleanup(0); } Set_str_value(&job.info,NEW_DEST, Find_str_value(args,NEW_DEST)); Set_str_value(&job.info,MOVE_DEST, Find_str_value(args,MOVE_DEST)); Set_decimal_value(&job.info,SERVER,getpid()); Free_line_list(args); n = Set_job_ticket_file( &job, 0, fd ); if( n ){ /* you cannot update job ticket file!! */ setstatus( &job, _("cannot update job ticket file for '%s'"), hf_name ); fatal(LOG_ERR, _("Service_worker: cannot update job ticket file for '%s'"), hf_name ); } if( fd > 0 ) close(fd); fd = -1; id = Find_str_value(&job.info,IDENTIFIER); if( !id ){ fatal(LOG_ERR, _("Service_worker: no identifier for '%s'"), Find_str_value(&job.info,HF_NAME) ); } if( (destinations = Find_flag_value(&job.info,DESTINATIONS)) ){ did = Find_str_value(&job.info,DESTINATION ); if( !Get_destination_by_name( &job, did ) ){ destination = &job.destination; attempt = Find_flag_value(destination,ATTEMPT); } } else { attempt = Find_flag_value(&job.info,ATTEMPT); } DEBUG3("Service_worker: attempt %d", attempt ); new_dest = Find_str_value(&job.info,NEW_DEST); move_dest = Find_str_value(&job.info,MOVE_DEST); lpd_bounce = Lpd_bounce_DYN; if( move_dest ){ lpd_bounce = 0; new_dest = move_dest; } /* * The following code is implementing job handling as follows. * if new_dest has a value then * new_dest has format 'pr' or 'pr@host' * if pr@host then * set RemotePrinter_DYN and RemoteHost_DYN * else * set RemotePrinter_DYN to pr * set RemoteHost_DYN to FQDNHost_FQDN */ if( new_dest ){ Set_DYN( &RemoteHost_DYN, 0); Set_DYN( &RemotePrinter_DYN, 0); Set_DYN( &Lp_device_DYN, 0); Set_DYN( &RemotePrinter_DYN, new_dest ); if( (s = safestrchr(RemotePrinter_DYN, '@')) ){ *s++ = 0; Set_DYN( &RemoteHost_DYN, s ); if( (s = safestrchr(s,'%')) ){ *s++ = 0; Set_DYN( &Lpd_port_DYN,s ); } } if( !RemoteHost_DYN ){ Set_DYN( &RemoteHost_DYN, LOCALHOST); } } /* we put a timeout before each attempt */ if( attempt > 0 ){ n = 8; if( attempt < n ) n = attempt; n = Connect_interval_DYN * (1 << (n-1)) + Connect_grace_DYN; if( Max_connect_interval_DYN > 0 && n > Max_connect_interval_DYN ){ n = Max_connect_interval_DYN; } DEBUG1("Service_worker: attempt %d, sleeping %d", attempt, n); if( n > 0 ){ setstatus( &job, "attempt %d, sleeping %d before retry", attempt+1, n ); plp_sleep(n); } } if( RemotePrinter_DYN ){ Name = "(Worker - Remote)"; DEBUG1( "Service_worker: sending '%s' to '%s@%s'", id, RemotePrinter_DYN, RemoteHost_DYN ); setproctitle( "lpd %s '%s'", Name, Printer_DYN ); if( Remote_support_DYN ) uppercase( Remote_support_DYN ); if( safestrchr( Remote_support_DYN, 'R' ) ){ Errorcode = Remote_job( &job, lpd_bounce, move_dest, id ); } else { Errorcode = JABORT; setstatus( &job, "no remote support to `%s@%s'", RemotePrinter_DYN, RemoteHost_DYN ); } } else { Name = "(Worker - Print)"; DEBUG1( "Service_worker: printing '%s'", id ); setproctitle( "lpd %s '%s'", Name, Printer_DYN ); Errorcode = Local_job( &job, id ); } cleanup(0); } /* * Filter all the files in the print job */ static void Filter_files_in_job( struct job *job, int outfd, char *user_filter ) { struct line_list *datafile; char *tempfile, *openname, *s, *filter, *id, *old_lp_value; const char *format; char filter_name[8], filter_title[64], msg[SMALLBUFFER], filtermsgbuffer[SMALLBUFFER]; struct stat statb; int tempfd, fd, n, pid, count, if_error[2]; struct line_list files; Init_line_list(&files); DEBUG1("Filter_files_in_job: starting, user_filter '%s'", user_filter); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Filter_files_in_job: START open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } Errorcode = 0; old_lp_value = safestrdup(Find_str_value( &PC_entry_line_list, "lp" ), __FILE__,__LINE__ ); id = Find_str_value(&job->info,IDENTIFIER); tempfd = -1; for( count = 0; count < job->datafiles.count; ++count ){ datafile = (void *)job->datafiles.list[count]; if(DEBUGL4)Dump_line_list("Filter_files_in_job - datafile", datafile ); openname = Find_str_value(datafile,OPENNAME); if( !openname ) openname = Find_str_value(datafile,DFTRANSFERNAME); format = Find_str_value(datafile,FORMAT); Set_str_value(&job->info,FORMAT,format); Set_str_value(&job->info,DF_NAME,openname); Set_str_value(&job->info,"N", Find_str_value(datafile,"N") ); /* * now we check to see if there is an input filter */ plp_snprintf(filter_name,sizeof(filter_name), "%s","if"); filter_name[0] = cval(format); filter = user_filter; switch( cval(format) ){ case 'p': case 'f': case 'l': filter_name[0] = 'i'; if( !filter ) filter = IF_Filter_DYN; break; case 'a': case 'i': case 'o': case 's': setstatus(job, "bad data file format '%c', using 'f' format", cval(format) ); filter_name[0] = 'i'; format = "f"; if( !filter ) filter = IF_Filter_DYN; break; } if( !filter ){ filter = Find_str_value(&PC_entry_line_list, filter_name); } if( !filter){ filter = Find_str_value(&Config_line_list,filter_name ); } if( filter == 0 ) filter = Filter_DYN; if( filter == 0 ) filter = IF_Filter_DYN; DEBUG3("Filter_files_in_job: format '%s', filter '%s'", format, filter ); if( filter == 0 ){ continue; } uppercase(filter_name); if( filter ){ s = filter; if( cval(s) == '(' ){ ++s; while( isspace(cval(s))) ++s; } else { if( !(s = strchr(filter,'/')) ) s = filter; } plp_snprintf(msg, sizeof(msg), "%s", s ); if( (s = strpbrk(msg,Whitespace)) ) *s = 0; if( (s = strrchr(msg,'/')) ) memmove(msg,s+1,safestrlen(s+1)+1); } plp_snprintf(filter_title,sizeof(filter_title), "%s filter '%s'", filter_name, msg ); if( (fd = Checkread( openname, &statb )) < 0 ){ Errorcode = JFAIL; logmsg( LOG_ERR, "Filter_files_in_job: job '%s', cannot open data file '%s'", id, openname ); goto end_of_job; } setstatus(job, "processing '%s', size %0.0f, format '%s', %s", openname, (double)statb.st_size, format, filter_title ); if( cval(format) == 'p' ){ DEBUG3("Filter_files_in_job: using 'p' formatter '%s'", Pr_program_DYN ); setstatus(job, "format 'p' pretty printer '%s'", Pr_program_DYN); if( Pr_program_DYN == 0 ){ setstatus(job, "no 'p' format filter available" ); Errorcode = JABORT; goto end_of_job; } tempfd = Make_temp_fd(&tempfile); Set_str_value(datafile,OPENNAME,tempfile); n = Filter_file( Send_job_rw_timeout_DYN, fd, tempfd, "PR_PROGRAM", Pr_program_DYN, 0, job, 0, 1 ); if( n ){ Errorcode = JABORT; logerr(LOG_INFO, "Filter_files_in_job: could not make '%s' process", Pr_program_DYN ); goto end_of_job; } close(fd); fd = tempfd; tempfd = -1; if( fstat(fd, &statb ) == -1 ){ Errorcode = JABORT; logerr(LOG_INFO, "Filter_files_in_job: fstat() failed"); } setstatus(job, "data file '%s', size now %0.0f", openname, (double)statb.st_size ); format = "f"; Set_str_value(datafile,FORMAT,format); } if( filter ){ DEBUG3("Filter_files_in_job: format '%s' starting filter '%s'", format, filter ); DEBUG2("Filter_files_in_job: filter_stderr_to_status_file %d, ps '%s'", Filter_stderr_to_status_file_DYN, Status_file_DYN ); if_error[0] = if_error[1] = -1; if( Filter_stderr_to_status_file_DYN && Status_file_DYN && *Status_file_DYN ){ if_error[1] = Checkwrite( Status_file_DYN, &statb, O_WRONLY|O_APPEND, 0, 0 ); } else if( pipe( if_error ) == -1 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Filter_files_in_job: pipe() failed"); goto end_of_job; } Max_open(if_error[0]); Max_open(if_error[1]); DEBUG3("Filter_files_in_job: %s fd if_error[%d,%d]", filter_title, if_error[0], if_error[1] ); s = 0; if( Backwards_compatible_filter_DYN ) s = BK_filter_options_DYN; if( s == 0 ) s = Filter_options_DYN; Free_line_list(&files); Check_max(&files, 10 ); files.list[files.count++] = Cast_int_to_voidstar(fd); /* stdin */ if( outfd > 0 ){ files.list[files.count++] = Cast_int_to_voidstar(outfd); /* stdout */ } else { tempfd = Make_temp_fd(&tempfile); Set_str_value( &PC_entry_line_list, LP, tempfile ); Set_str_value(datafile,OPENNAME,tempfile); files.list[files.count++] = Cast_int_to_voidstar(tempfd); /* stdout */ } files.list[files.count++] = Cast_int_to_voidstar(if_error[1]); /* stderr */ if( (pid = Make_passthrough( filter, s, &files, job, 0 )) < 0 ){ Errorcode = JFAIL; logerr(LOG_INFO, "Filter_files_in_job: could not make %s process", filter_title ); goto end_of_job; } files.count = 0; Free_line_list(&files); if( fd > 0 ) close(fd); fd = -1; if( tempfd > 0 ) close(tempfd); tempfd = -1; if( (close(if_error[1]) == -1 ) ){ Errorcode = JFAIL; logerr_die(LOG_INFO, "Filter_files_in_job: X5 close(%d) failed", if_error[1]); } if_error[1] = -1; Init_buf(&Outbuf, &Outmax, &Outlen ); filtermsgbuffer[0] = 0; if( if_error[0] != -1 ){ n = Get_status_from_OF(job,filter_title,pid, if_error[0], filtermsgbuffer, sizeof(filtermsgbuffer)-1, 0, 0, 0, Status_file_DYN ); if( filtermsgbuffer[0] ){ setstatus(job, "%s filter msg - '%s'", filter_title, filtermsgbuffer ); } if( n ){ Errorcode = n; setstatus(job, "%s filter problems, error '%s'", filter_title, Server_status(n)); goto end_of_job; } close(if_error[0]); if_error[0] = -1; } /* now we get the exit status for the filter */ n = Wait_for_pid( pid, filter_title, 0, 0 ); if( n ){ Errorcode = n; setstatus(job, "%s filter exit status '%s'", filter_title, Server_status(n)); goto end_of_job; } setstatus(job, "%s filter finished", filter_title ); Fix_bq_format( cval(format), datafile ); } DEBUG3("Filter_files_in_job: finished file"); } end_of_job: if( old_lp_value ) free( old_lp_value ); old_lp_value = 0; Free_line_list(&files); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Filter_files_in_job: END open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } if(DEBUGL3)Dump_job("Filter_files_in_job", job); } void Service_queue( struct line_list *args, int param_fd UNUSED ) { int subserver; Set_DYN(&Printer_DYN, Find_str_value(args, PRINTER) ); subserver = Find_flag_value( args, SUBSERVER ); Free_line_list(args); Do_queue_jobs( Printer_DYN, subserver ); cleanup(0); } int Remove_done_jobs( void ) { struct job job; char *id; int removed = 0, last_remove = 0, remove_count = 0, fd; time_t tm; int job_index, info_index, pid, remove, error, done, incoming; struct line_list info; char tval[SMALLBUFFER]; DEBUG3("Remove_done_jobs: save_when_done %d, save_on_error %d, done_jobs %d, d_j_max_age %d", Save_when_done_DYN, Save_on_error_DYN, Done_jobs_DYN, Done_jobs_max_age_DYN ); if( Save_when_done_DYN || Save_on_error_DYN || !(Done_jobs_DYN > 0 || Done_jobs_max_age_DYN > 0) ){ return( 0 ); } Init_line_list(&info); time( &tm ); Init_job(&job); fd = -1; for( job_index = 0; job_index < Sort_order.count; ++job_index ){ char *job_ticket_file = Sort_order.list[job_index]; Free_job(&job); if( fd > 0 ) close(fd); fd = -1; if( ISNULL(job_ticket_file) ) continue; DEBUG3("Remove_done_jobs: done_jobs - job_index [%d] '%s'", job_index, job_ticket_file); Get_job_ticket_file( &fd, &job, job_ticket_file ); if(DEBUGL4)Dump_job("Remove_done_jobs: done_jobs - job ",&job); if( job.info.count == 0 ) continue; /* get status from job ticket file */ id = Find_str_value(&job.info,IDENTIFIER); done = Find_flag_value(&job.info,DONE_TIME); error = Find_flag_value(&job.info,ERROR_TIME); incoming = Find_flag_value(&job.info,INCOMING_TIME); pid = Find_flag_value(&job.info,INCOMING_PID); remove = Find_flag_value(&job.info,REMOVE_TIME); DEBUG3("Remove_done_jobs: remove 0x%x, done 0x%x, error 0x%x, incoming 0x%x", remove, done, error, incoming ); if( incoming && pid && kill( pid, 0 ) ){ /* we have a stale incoming job */ Remove_job( &job ); continue; } if( !(remove || (error && !Save_on_error_DYN)) ) continue; if( last_remove != remove ){ remove_count = 0; } last_remove = remove; ++remove_count; if( (pid = Find_flag_value(&job.info,SERVER)) && kill( pid, 0 ) == 0 ){ DEBUG3("Remove_done_jobs: '%s' active %d", job_ticket_file, pid ); continue; } if( Done_jobs_max_age_DYN > 0 && ( (error && (tm - error) > Done_jobs_max_age_DYN) || (done && (tm - done) > Done_jobs_max_age_DYN) ) ){ setstatus( &job, _("job '%s' removed- status expired"), id ); /* Setup_cf_info( &job, 0 ); */ Remove_job( &job ); } else if( Done_jobs_DYN > 0 ){ plp_snprintf(tval,sizeof(tval), "0x%06x.%03d", remove, remove_count ); Set_str_value(&info, tval, job_ticket_file ); } } if( fd > 0 ) close(fd); fd = -1; if(DEBUGL1)Dump_line_list("Remove_done_jobs - removal candidates",&info); DEBUG1( "Remove_done_jobs: checking for removal - remove_count %d", Done_jobs_DYN ); for( info_index = 0; info_index < info.count - Done_jobs_DYN; ++info_index ){ char *job_ticket_file = info.list[info_index]; if( (job_ticket_file = safestrchr( job_ticket_file, '=' )) ){ ++job_ticket_file; } else { Errorcode = JABORT; fatal(LOG_ERR,"Remove_done_jobs: bad job ticket file format '%s'", info.list[info_index]); } DEBUG1( "Remove_done_jobs: [%d] job_ticket_file '%s'", info_index, job_ticket_file ); Free_job(&job); Get_job_ticket_file( &fd, &job, job_ticket_file ); Remove_job( &job ); if( fd > 0 ) close(fd); fd = -1; removed = 1; } Free_job(&job); Free_line_list(&info); if( removed && Lpq_status_file_DYN ){ unlink(Lpq_status_file_DYN); } return( removed ); } /* * move the job to a new spool queue * This will only work if the queue/printer is on the same * host. We will set up a job in the new spool queue that * appears to sent directly to the spool queue. */ static int Move_job(int fd, struct job *job, struct line_list *sp, char *errmsg, int errlen ) { /* we set up a copy of the job descriptor to use to make the job in the new directory */ int job_ticket_file_fd = -1, fail = 0, i; struct job jcopy; struct line_list datafiles; char *transfername = 0; char *savename = 0, *sd, *pr, *id; Init_line_list(&datafiles); Init_job(&jcopy); Copy_job(&jcopy,job); Set_str_value(&jcopy.info,SERVER,0); Set_str_value(&jcopy.info,MOVE,0); Set_str_value(&jcopy.info,DONE_TIME,0); Set_str_value(&jcopy.info,HOLD_TIME,0); Set_str_value(&jcopy.info,PRIORITY_TIME, 0 ); Set_str_value(&jcopy.info,ERROR_TIME, 0 ); Set_str_value(&jcopy.info,ERROR, 0 ); Set_str_value(&jcopy.info,DESTINATION, 0 ); Set_str_value(&jcopy.info,DESTINATIONS, 0 ); i = Find_flag_value(&jcopy.info,MOVE_COUNT); Set_flag_value(&jcopy.info,MOVE_COUNT,i+1); if(DEBUGL2)Dump_job("Move_job: use_subserver copy", &jcopy ); sd = Find_str_value(sp,SPOOLDIR); pr = Find_str_value(sp,PRINTER); id = Find_str_value(&job->info,IDENTIFIER); DEBUG1("Move_job: subserver '%s', spool dir '%s' for job '%s'", pr, sd, id ); setstatus(job, "moving '%s' to subserver '%s'", id, pr ); fail = 0; for( i = 0; i < jcopy.datafiles.count; ++i ){ char *from; struct line_list * datafile = (void *)jcopy.datafiles.list[i]; if(DEBUGL3)Dump_line_list("Move_job - copying datafiles", datafile); from = Find_str_value(datafile,DFTRANSFERNAME); Set_str_value(datafile,OTRANSFERNAME,from); if( !Find_str_value(&datafiles,from) ){ char * path = Make_temp_copy( from, sd ); DEBUG3("Move_job: sd '%s', from '%s', path '%s'", sd, from, path ); if( path ){ Set_str_value( &datafiles, from, path ); } else { plp_snprintf(errmsg,errlen, "cannot copy '%s' to subserver '%s' queue directory '%s'", from?from:"", pr, sd ); Set_str_value(&job->info,ERROR,errmsg); fail = 1; goto move_error; } } } /* set up the new context */ savename = safestrdup( Printer_DYN,__FILE__,__LINE__); errmsg[0] = 0; /* we have to chdir to the destination directory */ if( Setup_printer( pr, errmsg, errlen, 1 ) ){ Errorcode = JABORT; fatal(LOG_ERR, "Move_job: subserver '%s' setup failed - %s'", pr, errmsg ); } job_ticket_file_fd = Setup_temporary_job_ticket_file( &jcopy, 0, 0, 0, errmsg, errlen ); if( job_ticket_file_fd <= 0 ){ fail = 1; goto move_error; } if(DEBUGL2)Dump_job("Move_job: subserver after temp setup", &jcopy ); /* get the job set up */ transfername = Find_str_value(&jcopy.info,HF_NAME); fail = Check_for_missing_files( &jcopy, &datafiles, errmsg, errlen, 0, job_ticket_file_fd ); if( fail ) unlink( transfername ); /* now we switch back to the old context */ if( Setup_printer( savename, errmsg, errlen, 1 ) ){ Errorcode = JABORT; fatal(LOG_ERR, "Move_job: subserver '%s' setup failed '%s'", savename, errmsg ); } move_error: /* if we fail to copy, make a note of it */ Free_line_list( &datafiles ); Free_job(&jcopy); Remove_tempfiles(); if(savename) free(savename); savename = 0; if( job_ticket_file_fd > 0 ) close(job_ticket_file_fd); job_ticket_file_fd = -1; if( fail ){ setstatus(job, "%s", errmsg); Set_nz_flag_value(&job->info,ERROR_TIME,time(0)); Update_status(fd, job, JFAIL); } else { /* now we deal with the job in the original queue */ Update_status(fd, job, JSUCC); setstatus(job, "transfer '%s' to queue '%s' finished", id, pr ); setmessage(job,STATE,"COPYTO %s",pr); } return( fail ); } lprng-3.8.B/src/common/initialize.c0000644000131400013140000002160511531672131014167 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "initialize.h" #include "getopt.h" #include "child.h" #include "gethostinfo.h" #include "proctitle.h" #include "getqueue.h" #include "errorcodes.h" /**** ENDINCLUDE ****/ #ifdef IS_AUX # include #endif #ifdef HAVE_ARPA_NAMESER_H #include #endif #ifdef HAVE_RESOLV_H #include #endif static char *Get_user_information( void ); /*************************************************************************** * general initialization. * This should NOT do any network operations ***************************************************************************/ void Initialize(int argc, char *argv[], char *envp[], int debugchar ) { char *s; int fd; /* the gettext facility has been shown to be able to be used to * compromize setuid programs. * remove the slightest possibility of NLSPATH being used in a root * environment */ if( getuid() == ROOTUID || geteuid() == ROOTUID ){ #if defined(HAVE_UNSETENV) unsetenv("NLSPATH"); #elif defined(HAVE_SETENV) setenv("NLSPATH","",1); #elif defined(HAVE_PUTENV) putenv("NLSPATH="); #else # error require one of unsetenv(), setenv(), or putenv() #endif } DEBUG1("Initialize: starting"); if( argc > 1 ){ s = argv[1]; if( s[0] == '-' && s[1] == debugchar ){ if( s[2] ){ Parse_debug(s+2,1); } else { Parse_debug(argv[2],1); } } } if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Initialize: starting with open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } /* open /dev/null on fd 0, 1, 2, 3, 4, if neccessary This must be done before using any other database access functions, as they may open a socket and leave it open. */ if( (fd = open( "/dev/null", O_RDWR, 0600 )) < 0 ){ logerr_die(LOG_CRIT, "Initialize: cannot open '/dev/null'" ); } Max_open(fd); DEBUG1("Initialize: /dev/null fd %d", fd ); if( Is_server ) while( fd < 5 ){ if( (fd = dup(fd)) < 0 ){ logerr_die(LOG_CRIT, "Initialize: main cannot dup '/dev/null'" ); } Max_open(fd); } close(fd); initsetproctitle( argc, argv, envp ); Name = "UNKNOWN"; if( argv && argv[0] ){ Name = argv[0]; if( (s = strrchr(Name,'/')) ) Name = s+1; } /* set the umask so that you create safe files */ umask( 0077 ); #ifdef IS_AUX /******************************************** * Apparently this needs to be done for AUX *******************************************/ /* A/UX needs this to be more BSD-compatible. */ setcompat (COMPAT_BSDPROT); set42sig(); #endif /* set suid information */ Setup_uid(); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Initialize: before setlocale"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } setlocale(LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); if(DEBUGL3){ struct stat statb; int i; LOGDEBUG("Initialize: ending with open fd's"); for( i = 0; i < 20; ++i ){ if( fstat(i,&statb) == 0 ){ LOGDEBUG(" fd %d (0%o)", i, (unsigned int)(statb.st_mode&S_IFMT)); } } } } void Setup_configuration() { char *s; struct line_list raw; struct line_list order; /* Get default configuration file information */ #ifdef DMALLOC extern int dmalloc_outfile_fd; extern char *dmalloc_logpath; char buffer[SMALLBUFFER]; safestrdup("DMALLOC",__FILE__,__LINE__); if( dmalloc_logpath && dmalloc_outfile_fd < 0 ){ dmalloc_outfile_fd = open( dmalloc_logpath, O_WRONLY | O_CREAT | O_TRUNC, 0666); Max_open(dmalloc_outfile_fd); } plp_snprintf(buffer,sizeof(buffer), "*** Setup_configuration: pid %d\n", getpid() ); Write_fd_str(dmalloc_outfile_fd,buffer); DEBUG1("Setup_configuration: dmalloc_outfile fd %d", dmalloc_outfile_fd); #endif Init_line_list(&raw); Init_line_list(&order); Clear_config(); DEBUG1("Setup_configuration: starting, Allow_getenv %d", Allow_getenv_DYN ); /* get the configuration file information if there is any */ if( Allow_getenv_DYN ){ if( getuid() == ROOTUID || geteuid() == ROOTUID ){ FPRINTF( STDERR, "%s: WARNING- LPD_CONF environment variable option enabled\n" " and running as root! You have an exposed security breach!\n" " Recompile without -DGETENV or do not run clients as ROOT\n", Name ); exit(1); } if( (s = getenv( LPD_CONF )) ){ Set_DYN(&Config_file_DYN, s); } } DEBUG1("Setup_configuration: Configuration file '%s'", Config_file_DYN ); DEBUG1("Setup_configuration: Require_configfiles_DYN '%d'", Require_configfiles_DYN ); Get_config( Is_server || Require_configfiles_DYN, Config_file_DYN ); Reset_daemonuid(); if( Is_server ){ Setdaemon_group(); To_daemon(); } else { s = Get_user_information(); Set_DYN( &Logname_DYN, s ); if(s) free(s); s = 0; } DEBUG1( "Is_server %ld, DaemonUID %ld, DaemonGID %ld, UID %ld, EUID %ld, GID %ld, EGID %ld", (long)Is_server, (long)DaemonUID, (long)DaemonGID, (long)getuid(), (long)geteuid(), (long)getgid(), (long)getegid() ); DEBUG1("Setup_configuration: Host '%s', ShortHost '%s', user '%s'", FQDNHost_FQDN, ShortHost_FQDN, Logname_DYN ); if(DEBUGL2) Dump_parms( "Setup_configuration - final values", Pc_var_list ); if( Is_server ){ DEBUG2("Setup_configuration: Printcap_path '%s'", Printcap_path_DYN ); Getprintcap_pathlist( 1, &raw, &PC_filters_line_list, Printcap_path_DYN ); DEBUG2("Setup_configuration: Lpd_printcap_path '%s'", Lpd_printcap_path_DYN ); Getprintcap_pathlist( 0, &raw, &PC_filters_line_list, Lpd_printcap_path_DYN ); DEBUG2("Setup_configuration: Printer_perms_path '%s'", Printer_perms_path_DYN ); Getprintcap_pathlist( 1, &RawPerm_line_list, &Perm_filters_line_list, Printer_perms_path_DYN ); Free_line_list(&Perm_line_list); Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); } else { DEBUG2("Setup_configuration: Printcap_path '%s'", Printcap_path_DYN ); Getprintcap_pathlist( Require_configfiles_DYN, &raw, &PC_filters_line_list, Printcap_path_DYN ); } Build_printcap_info( &PC_names_line_list, &PC_order_line_list, &PC_info_line_list, &raw, &Host_IP ); /* now we can free up the raw list */ Free_line_list( &raw ); /* now we get the user level information */ DEBUG2("Setup_configuration: User_printcap '%s'", User_printcap_DYN ); if( !Is_server && User_printcap_DYN && (s = getenv("HOME")) ){ s = Make_pathname( s, User_printcap_DYN ); DEBUG2("Setup_configuration: User_printcap '%s'", s ); Getprintcap_pathlist( 0, &raw, 0, s ); Build_printcap_info( &PC_names_line_list, &order, &PC_info_line_list, &raw, &Host_IP ); Free_line_list( &raw ); if( s ) free(s); s = 0; /* now we append the names from the order list */ if( order.count > 0 ){ int i; /* append the found ones, remove duplicates */ for( i = 0; i < PC_order_line_list.count; ++i ){ int j; int found = 0; s = PC_order_line_list.list[i]; for( j = 0; !found && j < order.count; ++j ){ found = !strcmp(s, order.list[j]); } if( !found ){ Add_line_list(&order,s,0,0,0); } } Free_line_list( &PC_order_line_list ); for( i = 0; i < order.count; ++i ){ s = order.list[i]; Add_line_list(&PC_order_line_list,s,0,0,0); } } Free_line_list( &order ); } if(DEBUGL3){ Dump_line_list("Setup_configuration: PC names", &PC_names_line_list ); Dump_line_list("Setup_configuration: PC order", &PC_order_line_list ); Dump_line_list("Setup_configuration: PC info", &PC_info_line_list ); /* Dump_line_list("Setup_configuration: User_PC names", &User_PC_names_line_list ); Dump_line_list("Setup_configuration: User_PC order", &User_PC_order_line_list ); Dump_line_list("Setup_configuration: User_PC info", &User_PC_info_line_list ); */ Dump_line_list("Setup_configuration: Raw Perms", &RawPerm_line_list ); Dump_line_list("Setup_configuration: Perms", &Perm_line_list ); } } /* * char *Get_user_information(void) * OUTPUT: dynamic alloc string * - returns user name */ static char *Get_user_information( void ) { char *name = 0; char uid_msg[32]; uid_t uid = OriginalRUID; struct passwd *pw_ent; /* get the password file entry */ if( (pw_ent = getpwuid( uid )) ){ name = pw_ent->pw_name; } if( name == 0 ) name = getenv( "LOGNAME" ); if( name == 0 ) name = getenv( "USER" ); if( name == 0 ){ plp_snprintf( uid_msg, sizeof(uid_msg), "UID_%ld", (long)uid ); name = uid_msg; } name = safestrdup(name,__FILE__,__LINE__); return( name ); } lprng-3.8.B/src/common/lockfile.c0000644000131400013140000001134511531672131013616 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * MODULE: lockfile.c * lock file manipulation procedures. *************************************************************************** * File Locking Routines: * int Do_lock( int fd, int block ); * fd - file descriptor * block - non-zero- block until lock * Returns: 0 - success * -1 - fail *************************************************************************** * Lock File Manipulation: * Each active server has a lock file, which it uses to record its * activity. The lock file is created and then locked; * the deamon will place its PID and an activity in the lock file. * * The struct lockfile{} gives the format of this file. * * Programs wanting to know the server status will read the file. * Note: only active servers, not status programs, will lock the file. * This prevents a status program from locking out a server. * The information in the lock file may be stale, as the lock program * may update the file without the knowledge of the checker. * However, by making the file fixed size and small, we can read/write * it with a single operation, making the window of modification small. ***************************************************************************/ #include "lp.h" #include "lockfile.h" #include "fileopen.h" /**** ENDINCLUDE ****/ #if defined(HAVE_SYS_TTYCOM_H) #include #endif #if defined(HAVE_SYS_TTOLD_H) && !defined(IRIX) #include #endif #if defined(HAVE_SYS_IOCTL_H) #include #endif /*************************************************************************** * Do_lock( fd , int block ) * does a lock on a file; * if block is nonzero, block until file unlocked * Returns: < 0 if lock fn failed * 0 if successful ***************************************************************************/ int Do_lock( int fd, int block ) { int code = -2; DEBUG3("Do_lock: fd %d, block '%d'", fd, block ); #if defined(HAVE_FLOCK) if( code == -2 ){ int err; int how; if( block ){ how = LOCK_EX; } else { how = LOCK_EX|LOCK_NB; } DEBUG3 ("Do_lock: using flock" ); code = flock( fd, how ); err = errno; if( code < 0 ){ DEBUG1( "Do_lock: flock failed '%s'", Errormsg( err )); code = -1; } else { code = 0; } errno = err; } #else #if defined(HAVE_LOCKF) if( code == -2 ){ int err; int how; if( block ){ how = F_LOCK; } else { how = F_TLOCK; } DEBUG3 ("Do_lock: using lockf" ); code = lockf( fd, how, 0); err = errno; if( code < 0 ){ DEBUG1( "Do_lock: lockf failed '%s'", Errormsg( err)); code = -1; } else { code = 0; } errno = err; } #else #if defined(HAVE_FCNTL) if( code == -2 ){ struct flock file_lock; int err; int how; DEBUG3 ("Do_lock: using fcntl with SEEK_SET, block %d", block ); how = F_SETLK; if( block ) how = F_SETLKW; memset( &file_lock, 0, sizeof( file_lock ) ); file_lock.l_type = F_WRLCK; file_lock.l_whence = SEEK_SET; code = fcntl( fd, how, &file_lock); err = errno; if( code < 0 ){ code = -1; } else { code = 0; } DEBUG3 ("devlock_fcntl: status %d", code ); errno = err; } #endif #endif #endif DEBUG3 ("Do_lock: status %d", code); return( code); } /*************************************************************************** * LockDevice(fd, block) * Tries to lock the device file so that two or more queues can work on * the same print device. First does a non-blocking lock, if this fails, * puts a nice message in the status file and blocks in a second lock. * (contributed by Michael Joosten ) * * Finally, you can set locking off (:lk@:) * * RETURNS: >= 0 if successful, < 0 if fails ***************************************************************************/ int LockDevice(int fd, int block ) { int lock = -1; int err = errno; DEBUG2 ("LockDevice: locking '%d'", fd ); #if defined(TIOCEXCL) && !defined(HAVE_BROKEN_TIOCEXCL) DEBUG2 ("LockDevice: TIOCEXL on '%d', isatty %d", fd, isatty( fd ) ); if( isatty (fd) ){ /* use the TIOCEXCL ioctl. See termio(4). */ DEBUG2 ("LockDevice: TIOCEXL on '%d'", fd); lock = ioctl( fd, TIOCEXCL, (void *) 0); err = errno; if( lock < 0) { lock = -1; logerr(LOG_INFO, "LockDevice: TIOCEXCL failed"); } else { lock = 0; } } #endif if( lock < 0 ){ lock = Do_lock( fd, block ); } errno = err; return( lock ); } lprng-3.8.B/src/common/lpd_control.c0000644000131400013140000010044311531672131014343 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "getopt.h" #include "proctitle.h" #include "control.h" #include "child.h" #include "getprinter.h" #include "getqueue.h" #include "fileopen.h" #include "globmatch.h" #include "permission.h" #include "gethostinfo.h" #include "lpd_control.h" /**** ENDINCLUDE ****/ /*************************************************************************** The control (LPC) interface provides the following functionality. 1. Spool Queues have a 'control.printer' file that is read/written by the Get _spool_control and Set _spool_control routines. These routines will happily put out the various control strings you need. USED BY: start/stop, enable/disable, debug, forward, holdall 2. Individual jobs have a 'job ticket file' that is read/written by the Get_ job_ticket and Set_ job_ticket routines. These also will read/write various control strings. USED by topq, hold, release ***************************************************************************/ static void Do_printer_work( char *user, int action, int *sock, struct line_list *tokens, char *error, int errorlen ); static void Do_queue_control( char *user, int action, int *sock, struct line_list *tokens, char *error, int errorlen ); static int Do_job_ticket_file( int action, int *sock, struct line_list *tokens, char *error, int errorlen, char *option ); static int Do_control_lpq( char *user, int action, struct line_list *tokens ); static int Do_control_status( int *sock, char *error, int errorlen ); static int Do_control_redirect( int *sock, struct line_list *tokens, char *error, int errorlen ); static int Do_control_class( int *sock, struct line_list *tokens, char *error, int errorlen ); static int Do_control_debug( int *sock, struct line_list *tokens, char *error, int errorlen ); static int Do_control_printcap( int *sock ); static int Do_control_ppd( int *sock ); static int Do_control_defaultq( int *sock ); static char status_header[] = "%-18s %8s %8s %4s %7s %7s %8s %s%s"; int Job_control( int *sock, char *input ) { struct line_list tokens; char error[LINEBUFFER]; int tokencount; int i, action, permission; char *name, *user = 0, *s, *lpc_command; /* get the format */ Init_line_list(&tokens); error[0] = 0; Name = "Job_control"; ++input; if( (s = safestrchr(input, '\n' )) ) *s = 0; DEBUGF(DCTRL1)("Job_control: socket %d, doing '%s'", *sock, input ); /* check printername for characters, underscore, digits */ Split(&tokens,input,Whitespace,0,0,0,0,0,0); DEBUGFC(DCTRL2)Dump_line_list("Job_control - input", &tokens); tokencount = tokens.count; if( tokencount < 3 ){ plp_snprintf( error, sizeof(error), _("bad control command '%s'"), input ); goto error; } /* get the name for the printer */ /* it is either the default or user specified */ name = tokens.list[0]; if( tokencount > 3 ){ name = tokens.list[3]; } if( (s = Is_clean_name( name )) ){ plp_snprintf( error, sizeof(error), _("printer '%s' has illegal char at '%s' in name"), name, s ); goto error; } Set_DYN(&Printer_DYN,name); setproctitle( "lpd %s %s", Name, Printer_DYN ); user = tokens.list[1]; lpc_command = tokens.list[2]; action = Get_controlword( lpc_command ); if( action == 0 ){ plp_snprintf( error, sizeof(error), _("%s: unknown control request '%s'"), Printer_DYN, lpc_command ); goto error; } /* check the permissions for the action */ if( Perm_filters_line_list.count ){ Free_line_list(&Perm_line_list); Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); Filterprintcap( &Perm_line_list, &Perm_filters_line_list, ""); } DEBUGF(DCTRL1)( "Job_control: checking USER='%s' SERVICE='%c', PRINTER='%s'", user, Perm_check.service, Printer_DYN ); Perm_check.printer = Printer_DYN; Perm_check.remoteuser = user; Perm_check.service = 'C'; Perm_check.lpc = lpc_command; permission = Perms_check( &Perm_line_list, &Perm_check, 0, 0 ); /* queue perm check */ DEBUGF(DCTRL1)( "Job_control: checked for '%c', permission %s", Perm_check.service, perm_str(permission) ); switch( action ){ case OP_REREAD: if( permission == P_REJECT ){ goto noperm; } DEBUGF(DCTRL1)( "Job_control: sending pid %d SIGHUP", Server_pid ); plp_snprintf( error, sizeof(error), "lpd server pid %d on %s, sending SIGHUP\n", Server_pid, FQDNHost_FQDN ); (void)kill(Server_pid,SIGHUP); if( Write_fd_str( *sock, error ) < 0 ) cleanup(0); goto done; case OP_LPD: if( permission == P_REJECT ){ goto noperm; } DEBUGF(DCTRL1)( "Job_control: lpd pid %d", Server_pid ); plp_snprintf( error, sizeof(error), "lpd server pid %d on %s\n", Server_pid, FQDNHost_FQDN ); if( Write_fd_str( *sock, error ) < 0 ) cleanup(0); error[0] = 0; goto done; case OP_DEFAULTQ: if( permission == P_REJECT ){ goto noperm; } Do_control_defaultq( sock ); goto done; case OP_STATUS: /* we put out a space at the start to make PCNFSD happy */ if( permission == P_REJECT ){ goto noperm; } plp_snprintf( error, sizeof(error), status_header, " Printer", "Printing", "Spooling", "Jobs", "Server", "Subserver", "Redirect", "Status/(Debug)","" ); safestrncat(error,"\n"); if( Write_fd_str( *sock, error ) < 0 ) cleanup(0); case OP_STOP: case OP_START: case OP_DISABLE: case OP_ENABLE: case OP_ABORT: case OP_UP: case OP_DOWN: case OP_HOLDALL: case OP_NOHOLDALL: /* control line is 'Xprinter user action arg1 arg2 * t[0] t[1] t[2] t[3] */ if( tokencount > 4 ){ /* we have a list of printers to use */ for( i = 3; i < tokencount; ++i ){ Name = "Job_control"; Set_DYN(&Printer_DYN,tokens.list[i]); DEBUGF(DCTRL1)( "Job_control: doing printer '%s'", Printer_DYN ); Do_printer_work( user, action, sock, 0, error, sizeof(error) ); } goto done; } break; case OP_MOVE: /* we have Nprinter user move jobid* target */ if( tokencount < 5 ){ plp_snprintf( error, sizeof(error), _("Use: move printer (user|jobid)* target") ); goto error; } break; } Do_printer_work( user, action, sock, &tokens, error, sizeof(error) ); goto done; noperm: plp_snprintf( error, sizeof(error), _("no permission to control server") ); error: Name = "Job_control"; DEBUGF(DCTRL2)("Job_control: error msg '%s'", error ); safestrncat(error,"\n"); Write_fd_str( *sock, error ); done: Name = "Job_control"; DEBUGF(DCTRL3)( "Job_control: DONE" ); Free_line_list(&tokens); return(0); } static void Do_printer_work( char *user, int action, int *sock, struct line_list *tokens, char *error, int errorlen ) { int i; DEBUGF(DCTRL3)("Do_printer_work: printer '%s', action '%s'", Printer_DYN, Get_controlstr(action) ); Name = "Do_printer_work"; if( safestrcasecmp( Printer_DYN, ALL ) ){ DEBUGF(DCTRL3)( "Do_printer_work: checking printcap entry '%s'", Printer_DYN ); Do_queue_control( user, action, sock, tokens, error, errorlen ); } else { /* we work our way down the printcap list, checking for ones that have a spool queue */ /* note that we have already tried to get the 'all' list */ Get_all_printcap_entries(); for( i = 0; i < All_line_list.count; ++i ){ Name = "Do_printer_work"; Set_DYN(&Printer_DYN, All_line_list.list[i]); DEBUGF(DCTRL4)("Do_printer_work: printer [%d]='%s'", i, Printer_DYN ); Do_queue_control( user, action, sock, tokens, error, errorlen); Name = "Do_printer_work"; } } } /*************************************************************************** * Do_queue_control() * do the actual queue control operations * - start, stop, enable, disable are simple * - others are more complex, and are handled in Do_job_ticket_file * We have tokens: * printer user printer p1 p2 p3 -> p1 p2 p3 ***************************************************************************/ static void Do_queue_control( char *user, int action, int *sock, struct line_list *tokens, char *error, int errorlen ) { char *start, *end; pid_t serverpid; /* server pid to kill off */ struct stat statb; /* status of file */ int fd, c, i, permission, db, dbflag; /* descriptor and chars */ char line[LINEBUFFER]; char msg[LINEBUFFER]; int status, change; int signal_server = SIGUSR1; struct line_list l; const char *Action = "updated"; /* first get the printer name */ Init_line_list(&l); Name = "Do_queue_control"; error[0] = 0; change = 0; if( action != OP_STATUS ){ plp_snprintf(msg,sizeof(msg), "Printer: %s@%s\n", Printer_DYN,ShortHost_FQDN); Write_fd_str(*sock,msg); } if( Setup_printer( Printer_DYN, error, errorlen, 0 ) ){ goto error; } c = Debug; i = DbgFlag; end = Find_str_value(&Spool_control,DEBUG); if( !end ) end = New_debug_DYN; Parse_debug( end, 0 ); if( !(DbgFlag & DCTRLMASK) ){ Debug = c; DbgFlag = i; } else { db = Debug; dbflag = DbgFlag; Debug = c; DbgFlag = i; if( Log_file_DYN ){ fd = Trim_status_file( -1, Log_file_DYN, Max_log_file_size_DYN, Min_log_file_size_DYN ); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); } } Debug = db; DbgFlag = dbflag; } Perm_check.printer = Printer_DYN; Perm_check.remoteuser = user; Perm_check.service = 'C'; Perm_check.user = 0; Perm_check.host = 0; DEBUGF(DCTRL1)( "Do_queue_control: checking USER='%s' SERVICE='%c', PRINTER='%s'", user, Perm_check.service, Printer_DYN ); permission = Perms_check( &Perm_line_list, &Perm_check, 0, 0 ); /* queue check */ DEBUGF(DCTRL1)( "Do_queue_control: C permission %s", perm_str(permission) ); /* * some of the commands allow a list of printers to be * specified, others only take a single printer * We need to put in the list stuff for the ones that take a list */ if( permission == P_REJECT ) goto noperm; switch( action ){ case OP_LPQ: if( Do_control_lpq( user, action, tokens ) ){ goto error; } goto done; case OP_PRINTCAP: Do_control_printcap( sock ); goto done; case OP_PPD: Do_control_ppd( sock ); goto done; case OP_STATUS: if( Do_control_status( sock, error, errorlen ) ){ goto error; } goto done; case OP_STOP: Set_flag_value(&Spool_control,PRINTING_DISABLED, 1); break; case OP_START: Set_flag_value(&Spool_control,PRINTING_DISABLED, 0); Set_flag_value(&Spool_control,PRINTING_ABORTED, 0); break; case OP_DISABLE: Set_flag_value(&Spool_control,SPOOLING_DISABLED, 1); break; case OP_ENABLE: Set_flag_value(&Spool_control,SPOOLING_DISABLED, 0); break; case OP_ABORT: Set_flag_value(&Spool_control,PRINTING_ABORTED, 1); case OP_KILL: signal_server = SIGINT; break; case OP_UP: Set_flag_value(&Spool_control,PRINTING_ABORTED, 0); Set_flag_value(&Spool_control,PRINTING_DISABLED, 0); Set_flag_value(&Spool_control,SPOOLING_DISABLED, 0); break; case OP_DOWN: Set_flag_value(&Spool_control,PRINTING_DISABLED, 1); Set_flag_value(&Spool_control,SPOOLING_DISABLED, 1); break; case OP_HOLDALL: Set_flag_value(&Spool_control,HOLD_ALL, 1); break; case OP_NOHOLDALL: Set_flag_value(&Spool_control,HOLD_ALL, 0); break; case OP_RELEASE: case OP_REDO: case OP_TOPQ: Set_flag_value(&Spool_control,PRINTING_ABORTED, 0); Set_flag_value(&Spool_control,PRINTING_DISABLED, 0); case OP_HOLD: if( Do_job_ticket_file( action, sock, tokens, error, errorlen, 0 ) ){ goto error; } break; case OP_MSG: Remove_line_list(tokens,0); /* pr */ Remove_line_list(tokens,0); /* user */ Remove_line_list(tokens,0); /* printer */ Remove_line_list(tokens,0); /* 'msg' */ start = Join_line_list(tokens," "); if( start ){ end = start+safestrlen(start)-1; *end = 0; } DEBUGF(DCTRL1)("Do_queue_control: msg '%s'", start ); if( Lpq_status_file_DYN ) unlink(Lpq_status_file_DYN ); Set_str_value(&Spool_control,MSG,start); break; case OP_MOVE: --tokens->count; start = tokens->list[tokens->count]; status = Do_job_ticket_file( action, sock, tokens, error, errorlen, start ); ++tokens->count; if( status ) goto error; break; case OP_LPRM: if( Do_control_lpq( user, action, tokens ) ){ goto error; } break; case OP_REDIRECT: if( Do_control_redirect( sock, tokens, error, errorlen ) ){ goto error; } break; case OP_CLASS: if( Do_control_class( sock, tokens, error, errorlen ) ){ goto error; } break; case OP_DEBUG: if( Do_control_debug( sock, tokens, error, errorlen ) ){ goto error; } break; case OP_FLUSH: if( Lpq_status_file_DYN ) unlink(Lpq_status_file_DYN ); { char *file; int fd = -1; if( (file = Queue_status_file_DYN) && (fd = Checkwrite( file, &statb,O_RDWR,0,0)) > 0 ){ ftruncate( fd, 0); close(fd); } if( (file = Status_file_DYN) && (fd = Checkwrite( file, &statb,O_RDWR,0,0)) > 0 ){ ftruncate( fd, 0); close(fd); } } signal_server = 0; break; default: plp_snprintf( error, errorlen, _("not implemented yet") ); goto error; } Perm_check_to_list(&l, &Perm_check ); DEBUGFC(DCTRL2)Dump_line_list("Do_queue_control - perms", &l); if( Server_queue_name_DYN ){ Set_flag_value(&Spool_control,CHANGE,1); } /* modify the control file to force rescan of queue */ Set_spool_control( &l, Queue_control_file_DYN, &Spool_control ); Free_line_list(&l); /* signal or kill off the server */ serverpid = 0; if( signal_server && (serverpid = Read_pid_from_file( Queue_lock_file_DYN ) ) > 0 ){ if( signal_server != SIGUSR1 ){ killpg( serverpid, signal_server ); killpg( serverpid, SIGHUP ); killpg( serverpid, SIGQUIT ); kill( serverpid, signal_server ); kill( serverpid, SIGHUP ); kill( serverpid, SIGQUIT ); } if( kill( serverpid, signal_server ) ){ plp_snprintf(msg,sizeof(msg), _("server process PID %ld exited\n"), (long)serverpid ); } else { plp_snprintf(msg,sizeof(msg), _("kill server process PID %ld with %s\n"), (long)serverpid, Sigstr(signal_server) ); } Write_fd_str(*sock,msg); } switch( action ){ case OP_STATUS: Action = 0; break; /* no message */ case OP_UP: Action = _("enabled and started"); break; case OP_DOWN: Action = _("disabled and stopped"); break; case OP_STOP: Action = _("stopped"); break; case OP_RELEASE: case OP_REDO: case OP_TOPQ: case OP_START: Action = _("started"); break; case OP_DISABLE: Action = _("disabled"); break; case OP_ENABLE: Action = _("enabled"); break; case OP_REDIRECT: Action = _("redirected"); break; case OP_HOLDALL: Action = _("holdall on"); break; case OP_NOHOLDALL: Action = _("holdall off"); break; case OP_MOVE: Action = _("move done"); break; case OP_CLASS: Action = _("class updated"); break; case OP_KILL: Action = _("killed job"); break; case OP_ABORT: Action = _("aborted job"); break; case OP_FLUSH: Action = _("flushed status"); break; } if( Action ){ setmessage( 0, ACTION, "%s", Action ); plp_snprintf( line, sizeof(line), "%s@%s: %s\n", Printer_DYN, FQDNHost_FQDN, Action ); if( Write_fd_str( *sock, line ) < 0 ) cleanup(0); } if( Server_queue_name_DYN ){ if( Setup_printer( Server_queue_name_DYN, error, errorlen, 0 ) ){ goto error; } serverpid = 0; if( signal_server ) { serverpid = Read_pid_from_file( Queue_lock_file_DYN ); if( serverpid <= 0 || kill( serverpid, signal_server ) ){ serverpid = 0; } else { plp_snprintf(msg,sizeof(msg), _( "WARNING: the main load balance server may have exited before\n" "it could be informed that there were new jobs.\n" "Please use 'lpc start %s' to start the server\n"), Server_queue_name_DYN ); Write_fd_str(*sock,msg); } } } DEBUGF(DCTRL4)("Do_queue_control: server pid %ld", (long)serverpid ); /* start the server if necessary */ switch( action ){ case OP_KILL: plp_sleep(1); serverpid = 0; break; case OP_START: serverpid = 0; break; } if( serverpid <= 0 )switch( action ){ case OP_KILL: case OP_TOPQ: case OP_RELEASE: case OP_REDO: case OP_UP: case OP_START: case OP_REDIRECT: case OP_MOVE: case OP_CLASS: plp_snprintf( line, sizeof(line), "%s\n", Printer_DYN ); DEBUGF(DCTRL3)("Do_queue_control: sending '%s' to LPD", line ); if( Write_fd_str( Lpd_request, line ) < 0 ){ logerr_die(LOG_ERR, _("Do_queue_control: write to fd '%d' failed"), Lpd_request ); } } goto done; noperm: plp_snprintf( error, sizeof(error), "no permission"); error: DEBUGF(DCTRL2)("Do_queue_control: error msg '%s'", error ); if( (i = safestrlen(error)) ){ plp_snprintf( msg, sizeof(msg), "%s@%s: %s\n", Printer_DYN, ShortHost_FQDN, error ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); } done: DEBUGF(DCTRL3)( "Do_queue_control: done" ); Free_line_list(&l); return; } /*************************************************************************** * Do_job_ticket_file: * perform a suitable operation on a control file * 1. get the control files * 2. check to see if the control file has been selected * 3. update the job ticket file for the control file ***************************************************************************/ static int Do_job_ticket_file( int action, int *sock, struct line_list *tokens, char *error, int errorlen, char *option ) { int i, permission, err, fd; /* ACME! Nothing but the best */ int status, matchv; /* status of last IO op */ char msg[SMALLBUFFER]; /* message field */ char *s, *identifier; struct job job; int destinations, update_dest; struct line_list l; /* get the job files */ Init_line_list(&l); Init_job(&job); Free_line_list(&Sort_order); if( Scan_queue( &Spool_control, &Sort_order, 0,0,0,0,0,0,0,0) ){ err = errno; plp_snprintf(error, errorlen, "Do_job_ticket_file: cannot read '%s' - '%s'", Spool_dir_DYN, Errormsg(err) ); return(1); } DEBUGF(DCTRL4)("Do_job_ticket_file: total files %d", Sort_order.count ); DEBUGFC(DCTRL2)Dump_line_list("Do_job_ticket_file - tokens", tokens); /* scan the files to see if there is one which matches */ status = 0; fd = -1; for( i = 0; status == 0 && i < Sort_order.count; ++i ){ /* * check to see if this entry matches any of the patterns */ if( fd > 0 ) close(fd); fd = -1; Free_job(&job); Get_job_ticket_file( &fd, &job, Sort_order.list[i] ); DEBUGFC(DCTRL2)Dump_job("Do_job_ticket_file - getting info",&job); if( Find_flag_value(&job.info,INCOMING_TIME) ){ DEBUGF(DCTRL2)("Do_job_ticket_file: incoming job"); continue; } identifier = Find_str_value(&job.info,IDENTIFIER); if( identifier == 0 ) identifier = Find_str_value(&job.info,XXCFTRANSFERNAME); if( identifier == 0 ) continue; DEBUGF(DCTRL4)("Do_job_ticket_file: checking id '%s'", identifier ); Perm_check.user = Find_str_value(&job.info,LOGNAME); Perm_check.host = 0; s = Find_str_value(&job.info,FROMHOST); if( s && Find_fqdn( &PermHost_IP, s ) ){ Perm_check.host = &PermHost_IP; } permission = Perms_check( &Perm_line_list, &Perm_check, 0, 1 ); DEBUGF(DCTRL1)( "Do_job_ticket_file: id '%s', user '%s', host '%s', permission %s", identifier, Perm_check.user, s, perm_str(permission) ); if( permission == P_REJECT ){ plp_snprintf( msg, sizeof(msg), _("%s: no permission '%s'\n"), Printer_DYN, identifier ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); continue; } destinations = Find_flag_value(&job.info,DESTINATIONS); update_dest = 0; next_dest: if( tokens->count > 4 ){ /* you have printer user operation host key key key... * 0 1 2 3 4 */ for( matchv = Patselect( tokens, &job.info, 4 ); matchv && update_dest < destinations; ++update_dest ){ Get_destination(&job,update_dest); matchv = Patselect( tokens, &job.destination, 3 ); } if( matchv ) continue; } else { status = 1; } DEBUGFC(DCTRL4){ LOGDEBUG("Do_job_ticket_file: selected id '%s'", identifier ); s = Find_str_value(&job.destination,IDENTIFIER); LOGDEBUG("Do_job_ticket_file: update_dest %d, id '%s'", update_dest, s ); } /* we report this job being selected */ switch( action ){ case OP_HOLD: Set_flag_value(&job.info,HOLD_TIME,time((void *)0) ); if( update_dest ){ Set_flag_value(&job.destination,HOLD_TIME,time((void *)0) ); } setmessage( &job, TRACE, "LPC held" ); break; case OP_TOPQ: Set_flag_value(&job.info,HOLD_TIME,0 ); Set_flag_value(&job.info,PRIORITY_TIME,time((void *)0) ); if( update_dest ){ Set_flag_value(&job.destination,HOLD_TIME,0 ); } setmessage( &job, TRACE, "LPC topq"); break; case OP_MOVE: Set_str_value(&job.info,MOVE,option); Set_flag_value(&job.info,HOLD_TIME,0 ); Set_flag_value(&job.info,PRIORITY_TIME,0 ); Set_flag_value(&job.info,DONE_TIME,0 ); Set_flag_value(&job.info,REMOVE_TIME,0 ); Set_flag_value(&job.info,ERROR_TIME,0 ); Set_str_value(&job.info,ERROR,0 ); setmessage( &job, TRACE, "LPC move" ); break; case OP_RELEASE: Set_flag_value(&job.info,HOLD_TIME,0 ); Set_flag_value(&job.info,ATTEMPT,0 ); if( update_dest ){ Set_flag_value(&job.destination,HOLD_TIME,0 ); Set_flag_value(&job.destination,ATTEMPT,0 ); } setmessage( &job, TRACE, "LPC release" ); break; case OP_REDO: Set_flag_value(&job.info,HOLD_TIME,0 ); Set_flag_value(&job.info,ATTEMPT,0 ); Set_flag_value(&job.info,DONE_TIME,0 ); Set_flag_value(&job.info,REMOVE_TIME,0 ); if( update_dest ){ Set_flag_value(&job.destination,HOLD_TIME,0 ); Set_flag_value(&job.destination,ATTEMPT,0 ); Set_flag_value(&job.destination,DONE_TIME,0 ); Set_flag_value(&job.destination,COPY_DONE,0 ); } setmessage( &job, TRACE, "LPC redo"); break; } if( update_dest ){ Update_destination( &job ); } plp_snprintf( msg, sizeof(msg), _("%s: selected '%s'\n"), Printer_DYN, identifier ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); Set_str_value(&job.info,ERROR,0 ); Set_flag_value(&job.info,ERROR_TIME,0); /* record the last update person */ Perm_check_to_list(&l, &Perm_check ); if( Set_job_ticket_file(&job,&l,fd) ){ setmessage( &job, TRACE, "LPC failed" ); plp_snprintf( msg, sizeof(msg), _("%s: cannot set hold file '%s'\n"), Printer_DYN, identifier ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); } Free_line_list(&l); if( update_dest ){ goto next_dest; } } if( fd > 0 ) close(fd); fd = -1; Free_job(&job); Free_line_list(&Sort_order); Free_line_list(&l); return( 0 ); } /*************************************************************************** * Do_control_lpq: * forward an OP_LPQ or OP_LPRM ***************************************************************************/ static int Do_control_lpq( char *user, int action, struct line_list *tokens ) { char msg[LINEBUFFER]; /* message field */ int i = 0; /* synthesize an OP_LPQ or OP_LPRM line */ msg[sizeof(msg)-1] = 0; switch( action ){ case OP_LPQ: i = REQ_DSHORT; break; case OP_LPRM: i = REQ_REMOVE; break; } plp_snprintf( msg, sizeof(msg), "%c%s", i, Printer_DYN ); switch( action ){ case OP_LPRM: safestrncat( msg, " " ); safestrncat( msg, user ); break; } for( i = 0; i < tokens->count; ++i ){ safestrncat( msg, " " ); safestrncat( msg, tokens->list[i] ); } safestrncat( msg, "\n" ); DEBUGF(DCTRL3)("Do_control_lpq: sending '%s'", msg ); /* switch( action ){ case OP_LPQ: Job_status( sock, msg ); break; case OP_LPRM: Job_remove( sock, msg ); break; } */ return(0); } /*************************************************************************** * Do_control_status: * report current status ***************************************************************************/ static int Do_control_status( int *sock, char *error, int errorlen ) { char msg[SMALLBUFFER]; /* message field */ char pr[LINEBUFFER]; char pr_status[LINEBUFFER]; char count[32]; char server[32]; char spooler[32]; char forward[LINEBUFFER]; char debugstr[LINEBUFFER]; int serverpid, unspoolerpid; /* server and unspooler */ int len; char *s; int printable, held, move, err, done; /* get the job files */ Free_line_list(&Spool_control); Get_spool_control( Queue_control_file_DYN, &Spool_control ); if( Scan_queue( &Spool_control, &Sort_order, &printable, &held, &move,1,&err,&done,0,0) ){ plp_snprintf( error, errorlen, "Do_control_status: cannot read '%s' - '%s'", Spool_dir_DYN, Errormsg(errno) ); return(1); } Free_line_list(&Sort_order); DEBUGF(DCTRL1)( "Do_control_status: printable %d, held %d, move %d, err %d, done %d", printable, held, move, err, done ); /* now check to see if there is a server and unspooler process active */ serverpid = Server_active( Printer_DYN ); DEBUGF(DCTRL4)("Get_queue_status: serverpid %d", serverpid ); unspoolerpid = Server_active( Queue_unspooler_file_DYN ); DEBUGF(DCTRL4)("Get_queue_status: unspoolerpid %d", unspoolerpid ); plp_snprintf( pr, sizeof(pr), "%s@%s", Printer_DYN, Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN ); pr_status[0] = 0; if( Hld_all(&Spool_control) ){ len = safestrlen(pr_status); plp_snprintf( pr_status+len, sizeof(pr_status)-len, _(" holdall") ); } if( (s = Clsses(&Spool_control)) ){ len = safestrlen(pr_status); plp_snprintf( pr_status+len, sizeof(pr_status)-len, _(" class=%s"),s ); } if( Auto_hold_DYN ){ len = safestrlen(pr_status); plp_snprintf( pr_status+len, sizeof(pr_status)-len, _(" autohold") ); } if( pr_status[0] ){ len = safestrlen(pr_status); plp_snprintf( pr_status+len, sizeof(pr_status)-len, ")" ); pr_status[0] = '('; } plp_snprintf( count, sizeof(count), "%d", printable ); strcpy( server, "none" ); strcpy( spooler, "none" ); if( serverpid ) plp_snprintf( server, sizeof(server), "%d",serverpid ); if( unspoolerpid ) plp_snprintf( spooler, sizeof(spooler), "%d",unspoolerpid ); if( Server_names_DYN ) plp_snprintf( spooler, sizeof(spooler), "%s",Server_names_DYN ); forward[0] = 0; if( (s = Frwarding(&Spool_control)) ){ plp_snprintf( forward, sizeof( forward ), "%s", s ); } debugstr[0] = 0; if( (s = Cntrol_debug(&Spool_control)) ){ plp_snprintf( debugstr, sizeof(debugstr), "(%s)", s ); } plp_snprintf( msg, sizeof(msg), status_header, pr, Pr_disabled(&Spool_control)?"disabled":(Pr_aborted(&Spool_control)?"aborted":"enabled"), Sp_disabled(&Spool_control)? "disabled" : "enabled", count, server, spooler, forward, pr_status, debugstr ); trunc_str( msg ); safestrncat(msg,"\n"); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); return( 0 ); } /*************************************************************************** * Do_control_redirect: * perform a suitable operation on a control file * 1. get the control files * 2. if no options, report redirect name * 3. if option = none, remove redirect file * 4. if option = printer@host, specify name ***************************************************************************/ static int Do_control_redirect( int *sock, struct line_list *tokens, char *error, int errorlen ) { char *s; char msg[LINEBUFFER]; int n = 0; /* get the spool entries */ DEBUGFC(DCTRL2)Dump_line_list("Do_control_redirect - tokens",tokens); switch( tokens->count ){ case 3: case 4: n = 1; break; case 5: s = tokens->list[4]; DEBUGF(DCTRL4)("Do_control_redirect: redirect to '%s'", s ); if( safestrcasecmp( s, "off" ) == 0 ){ Set_str_value(&Spool_control,FORWARDING,0); } else { Set_str_value(&Spool_control,FORWARDING,s); } break; default: plp_snprintf( error, errorlen, _("wrong number arguments, %d"), tokens->count ); goto error; } s = Frwarding(&Spool_control); if( s ){ plp_snprintf( msg, sizeof(msg), _("forwarding to '%s'\n"), s ); } else { plp_snprintf( msg, sizeof(msg), _("forwarding off\n") ); } if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); error: return( n ); } /*************************************************************************** * Do_control_class: * perform a suitable operation on a control file * 1. get the control files * 2. if no options, report class name * 3. if option = none, remove class file * 4. if option = printer@host, specify name ***************************************************************************/ static int Do_control_class( int *sock, struct line_list *tokens, char *error, int errorlen ) { char forward[LINEBUFFER]; char *s; int n = 0; /* get the spool entries */ error[0] = 0; forward[0] = 0; switch( tokens->count ){ case -1: case 3: case 4: n = 1; break; case 5: s = tokens->list[4]; DEBUGF(DCTRL4)("Do_control_class: class to '%s'", s ); if( safestrcasecmp( s, "off" ) == 0 ){ Set_str_value(&Spool_control,CLASS,0); } else { Set_str_value(&Spool_control,CLASS,s); } break; default: plp_snprintf( error, errorlen, _("wrong number arguments, %d"), tokens->count ); goto error; } s = Find_str_value(&Spool_control,CLASS); if( s ){ plp_snprintf( forward, sizeof(forward), _("classes printed '%s'\n"), s ); } else { plp_snprintf( forward, sizeof(forward), _("all classes printed\n") ); } if( Write_fd_str( *sock, forward ) < 0 ) cleanup(0); error: return( n ); } /*************************************************************************** * Do_control_debug: * perform a suitable operation on a control file * 1. get the control files * 2. if no options, report debug name * 3. if option = none, remove debug file * 4. if option = printer@host, specify name ***************************************************************************/ static int Do_control_debug( int *sock, struct line_list *tokens, char *error, int errorlen ) { char debugging[LINEBUFFER]; char *s; int n = 0; /* get the spool entries */ error[0] = 0; debugging[0] = 0; switch( tokens->count ){ case -1: case 3: case 4: n = 1; break; case 5: s = tokens->list[4]; DEBUGF(DCTRL4)("Do_control_debug: debug to '%s'", s ); if( safestrcasecmp( s, "off" ) == 0 ){ Set_str_value(&Spool_control,DEBUG,0); } else { Set_str_value(&Spool_control,DEBUG,s); } break; default: plp_snprintf( error, errorlen, _("wrong number arguments, %d"), tokens->count ); goto error; } if( (s = Cntrol_debug(&Spool_control)) ){ plp_snprintf( debugging, sizeof(debugging), _("debugging override set to '%s'"), s ); } else { plp_snprintf( debugging, sizeof(debugging), _("debugging override off") ); } if( debugging[0] ){ safestrncat(debugging,"\n"); if( Write_fd_str( *sock, debugging ) < 0 ) cleanup(0); } error: return( n ); } /*************************************************************************** * Do_control_printcap: * get the LPD status * 1. get the printcap PID * 2. if no options, report PID * 3. if option = HUP, send signal ***************************************************************************/ static int Do_control_printcap( int *sock ) { char *printcap = 0, *s, *t, *w; /* get the spool entries */ t = Join_line_list(&PC_alias_line_list,"|"); s = Join_line_list(&PC_entry_line_list,"\n :"); if( s && t ){ if( (w = safestrrchr(t,'|')) ) *w = 0; printcap = safestrdup3(t,"\n :",s,__FILE__,__LINE__); if( (w = safestrrchr(printcap,' ')) ) *w = 0; if( Write_fd_str( *sock, printcap ) < 0 ) cleanup(0); } else { if( Write_fd_str( *sock, "\n" ) < 0 ) cleanup(0); } if( s ) free(s); s = 0; if( t ) free(t); t = 0; if( printcap ) free(printcap); printcap = 0; return(0); } /*************************************************************************** * Do_control_ppd: * get the PPD file * 1. get the ppd file name * 2. if no ppdfile, write nothint ***************************************************************************/ static int Do_control_ppd( int *sock ) { char *file = Ppd_file_DYN; char buffer[LARGEBUFFER]; int fd, count; struct stat statb; /* status of file */ /* get the spool entries */ if( !ISNULL(file) ){ if( (fd = Checkread( file, &statb )) < 0 ){ plp_snprintf(buffer, sizeof(buffer), "%s: cannot open '%s' - '%s'\n", Printer_DYN, file, Errormsg(errno) ); Write_fd_str( *sock, buffer ); } else { while( (count = ok_read(fd, buffer, sizeof(buffer)-1)) > 0 ){ if( Write_fd_len( *sock, buffer, count ) < 0 ) cleanup(0); } if( count < 0 ){ plp_snprintf(buffer, sizeof(buffer), "%s: error reading '%s' - '%s'\n", Printer_DYN, file, Errormsg(errno) ); if( Write_fd_str( *sock, buffer ) < 0 ) cleanup(0); } } } return(0); } static int Do_control_defaultq( int *sock ) { char msg [LINEBUFFER]; Printer_DYN = 0; /* get the default queue */ Get_printer(); plp_snprintf( msg, sizeof(msg), "%s\n", Printer_DYN ); if ( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); return(0); } lprng-3.8.B/src/common/accounting.c0000644000131400013140000001522211531672131014156 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: accounting.c,v 1.74 2004/09/24 20:19:57 papowell Exp $"; #include "lp.h" #include "accounting.h" #include "getqueue.h" #include "errorcodes.h" #include "child.h" #include "linksupport.h" #include "fileopen.h" /**** ENDINCLUDE ****/ /* Do_accounting is called with: status = Do_accounting( 0, Accounting_start_DYN, job, Send_job_rw_timeout_DYN ); OR status = Do_accounting( 0, Accounting_end_DYN, job, Send_job_rw_timeout_DYN ); The general approach is: You are going to do accounting. You either write accounting information to a file, or to a program. If the 'achk' flag is set then you write it to a program and then get back a 'proceed' indication. What you write is specified by the 'Accounting_start_DYN' (:as=) or 'Accounting_end_DYN' (:ae=) entries, or the 'Accounting_file_DYN' (:af=) entries. By default, the :as or :ae entries are a simple string and are interpreted as text to send. If they are a path (starting with "/" or "|") then they are a program to run. In this case we run the program with no input, expecting that the necessary options will be passed on the command line. If the :as (or :ae) is a string, then then :af is checked to see if it is a filter ("|/..."), network port ("host@port"), or file. If it is a filter, then the program is run, a network port then a connection is made to the remote host, and if a file, the file is opened. In all three cases the :as or :ae string is written to the program, socket, or file respectively. If we are starting the job and the :achk flag is set and have specified a filter (program) or host, then we now read the status back from the filter or remote host. The connection is then closed. If we are writing to a program then the exit status is first used to determine the disposition: JHOLD, JREMOVE, JABORT (or unknown) will cause the job to be held, removed, or aborted respectively. JSUCC will cause a line (or lines) to be read The first input line read from the remote program or host is used to determine job disposal. If the line is blank or starts with ACCEPT then the job will be printed, HOLD will hold the job, REMOVE will remove the job, and ABORT or a non-recognizable response will cause printing to be aborted. */ int Do_accounting( int end, char *command, struct job *job, int timeout ) { int n, err, len, tempfd; char msg[SMALLBUFFER]; char *s, *t; struct line_list args; struct stat statb; Init_line_list(&args); msg[0] = 0; err = JSUCC; while( isspace(cval(command)) ) ++command; s = command; if( cval(s) == '|' ) ++s; Add_line_list(&args, s,0,0,0); Fix_dollars(&args, job, 1, Filter_options_DYN ); s = args.list[0]; DEBUG1("Do_accounting: command '%s', af '%s', expanded '%s'", command, Accounting_file_DYN, s ); s = safeextend2(s,"\n",__FILE__,__LINE__); args.list[0] = s; tempfd = -1; if( (cval(command) == '|') || (cval(command) == '/') ){ if( end == 0 && Accounting_check_DYN ){ tempfd = Make_temp_fd( 0 ); } err = Filter_file( Send_query_rw_timeout_DYN,-1, tempfd, "ACCOUNTING_FILTER", command, Filter_options_DYN, job, 0, 1 ); if( tempfd > 0 && lseek(tempfd,0,SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Do_accounting: lseek tempfile failed"); } } else if( !ISNULL(Accounting_file_DYN) ){ if( (cval(Accounting_file_DYN) == '|') ){ int fd = Make_temp_fd(0); if( Write_fd_str( fd, args.list[0] ) < 0 ){ Errorcode= JFAIL; logerr_die(LOG_INFO, "Do_accounting: write to tempfile of '%s' failed", command); } if( fd > 0 && lseek(fd,0,SEEK_SET) == -1 ){ Errorcode= JFAIL; logerr_die(LOG_INFO, "Do_accounting: seek of tempfile failed" ); } if( end == 0 && Accounting_check_DYN ){ tempfd = Make_temp_fd( 0 ); } err = Filter_file( Send_query_rw_timeout_DYN,fd, tempfd, "ACCOUNTING_FILTER", Accounting_file_DYN, Filter_options_DYN, job, 0, 1 ); if( tempfd > 0 && lseek(tempfd,0,SEEK_SET) == -1 ){ Errorcode= JFAIL; logerr_die(LOG_INFO, "Do_accounting: seek of tempfile failed" ); } close(fd); } else if( isalnum(cval(Accounting_file_DYN)) && safestrchr( Accounting_file_DYN, '%' ) ){ /* now try to open a connection to a server */ char *host = Accounting_file_DYN; DEBUG2("Do_accounting: connecting to '%s'",host); if( (tempfd = Link_open(host,timeout,0, 0, msg, sizeof(msg) )) < 0 ){ err = errno; Errorcode= JFAIL; logerr_die(LOG_INFO, _("connection to accounting server '%s' failed '%s'"), Accounting_file_DYN, msg); } DEBUG2("Setup_accounting: socket %d", tempfd ); if( Write_fd_str( tempfd, args.list[0] ) < 0 ){ Errorcode= JFAIL; logerr_die(LOG_INFO, "Do_accounting: write to '%s' failed", command); } shutdown(tempfd,1); } else { tempfd = Checkwrite( Accounting_file_DYN, &statb, 0, Create_files_DYN, 0 ); if( !end ){ tempfd = Trim_status_file( tempfd, Accounting_file_DYN, Max_accounting_file_size_DYN, Min_accounting_file_size_DYN ); } DEBUG2("Do_accounting: fd %d", tempfd ); if( tempfd > 0 ){ if( Write_fd_str( tempfd, args.list[0] ) < 0 ){ err = errno; Errorcode= JFAIL; logerr_die(LOG_INFO, "Do_accounting: write to '%s' failed", command); } close(tempfd); tempfd = -1; } } } if( tempfd > 0 && err == 0 && end == 0 && Accounting_check_DYN ){ msg[0] = 0; len = 0; while( len < (int)(sizeof(msg)-1) && (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN,tempfd,msg+len,sizeof(msg)-1-len)) > 0 ){ msg[len+n] = 0; DEBUG1("Do_accounting: read %d, '%s'", n, msg ); } Free_line_list(&args); lowercase(msg); Split(&args,msg,Whitespace,0,0,0,0,0,0); err = JSUCC; if( args.count && (s = args.list[0]) ){ if( (t = safestrchr(s,'\n')) ) *t = 0; setstatus(job, "accounting filter replied with '%s'", s); if( *s == 0 || !safestrncasecmp( s, "accept", 6 ) ){ err = JSUCC; } else if( !safestrncasecmp( s, "hold", 4 ) ){ err = JHOLD; } else if( !safestrncasecmp( s, "remove", 6 ) ){ err = JREMOVE; } else if( !safestrncasecmp( s, "fail", 4 ) ){ err = JFAIL; } else { plp_snprintf( msg, sizeof(msg), "accounting check failed - status message '%s'", s ); err = JABORT; } } } if( tempfd > 0 ) close(tempfd); tempfd = -1; Free_line_list(&args); DEBUG2("Do_accounting: status %s", Server_status(err) ); return( err ); } lprng-3.8.B/src/common/proctitle.c0000644000131400013140000002261711531672132014040 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: proctitle.c,v 1.74 2004/09/24 20:19:58 papowell Exp $"; #include "lp.h" #include "proctitle.h" /**** ENDINCLUDE ****/ /* * SETPROCTITLE -- set process title for ps * proctitle( char *str ); * * Returns: none. * * Side Effects: Clobbers argv of our main procedure so ps(1) will * display the title. */ /* * From the Sendmail.8.8.8 Source Distribution * * Copyright (c) 1983, 1995-2000 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)conf.h 8.335 (Berkeley) 10/24/97 */ #ifdef __hpux # define SPT_TYPE SPT_PSTAT #endif #if defined(_AIX32) || defined(_AIX) || defined(AIX) || defined(IS_AIX32) # define SPT_PADCHAR '\0' /* pad process title with nulls */ #endif #ifdef DGUX # define SPT_TYPE SPT_NONE /* don't use setproctitle */ #endif #if defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__) # define SPT_TYPE SPT_PSSTRINGS /* use PS_STRINGS pointer */ #endif #ifdef __bsdi__ # if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312 # undef SPT_TYPE # define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ # else # define SPT_PADCHAR '\0' /* pad process title with nulls */ # endif #endif #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) # if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1) # undef SPT_TYPE # define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ # endif # if defined(__FreeBSD__) # undef SPT_TYPE # if __FreeBSD__ >= 2 # include /* and this works */ # if __FreeBSD_version >= 199512 /* 2.2-current right now */ # include # define SPT_TYPE SPT_BUILTIN # endif # endif # ifndef SPT_TYPE # define SPT_TYPE SPT_REUSEARGV # define SPT_PADCHAR '\0' /* pad process title with nulls */ # endif # endif # if defined(__OpenBSD__) # undef SPT_TYPE # define SPT_TYPE SPT_BUILTIN /* setproctitle is in libc */ # endif #endif #ifdef __GNU_HURD__ # define SPT_TYPE SPT_CHANGEARGV #endif /* GNU */ /* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */ #ifdef _SCO_unix_ # define SPT_TYPE SPT_SCO /* write kernel u. area */ #endif #ifdef __linux__ # define SPT_PADCHAR '\0' /* pad process title with nulls */ #endif #ifdef _SEQUENT_ # define SPT_TYPE SPT_NONE /* don't use setproctitle */ #endif #ifdef apollo # define SPT_TYPE SPT_NONE /* don't use setproctitle */ #endif #ifdef NCR_MP_RAS2 # define SPT_TYPE SPT_NONE #endif #ifdef NCR_MP_RAS3 # define SPT_TYPE SPT_NONE #endif /* ** SETPROCTITLE -- set process title for ps ** ** Parameters: ** fmt -- a printf style format string. ** a, b, c -- possible parameters to fmt. ** ** Returns: ** none. ** ** Side Effects: ** Clobbers argv of our main procedure so ps(1) will ** display the title. */ #define SPT_NONE 0 /* don't use it at all */ #define SPT_REUSEARGV 1 /* cover argv with title information */ #define SPT_BUILTIN 2 /* use libc builtin */ #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ #define SPT_SCO 6 /* write kernel u. area */ #define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ #ifndef SPT_TYPE # define SPT_TYPE SPT_REUSEARGV #endif #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN # if SPT_TYPE == SPT_PSTAT # include # endif # if SPT_TYPE == SPT_PSSTRINGS # include # include # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ # undef SPT_TYPE # define SPT_TYPE SPT_REUSEARGV # else # ifndef NKPDE /* FreeBSD 2.0 */ # define NKPDE 63 typedef unsigned int *pt_entry_t; # endif # endif # endif # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV # define SETPROC_STATIC static # else # define SETPROC_STATIC # endif # if SPT_TYPE == SPT_SYSMIPS # include # include # endif # if SPT_TYPE == SPT_SCO # include # include # include # include # if PSARGSZ > LINEBUFFER # define SPT_BUFSIZE PSARGSZ # endif # endif # ifndef SPT_PADCHAR # define SPT_PADCHAR ' ' # endif # ifndef SPT_BUFSIZE # define SPT_BUFSIZE LINEBUFFER # endif #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ /* ** Pointers for setproctitle. ** This allows "ps" listings to give more useful information. */ # if SPT_TYPE != SPT_BUILTIN static char **Argv = NULL; /* pointer to argument vector */ static char *LastArgv = NULL; /* end of argv */ #endif void initsetproctitle(argc, argv, envp) int argc; char **argv; char **envp; { # if SPT_TYPE != SPT_BUILTIN register int i, envpsize = 0; extern char **environ; /* ** Move the environment so setproctitle can use the space at ** the top of memory. */ DEBUG1("initsetproctitle: doing setup"); for (i = 0; envp[i] != NULL; i++) envpsize += safestrlen(envp[i]) + 1; { char *s; environ = (char **) malloc_or_die((sizeof (char *) * (i + 1))+envpsize+1,__FILE__,__LINE__); s = ((char *)environ)+((sizeof (char *) * (i + 1))); for (i = 0; envp[i] != NULL; i++){ strcpy(s,envp[i]); environ[i] = s; s += safestrlen(s)+1; } } environ[i] = NULL; /* ** Save start and extent of argv for setproctitle. */ Argv = argv; /* ** Determine how much space we can use for setproctitle. ** Use all contiguous argv and envp pointers starting at argv[0] */ for (i = 0; i < argc; i++) { if (i==0 || LastArgv + 1 == argv[i]) LastArgv = argv[i] + safestrlen(argv[i]); else continue; } for (i=0; envp[i] != NULL; i++) { if (LastArgv + 1 == envp[i]) LastArgv = envp[i] + safestrlen(envp[i]); else continue; } DEBUG1("initsetproctitle: Argv 0x%p, LastArgv 0x%p", Argv, LastArgv); #else DEBUG1("initsetproctitle: using builtin"); #endif } #if SPT_TYPE != SPT_BUILTIN void #ifdef HAVE_STDARGS setproctitle (const char *fmt,...) #else setproctitle (va_alist) va_dcl #endif { # if SPT_TYPE != SPT_NONE register int i; SETPROC_STATIC char buf[SPT_BUFSIZE]; # if SPT_TYPE == SPT_PSTAT union pstun pst; # endif # if SPT_TYPE == SPT_SCO off_t seek_off; static int kmem = -1; static int kmempid = -1; struct user u; # endif VA_LOCAL_DECL /* print the argument string */ VA_START (fmt); VA_SHIFT (fmt, char *); (void) plp_vsnprintf(buf, sizeof(buf), fmt, ap); VA_END; i = safestrlen(buf); # if SPT_TYPE == SPT_PSTAT pst.pst_command = buf; pstat(PSTAT_SETCMD, pst, i, 0, 0); # endif # if SPT_TYPE == SPT_PSSTRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = buf; # endif # if SPT_TYPE == SPT_SYSMIPS sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); # endif # if SPT_TYPE == SPT_SCO if (kmem < 0 || kmempid != getpid()) { if (kmem >= 0) close(kmem); kmem = open(_PATH_KMEM, O_RDWR, 0); if (kmem < 0) return; (void) fcntl(kmem, F_SETFD, 1); kmempid = getpid(); } buf[PSARGSZ - 1] = '\0'; seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) (void) write(kmem, buf, PSARGSZ); # endif # if SPT_TYPE == SPT_REUSEARGV if (i > LastArgv - Argv[0] - 2) { i = LastArgv - Argv[0] - 2; buf[i] = '\0'; } (void) strcpy(Argv[0], buf); { char *p; p = &Argv[0][i]; while (p < LastArgv) *p++ = SPT_PADCHAR; } Argv[1] = NULL; # endif # if SPT_TYPE == SPT_CHANGEARGV Argv[0] = buf; Argv[1] = 0; # endif # endif /* SPT_TYPE != SPT_NONE */ } #endif /* SPT_TYPE != SPT_BUILTIN */ lprng-3.8.B/src/common/lpf.c0000644000131400013140000004006111531672132012605 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /*************************************************************************** * Filter template and frontend. * * A filter is invoked with the following parameters, * which can be in any order, and perhaps some missing. * * filtername arguments \ <- from PRINTCAP entry * -PPrinter -wwidth -llength -xwidth -ylength [-c] \ * -Kcontrolfilename -Lbnrname \ * [-iindent] \ * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ * -Fformat [-Tcrlf] [-Tdebug] [affile] * * 1. Parameters can be in different order than the above. * 2. Optional parameters can be missing * 3. Values specified for the width, length, etc., are from PRINTCAP * or from the overridding user specified options. * * This program provides a common front end for most of the necessary * grunt work. This falls into the following classes: * 1. Parameter extraction. * 2. Suspension when used as the "of" filter. * 3. Termination and accounting * The front end will extract parameters, then call the filter_pgm() * routine, which is responsible for carrying out the required filter * actions. filter_pgm() is invoked with the printer device on fd 1, * and error log on fd 2. The npages variable is used to record the * number of pages that were used. * The "halt string", which is a sequence of characters that * should cause the filter to suspend itself, is passed to filter. * When these characters are detected, the "suspend_ofilter()" routine should be * called. * * On successful termination, the accounting file will be updated. * * The filter_pgm() routine should return 0 (success), 1 (retry) or 2 (abort). * * Parameter Extraction * The main() routine will extract parameters * whose values are placed in the appropriate variables. This is done * by using the ParmTable[], which has entries for each valid letter * parmeter, such as the letter flag, the type of variable, * and the address of the variable. * The following variables are provided as a default set. * -PPrinter -wwidth -llength -xwidth -ylength [-c] [-iindent] \ * [-Zoptions] [-Cclass] [-Jjob] [-Raccntname] -nlogin -hHost \ * -Fformat [affile] * VARIABLE FLAG TYPE PURPOSE / PRINTCAP ENTRTY * name name of filter char* argv[0], program identification * width -wwidth int PW, width in chars * length -llength int PL, length in lines * xwidth -xwidth int PX, width in pixels * xlength -xlength int PY, length in pixels * literal -c int if set, ignore control chars * controlfile -kcontrolfile char* control file name * bnrname -Lbnrname char* banner name * indent -iindent int indent amount (depends on device) * zopts -Zoptions char* extra options for printer * comment -Scomment char* printer name in comment field * class -Cclass char* classname * job -Jjob char* jobname * accntname -Raccntname char* account for billing purposes * login -nlogin char* login name * host -hhost char* host name * format -Fformat char* format * statusfile -sstatusfile char* statusfile * accntfile file char* AF, accounting file * * npages - number of pages for accounting * * -Tdebug - increment debug level * -Tcrlf - turn LF to CRLF translation off * * The functions logerr(), and logerr_die() can be used to report * status. The variable errorcode can be set by the user before calling * these functions, and will be the exit value of the program. Its default * value will be 2 (abort status). * logerr() reports a message, appends information indicated by errno * (see perror(2) for details), and then returns. * logerr_die() will call logerr(), and then will exit with errorcode * status. * * DEBUGGING: a simple minded debugging version can be enabled by * compiling with the -DDEBUG option. */ #include #include "portable.h" #include "plp_snprintf.h" /* VARARGS2 */ #ifdef HAVE_STDARGS static void safefprintf (int fd, const char *format,...) PRINTFATTR(2,3) ; #else static void safefprintf (); #endif #ifdef HAVE_STDARGS static void logerr(const char *msg, ...) PRINTFATTR(1,2) #else static void logerr( va_alist ) va_dcl #endif ; #ifdef HAVE_STDARGS static void logerr_die(const char *msg, ...) PRINTFATTR(1,2) #else static void logerr_die( va_alist ) va_dcl #endif ; #include #include #include #include #include #include #include #ifdef HAVE_STDLIB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_FILE_H # include #endif #ifdef HAVE_SYS_FCNTL_H # include #endif #ifdef HAVE_FCNTL_H # include #endif /* varargs declarations: */ #if defined(HAVE_STDARG_H) # include # define HAVE_STDARGS /* let's hope that works everywhere (mj) */ # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap, f) # define VA_SHIFT(v,t) ; /* no-op for ANSI */ # define VA_END va_end(ap) #else # if defined(HAVE_VARARGS_H) # include # undef HAVE_STDARGS # define VA_LOCAL_DECL va_list ap; # define VA_START(f) va_start(ap) /* f is ignored! */ # define VA_SHIFT(v,t) v = va_arg(ap,t) # define VA_END va_end(ap) # else XX ** NO VARARGS ** XX # endif #endif static char *lpf_time_str(void); static void filter_pgm(const char *stop); /* * default exit status, causes abort */ static int errorcode = 2; static const char *name; /* name of filter */ /* set from flags */ static int debug = 0; static int width = 80, length = 72, xwidth = 1440, ylength = -1; static int literal = 0, indent = 0; static const char *zopts = NULL, *class = NULL, *job = NULL, *login = NULL; static const char *accntname = NULL, *host = NULL, *accntfile= NULL; static const char *format = NULL, *printer = NULL, *controlfile = NULL; static const char *bnrname = NULL, *comment = NULL, *queuename = NULL; static const char *errorfile = NULL, *statusfile = NULL; static int npages; /* number of pages */ static int accounting_fd; static int crlf = 0; /* change lf to CRLF */ static void getargs( int argc, char *argv[], char *envp[] ); static int of_filter; int main( int argc, char *argv[], char *envp[] ) { /* check to see if you have the accounting fd */ accounting_fd = dup(3); /* if this works, then you have one */ if( accounting_fd >= 0 ){ (void)close( accounting_fd ); accounting_fd = 3; } else { accounting_fd = -1; } if( fcntl(0,F_GETFL,0) == -1 ){ FPRINTF(STDERR,"BAD FD 0\n"); exit(2); } if( fcntl(1,F_GETFL,0) == -1 ){ FPRINTF(STDERR,"BAD FD 1\n"); exit(2); } if( fcntl(2,F_GETFL,0) == -1 ){ FPRINTF(STDERR,"BAD FD 2\n"); exit(2); } getargs( argc, argv, envp ); /* * Turn off SIGPIPE */ (void)signal( SIGPIPE, SIG_IGN ); (void)signal( SIGINT, SIG_DFL ); (void)signal( SIGHUP, SIG_DFL ); (void)signal( SIGQUIT, SIG_DFL ); (void)signal( SIGCHLD, SIG_DFL ); if( of_filter || (format && format[0] == 'o') ){ filter_pgm( "\031\001" ); } else { filter_pgm( (char *)0 ); } return(0); } static int Write_fd_str( int fd, const char *msg ) { int n; n = strlen(msg); return write(fd,msg,n); } /* VARARGS2 */ #ifdef HAVE_STDARGS void safefprintf (int fd, const char *format,...) #else void safefprintf (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS int fd; char *format; #endif char buf[1024]; VA_LOCAL_DECL VA_START (format); VA_SHIFT (fd, int); VA_SHIFT (format, char *); buf[0] = 0; (void) plp_vsnprintf(buf, sizeof(buf), format, ap); Write_fd_str(fd,buf); } /**************************************************************************** * Extract the necessary definitions for error message reporting ****************************************************************************/ #ifdef HAVE_STRERROR #define Errormsg strerror #else static const char * Errormsg ( int err ) { if( err == 0 ){ return "No Error"; } else { static char msgbuf[32]; /* holds "errno=%d". */ (void) plp_snprintf(msgbuf, sizeof(msgbuf), "errno=%d", err); return msgbuf; } } #endif #ifdef HAVE_STDARGS static void logerr(const char *msg, ...) #else static void logerr( va_alist ) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif int err = errno; int n; char buf[1024]; VA_LOCAL_DECL VA_START(msg); VA_SHIFT(msg, char *); (void)plp_snprintf(buf,sizeof(buf), "%s: ", name); n = strlen(buf); (void)plp_vsnprintf(buf+n,sizeof(buf)-n, msg, ap); n = strlen(buf); (void)plp_snprintf(buf+n,sizeof(buf)-n, "- %s\n", Errormsg(err) ); Write_fd_str(2,buf); VA_END; } #ifdef HAVE_STDARGS static void logerr_die(const char *msg, ...) #else static void logerr_die( va_alist ) va_dcl #endif { #ifndef HAVE_STDARGS char *msg; #endif int err = errno; int n; char buf[1024]; VA_LOCAL_DECL VA_START(msg); VA_SHIFT(msg, char *); (void)plp_snprintf(buf,sizeof(buf), "%s: ", name); n = strlen(buf); (void)plp_vsnprintf(buf+n,sizeof(buf)-n, msg, ap); n = strlen(buf); (void)plp_snprintf(buf+n,sizeof(buf)-n, "- %s\n", Errormsg(err) ); Write_fd_str(2,buf); VA_END; exit(errorcode); } /* * doaccnt() * writes the accounting information to the accounting file * This has the format: user host printer pages format date */ static void doaccnt(void) { char buffer[256]; FILE *f; int l, len, c; plp_snprintf(buffer, sizeof(buffer), "%s\t%s\t%s\t%7d\t%s\t%s\n", login? login: "NULL", host? host: "NULL", printer? printer: "NULL", npages, format? format: "NULL", lpf_time_str()); len = strlen( buffer ); if( accounting_fd < 0 ){ if(accntfile && (f = fopen(accntfile, "a" )) != NULL ) { accounting_fd = fileno( f ); } } if( accounting_fd >= 0 ){ for( c = l = 0; c >= 0 && l < len; l += c ){ c = write( accounting_fd, &buffer[l], len-l ); } if( c < 0 ){ logerr( "bad write to accounting file" ); } } } static void getargs( int argc, char *argv[], char *envp[] ) { int i, c; /* argument index */ char *arg, *optargv; /* argument */ char *s, *end; const char *n; if( (name = argv[0]) == 0 ) name = "FILTER"; if( (n = strrchr( name, '/' )) ){ ++n; } else { n = name; } of_filter = (strstr( n, "of" ) != 0); for( i = 1; i < argc && (arg = argv[i])[0] == '-'; ++i ){ if( (c = arg[1]) == 0 ){ FPRINTF( STDERR, "missing option flag"); i = argc; break; } if( c == 'c' ){ literal = 1; continue; } optargv = &arg[2]; if( arg[2] == 0 ){ optargv = argv[++i]; if( optargv == 0 ){ FPRINTF( STDERR, "missing option '%c' value", c ); i = argc; break; } } switch(c){ case 'C': class = optargv; break; case 'E': errorfile = optargv; break; case 'T': for( s = optargv; s && *s; s = end ){ end = strchr( s, ',' ); if( end ){ *end++ = 0; } if( !strcasecmp( s, "crlf" ) ){ crlf = 1; } if( !strcasecmp( s, "debug" ) ){ ++debug; } } break; case 'F': format = optargv; break; case 'J': job = optargv; break; case 'K': controlfile = optargv; break; case 'L': bnrname = optargv; break; case 'P': printer = optargv; break; case 'Q': queuename = optargv; break; case 'R': accntname = optargv; break; case 'S': comment = optargv; break; case 'Z': zopts = optargv; break; case 'h': host = optargv; break; case 'i': indent = atoi( optargv ); break; case 'l': length = atoi( optargv ); break; case 'n': login = optargv; break; case 's': statusfile = optargv; break; case 'w': width = atoi( optargv ); break; case 'x': xwidth = atoi( optargv ); break; case 'y': ylength = atoi( optargv ); break; default: break; } } if( i < argc ){ accntfile = argv[i]; } if( errorfile ){ int fd; fd = open( errorfile, O_APPEND | O_WRONLY, 0600 ); if( fd < 0 ){ FPRINTF( STDERR, "cannot open error log file '%s'", errorfile ); } else { FPRINTF( STDERR, "using error log file '%s'", errorfile ); if( fd != 2 ){ dup2(fd, 2 ); close(fd); } } } if( debug ){ FPRINTF(STDERR, "%s command: ", name ); for( i = 0; i < argc; ++i ){ FPRINTF(STDERR, "%s ", argv[i] ); } FPRINTF( STDERR, "\n" ); } if( debug ){ FPRINTF(STDERR, "FILTER decoded options: " ); FPRINTF(STDERR,"accntfile '%s'\n", accntfile? accntfile : "null" ); FPRINTF(STDERR,"accntname '%s'\n", accntname? accntname : "null" ); FPRINTF(STDERR,"class '%s'\n", class? class : "null" ); FPRINTF(STDERR,"errorfile '%s'\n", errorfile? errorfile : "null" ); FPRINTF(STDERR,"format '%s'\n", format? format : "null" ); FPRINTF(STDERR,"host '%s'\n", host? host : "null" ); FPRINTF(STDERR,"indent, %d\n", indent); FPRINTF(STDERR,"job '%s'\n", job? job : "null" ); FPRINTF(STDERR,"length, %d\n", length); FPRINTF(STDERR,"literal, %d\n", literal); FPRINTF(STDERR,"login '%s'\n", login? login : "null" ); FPRINTF(STDERR,"printer '%s'\n", printer? printer : "null" ); FPRINTF(STDERR,"queuename '%s'\n", queuename? queuename : "null" ); FPRINTF(STDERR,"statusfile '%s'\n", statusfile? statusfile : "null" ); FPRINTF(STDERR,"width, %d\n", width); FPRINTF(STDERR,"xwidth, %d\n", xwidth); FPRINTF(STDERR,"ylength, %d\n", ylength); FPRINTF(STDERR,"zopts '%s'\n", zopts? zopts : "null" ); FPRINTF(STDERR, "FILTER environment: " ); for( i = 0; (arg = envp[i]); ++i ){ FPRINTF(STDERR,"%s\n", arg ); } FPRINTF(STDERR, "RUID: %d, EUID: %d\n", (int)getuid(), (int)geteuid() ); } } /* * suspend_ofilter(): suspends the output filter, waits for a signal */ static void suspend_ofilter(void) { fflush(stdout); fflush(stderr); if(debug)FPRINTF(STDERR,"FILTER suspending\n"); kill(getpid(), SIGSTOP); if(debug)FPRINTF(STDERR,"FILTER awake\n"); } /****************************************** * prototype filter() * filter will scan the input looking for the suspend string * if any. ******************************************/ static void filter_pgm(const char *stop) { int c; int state, i, xout, lastc; int lines = 0; char inputline[1024]; int inputcount = 0; /* * do whatever initializations are needed */ /* FPRINTF(STDERR, "filter ('%s')\n", stop ? stop : "NULL" ); */ /* * now scan the input string, looking for the stop string */ lastc = xout = state = 0; npages = 1; inputcount = 0; while( (c = getchar()) != EOF ){ if( inputcount < (int)sizeof(inputline) - 3 ) inputline[inputcount++] = c; if( c == '\n' ){ inputline[inputcount-1] = 0; if(debug)FPRINTF(STDERR,"INPUTLINE count %d '%s'\n", inputcount, inputline ); inputcount = 0; ++lines; if( lines > length ){ lines -= length; ++npages; } if( !literal && crlf == 0 && lastc != '\r' ){ putchar( '\r' ); } } if( c == '\014' ){ ++npages; lines = 0; if( !literal && crlf == 0 ){ putchar( '\r' ); } } if( stop ){ if( c == stop[state] ){ ++state; if( stop[state] == 0 ){ state = 0; suspend_ofilter(); } } else if( state ){ for( i = 0; i < state; ++i ){ putchar( stop[i] ); } state = 0; putchar( c ); } else { putchar( c ); } } else { putchar( c ); } lastc = c; } if( ferror( stdin ) ){ logerr( "error on STDIN"); } for( i = 0; i < state; ++i ){ putchar( stop[i] ); } if( lines > 0 ){ ++npages; } doaccnt(); } /* * Time_str: return "cleaned up" ctime() string... * * in YY/MO/DY/hr:mn:sc * Thu Aug 4 12:34:17 BST 1994 -> 12:34:17 */ static char *lpf_time_str(void) { static char buffer[99]; struct tm *tmptr; struct timeval tv; tv.tv_usec = 0; if( gettimeofday( &tv, 0 ) == -1 ){ logerr_die( "Time_str: gettimeofday failed"); } tmptr = localtime( &tv.tv_sec ); plp_snprintf( buffer, sizeof(buffer), "%d-%02d-%02d-%02d:%02d:%02d.%03d", tmptr->tm_year+1900, tmptr->tm_mon+1, tmptr->tm_mday, tmptr->tm_hour, tmptr->tm_min, tmptr->tm_sec, (int)(tv.tv_usec/1000) ); return( buffer ); } lprng-3.8.B/src/common/lpd_status.c0000644000131400013140000012525711531672132014221 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ #include "lp.h" #include "getopt.h" #include "gethostinfo.h" #include "proctitle.h" #include "getprinter.h" #include "getqueue.h" #include "child.h" #include "fileopen.h" #include "sendreq.h" #include "globmatch.h" #include "permission.h" #include "lockfile.h" #include "errorcodes.h" #include "lpd_jobs.h" #include "lpd_status.h" /**** ENDINCLUDE ****/ /*************************************************************************** * Commentary: * Patrick Powell Tue May 2 09:32:50 PDT 1995 * * Return status: * status has two formats: short and long * * Status information is obtained from 3 places: * 1. The status file * 2. any additional progress files indicated in the status file * 3. job queue * * The status file is maintained by the current unspooler process. * It updates this file with the following information: * * PID of the unspooler process [line 1] * active job and status file name * active job and status file name * * Example 1: * 3012 * cfa1024host status * * Example 2: * 3015 * cfa1024host statusfd2 * cfa1026host statusfd1 * * Format of the information reporting: * * 0 1 2 3 4 5 6 7 * 12345678901234567890123456789012345678901234567890123456789012345678901234 * Rank Owner/ID Class Job Files Size Time * 1 papowell@astart4+322 A 322 /tmp/hi 3 17:33:47 * x Sx SxSx Sx Sx Sx X * ***************************************************************************/ #define RANKW 7 #define OWNERW 29 #define CLASSW 2 #define JOBW 6 #define FILEW 18 #define SIZEW 6 #define TIMEW 8 static void Print_status_info( int *sock, char *file, char *prefix, int status_lines, int max_size ); int Job_status( int *sock, char *input ) { char *s, *t, *name, *hash_key; int displayformat, status_lines = 0, i, n; struct line_list l, listv; struct line_list done_list; char error[SMALLBUFFER], buffer[16]; int db, dbflag; Init_line_list(&l); Init_line_list(&listv); Init_line_list(&done_list); db = Debug; dbflag = DbgFlag; Name = "Job_status"; /* get the format */ if( (s = safestrchr(input, '\n' )) ) *s = 0; displayformat = *input++; /* * if we get a short/long request from these hosts, * reverse the sense of question */ if( Reverse_lpq_status_DYN && (displayformat == REQ_DSHORT || displayformat==REQ_DLONG) ){ Free_line_list(&l); Split(&l,Reverse_lpq_status_DYN,File_sep,0,0,0,0,0,0); if( Match_ipaddr_value( &l, &RemoteHost_IP ) == 0 ){ DEBUGF(DLPQ1)("Job_status: reversing status sense"); if( displayformat == REQ_DSHORT ){ displayformat = REQ_DLONG; } else { displayformat = REQ_DSHORT; } } Free_line_list(&l); } /* * we have a list of hosts with format of the form: * Key=list; Key=list;... * key is s for short, l for long */ DEBUGF(DLPQ1)("Job_status: Force_lpq_status_DYN '%s'", Force_lpq_status_DYN); if( Force_lpq_status_DYN ){ Free_line_list(&listv); Split(&listv,Force_lpq_status_DYN,";",0,0,0,0,0,0); for(i = 0; i < listv.count; ++i ){ s = listv.list[i]; if( (t = safestrpbrk(s,Hash_value_sep)) ) *t++ = 0; Free_line_list(&l); Split(&l,t,File_sep,0,0,0,0,0,0); DEBUGF(DLPQ1)("Job_status: Force_lpq_status '%s'='%s'", s,t); if( Match_ipaddr_value( &l, &RemoteHost_IP ) == 0 ){ DEBUGF(DLPQ1)("Job_status: forcing status '%s'", s); if( safestrcasecmp(s,"s") == 0 ){ displayformat = REQ_DSHORT; } else if( safestrcasecmp(s,"l") == 0 ){ displayformat = REQ_DLONG; } status_lines = Short_status_length_DYN; break; } } Free_line_list(&l); Free_line_list(&listv); } /* * check for short status to be returned */ if( Return_short_status_DYN && displayformat == REQ_DLONG ){ Free_line_list(&l); Split(&l,Return_short_status_DYN,File_sep,0,0,0,0,0,0); if( Match_ipaddr_value( &l, &RemoteHost_IP ) == 0 ){ status_lines = Short_status_length_DYN; DEBUGF(DLPQ1)("Job_status: truncating status to %d", status_lines); } Free_line_list(&l); } DEBUGF(DLPQ1)("Job_status: doing '%s'", input ); Free_line_list(&l); Split(&l,input,Whitespace,0,0,0,0,0,0); if( l.count == 0 ){ plp_snprintf( error, sizeof(error), "zero length command line"); goto error; } /* save l.list[0] */ name = l.list[0]; if( (s = Is_clean_name( name )) ){ plp_snprintf( error, sizeof(error), _("printer '%s' has illegal character at '%s' in name"), name, s ); goto error; } Set_DYN(&Printer_DYN,name); setproctitle( "lpd %s '%s'", Name, name ); plp_snprintf(buffer,sizeof(buffer), "%d",displayformat); l.list[0] = buffer; /* we have the hash key */ hash_key = Join_line_list_with_sep(&l,"_"); for( s = hash_key; (s = strpbrk(s,Whitespace)); ) *s = '_'; DEBUGF(DLPQ1)("Job_status: arg '%s'", s ); /* now we put back the l.list[0] value */ l.list[0] = name; /* free the values l.list[0] */ Remove_line_list( &l, 0 ); name = Printer_DYN; if( l.count && (s = l.list[0]) && s[0] == '-' ){ DEBUGF(DLPQ1)("Job_status: arg '%s'", s ); Free_line_list(&listv); Split(&listv,s+1,Arg_sep,1,Hash_value_sep,1,1,0,0); Remove_line_list( &l, 0 ); DEBUGFC(DLPQ1)Dump_line_list( "Job_status: args", &listv ); if( (n = Find_flag_value(&listv,"lines")) ) status_lines = n; DEBUGF(DLPQ1)("Job_status: status_lines '%d'", status_lines ); Free_line_list(&listv); } if( safestrcasecmp( name, ALL ) ){ DEBUGF(DLPQ1)("Job_status: checking printcap entry '%s'", name ); Get_queue_status( &l, sock, displayformat, status_lines, &done_list, Max_status_size_DYN, hash_key ); } else { /* we work our way down the printcap list, checking for ones that have a spool queue */ /* note that we have already tried to get the 'all' list */ Get_all_printcap_entries(); for( i = 0; i < All_line_list.count; ++i ){ Set_DYN(&Printer_DYN, All_line_list.list[i] ); Debug = db; DbgFlag = dbflag; Get_queue_status( &l, sock, displayformat, status_lines, &done_list, Max_status_size_DYN, hash_key ); } } Free_line_list( &l ); Free_line_list( &listv ); Free_line_list( &done_list ); DEBUGF(DLPQ3)("Job_status: DONE" ); return(0); error: DEBUGF(DLPQ2)("Job_status: error msg '%s'", error ); i = safestrlen(error); if( (i = safestrlen(error)) >= (int)sizeof(error)-2 ){ i = sizeof(error) - 2; } error[i++] = '\n'; error[i] = 0; Free_line_list( &l ); Free_line_list( &listv ); Free_line_list( &done_list ); if( Write_fd_str( *sock, error ) < 0 ) cleanup(0); DEBUGF(DLPQ3)("Job_status: done" ); return(0); } /*************************************************************************** * void Get_queue_status * sock - used to send information * displayformat - REQ_DSHORT, REQ_DLONG, REQ_VERBOSE * tokens - arguments * - get the printcap entry (if any) * - check the control file for current status * - find and report the spool queue entries ***************************************************************************/ void Get_queue_status( struct line_list *tokens, int *sock, int displayformat, int status_lines, struct line_list *done_list, int max_size, char *hash_key ) { char msg[SMALLBUFFER], buffer[SMALLBUFFER], error[SMALLBUFFER], number[LINEBUFFER], header[LARGEBUFFER]; char sizestr[SIZEW+TIMEW+32]; const char *identifier, *cs; char *pr, *s, *t, *path, *jobname, *joberror, *class, *priority, *d_identifier, *job_time, *d_error, *d_dest, *cftransfername, *hf_name, *filenames, *tempfile = 0, *file = 0, *end_of_name; struct line_list outbuf, info, lineinfo, cache, cache_info; int status = 0, len, ix, nx, flag, count, held, move, server_pid, unspooler_pid, fd, nodest, printable, dcount, destinations = 0, d_copies, d_copy_done, permission, jobnumber, db, dbflag, matches, tempfd, savedfd, lockfd, delta, err, cache_index, total_held, total_move, jerror, jdone; double jobsize; struct stat statb; struct job job; time_t modified = 0; time_t timestamp = 0; time_t now = time( (void *)0 ); cache_index = -1; DEBUG1("Get_queue_status: sock fd %d, checking '%s'", *sock, Printer_DYN ); if(DEBUGL1)Dump_line_list( "Get_queue_status: done_list", done_list ); /* set printer name and printcap variables */ Init_job(&job); Init_line_list(&info); Init_line_list(&lineinfo); Init_line_list(&outbuf); Init_line_list(&cache); Init_line_list(&cache_info); /* for caching */ tempfile = 0; savedfd = tempfd = lockfd = -1; Check_max(tokens,2); tokens->list[tokens->count] = 0; msg[0] = 0; header[0] = 0; error[0] = 0; pr = 0; s = 0; safestrncpy(buffer,Printer_DYN); status = Setup_printer( Printer_DYN, error, sizeof(error), 0); if( status ){ if( error[0] == 0 ){ plp_snprintf(error,sizeof(error), "Nonexistent printer '%s'", Printer_DYN); } goto error; } db = Debug; dbflag = DbgFlag; s = Find_str_value(&Spool_control,DEBUG); if( !s ) s = New_debug_DYN; Parse_debug( s, 0 ); if( !(DLPQMASK & DbgFlag) ){ Debug = db; DbgFlag = dbflag; } else { int odb, odbf; odb = Debug; odbf = DbgFlag; Debug = db; DbgFlag = dbflag; if( Log_file_DYN ){ fd = Trim_status_file( -1, Log_file_DYN, Max_log_file_size_DYN, Min_log_file_size_DYN ); if( fd > 0 && fd != 2 ){ dup2(fd,2); close(fd); close(fd); } } Debug = odb; DbgFlag = odbf; } DEBUGF(DLPQ3)("Get_queue_status: sock fd %d, Setup_printer status %d '%s'", *sock, status, error ); /* set up status */ if( Find_exists_value(done_list,Printer_DYN,Hash_value_sep ) ){ return; } Add_line_list(done_list,Printer_DYN,Hash_value_sep,1,1); /* check for permissions */ Perm_check.service = 'Q'; Perm_check.printer = Printer_DYN; permission = Perms_check( &Perm_line_list, &Perm_check, 0, 0 ); DEBUGF(DLPQ1)("Job_status: permission '%s'", perm_str(permission)); if( permission == P_REJECT ){ plp_snprintf( error, sizeof(error), _("%s: no permission to show status"), Printer_DYN ); goto error; } /* check to see if we have any cached information */ if( Lpq_status_cached_DYN > 0 && Lpq_status_file_DYN ){ fd = -1; do{ DEBUGF(DLPQ1)("Job_status: getting lock on '%s'", Lpq_status_file_DYN); lockfd = Checkwrite( Lpq_status_file_DYN, &statb, O_RDWR, 1, 0 ); if( lockfd < 0 ){ logerr_die(LOG_INFO, "Get_queue_status: cannot open '%s'", Lpq_status_file_DYN); } if( Do_lock(lockfd, 0) < 0 ){ DEBUGF(DLPQ1)("Get_queue_status: did not get lock"); Do_lock(lockfd, 1); DEBUGF(DLPQ1)("Get_queue_status: lock released"); close(lockfd); lockfd = -1; } }while( lockfd < 0 ); DEBUGF(DLPQ1)("Get_queue_status: lock succeeded"); Free_line_list(&cache); Get_fd_image_and_split(lockfd, 0,0,&cache,Line_ends,0,0,0,0,0,0); DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status- cache", &cache ); DEBUGF(DLPQ3)("Get_queue_status: cache hash_key '%s'", hash_key ); file = 0; nx = -1; if( cache.count < Lpq_status_cached_DYN ){ Check_max(&cache,Lpq_status_cached_DYN-cache.count); for( ix = cache.count; ix < Lpq_status_cached_DYN; ++ix ){ cache.list[ix] = 0; } cache.count = ix; } for( ix = 0; file == 0 && ix < cache.count; ++ix ){ if( (s = cache.list[ix]) ){ if( (t = safestrchr(s,'=')) ){ *t = 0; if( !strcmp(hash_key,s) ){ file = t+1; cache_index = ix; } *t = '='; } } } /* if we have a file name AND it is not stale then we use it */ DEBUGF(DLPQ3)("Get_queue_status: found in cache '%s'", file ); fd = -1; if( file ){ Split(&cache_info,file,Arg_sep,1,Hash_value_sep,1,1,0,0); file = Find_str_value(&cache_info,FILENAMES); } DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status: cache_info", &cache_info ); if( file && (fd = Checkread( file, &statb )) > 0 ){ modified = statb.st_mtime; delta = now - modified; if( Lpq_status_stale_DYN && delta > Lpq_status_stale_DYN ){ /* we cannot use it */ close(fd); fd = -1; } } if( fd > 0 ){ modified = 0; if( Queue_status_file_DYN && stat(Queue_status_file_DYN,&statb) == 0 ){ modified = statb.st_mtime; } timestamp = Find_flag_value(&cache_info,QUEUE_STATUS_FILE); delta = modified - timestamp; DEBUGF(DLPQ3)("Get_queue_status: queue status '%s', modified %lx, timestamp %lx, delta %d", Queue_status_file_DYN, (long)(modified), (long)(timestamp), delta ); if( delta > Lpq_status_interval_DYN ){ /* we need to refresh the data */ close(fd); fd = -1; } } if( fd > 0 ){ if( Status_file_DYN && stat(Status_file_DYN,&statb) == 0 ){ modified = statb.st_mtime; } timestamp = Find_flag_value(&cache_info,PRSTATUS); delta = modified - timestamp; DEBUGF(DLPQ3)("Get_queue_status: pr status '%s', modified %lx, timestamp %lx, delta %d", Status_file_DYN, (long)(modified), (long)(timestamp), delta ); if( delta > Lpq_status_interval_DYN ){ /* we need to refresh the data */ close(fd); fd = -1; } } if( fd > 0 ){ DEBUGF(DLPQ3)("Get_queue_status: reading cached status from fd '%d'", fd ); /* We can read the status from the cached data */ while( (ix = ok_read( fd, buffer, sizeof(buffer)-1 )) > 0 ){ if( write( *sock, buffer, ix ) < 0 ){ cleanup(0); } } close(fd); fd = -1; goto remote; } /* OK, we have to cache the status in a file */ tempfd = Make_temp_fd( &tempfile ); savedfd = *sock; *sock = tempfd; } end_of_name = 0; if( displayformat != REQ_DSHORT ){ plp_snprintf( header, sizeof(header), "%s: ", Server_queue_name_DYN?"Server Printer":"Printer" ); } len = strlen(header); plp_snprintf( header+len, sizeof(header)-len, "%s@%s", Printer_DYN, Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN ); if( safestrcasecmp( buffer, Printer_DYN ) ){ len = strlen(header); plp_snprintf( header+len, sizeof(header)-len, _(" (originally %s)"), buffer ); } end_of_name = header+strlen(header); /* TODO: gcc complains that is never looked at. And indeed it looks like * status is checked above and it does not end up here. * Why is this code here? - brl */ if( status ){ len = strlen( header ); if( displayformat == REQ_VERBOSE ){ safestrncat( header, _("\n Error: ") ); len = strlen( header ); } if( error[0] ){ plp_snprintf( header+len, sizeof(header)-len, _(" - %s"), error ); } else if( !Spool_dir_DYN ){ plp_snprintf( header+len, sizeof(header)-len, _(" - printer %s@%s not in printcap"), Printer_DYN, Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" - printer %s@%s has bad printcap entry"), Printer_DYN, Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN ); } safestrncat( header, "\n" ); DEBUGF(DLPQ3)("Get_queue_status: forward header '%s'", header ); if( Write_fd_str( *sock, header ) < 0 ) cleanup(0); header[0] = 0; goto done; } if( displayformat == REQ_VERBOSE ){ safestrncat( header, "\n" ); if( Write_fd_str( *sock, header ) < 0 ) cleanup(0); header[0] = 0; } /* get the spool entries */ Free_line_list( &outbuf ); Scan_queue( &Spool_control, &Sort_order, &printable,&held,&move,0,0,0,0,0 ); /* check for done jobs, remove any if there are some */ if( Remove_done_jobs() ){ Scan_queue( &Spool_control, &Sort_order, &printable,&held,&move,0,0,0,0,0 ); } DEBUGF(DLPQ3)("Get_queue_status: total files %d", Sort_order.count ); DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status- Sort_order", &Sort_order ); /* set up the short format for folks */ if( displayformat == REQ_DLONG && Sort_order.count > 0 ){ /* Rank Owner/ID Class Job Files Size Time */ Add_line_list(&outbuf, " Rank Owner/ID Pr/Class Job Files Size Time" ,0,0,0); } error[0] = 0; matches = 0; total_held = 0; total_move = 0; for( count = 0; count < Sort_order.count; ++count ){ int printable, held, move; char prclass[32]; printable = held = move = 0; Free_job(&job); Get_job_ticket_file( 0, &job, Sort_order.list[count] ); if( job.info.count == 0 ){ /* job was removed */ continue; } Job_printable(&job,&Spool_control, &printable,&held,&move,&jerror,&jdone); DEBUGF(DLPQ3)("Get_queue_status: printable %d, held %d, move %d, error %d, done %d", printable, held, move, jerror, jdone ); DEBUGFC(DLPQ4)Dump_job("Get_queue_status - info", &job ); if( job.info.count == 0 ) continue; if( tokens->count && Patselect( tokens, &job.info, 0) ){ continue; } number[0] = 0; error[0] = 0; msg[0] = 0; nodest = 0; s = Find_str_value(&job.info,PRSTATUS); if( s == 0 ){ plp_snprintf(number,sizeof(number), "%d",count+1); } else { plp_snprintf(number,sizeof(number), "%s",s); } identifier = Find_str_value(&job.info,IDENTIFIER); if( identifier == 0 ){ identifier = Find_str_value(&job.info,LOGNAME); } if( identifier == 0 ){ identifier = "???"; } priority = Find_str_value(&job.info,PRIORITY); class = Find_str_value(&job.info,CLASS); jobname = Find_str_value(&job.info,JOBNAME); filenames = Find_str_value(&job.info,FILENAMES); jobnumber = Find_decimal_value(&job.info,NUMBER); joberror = Find_str_value(&job.info,ERROR); jobsize = Find_double_value(&job.info,SIZE); job_time = Find_str_value(&job.info,JOB_TIME ); destinations = Find_flag_value(&job.info,DESTINATIONS); cftransfername = Find_str_value(&job.info,XXCFTRANSFERNAME); hf_name = Find_str_value(&job.info,HF_NAME); /* we report this jobs status */ DEBUGF(DLPQ3)("Get_queue_status: joberror '%s'", joberror ); DEBUGF(DLPQ3)("Get_queue_status: class '%s', priority '%s'", class, priority ); if( class ){ if( safestrcmp(class,priority) || Class_in_status_DYN || priority == 0 ){ plp_snprintf( prclass, sizeof(prclass), "%s/%s", priority?priority:"?", class ); priority = prclass; } } if( displayformat == REQ_DLONG ){ plp_snprintf( msg, sizeof(msg), "%-*s %-*s ", RANKW-1, number, OWNERW-1, identifier ); while( (len = safestrlen(msg)) > (RANKW+OWNERW) && isspace(cval(msg+len-1)) && isspace(cval(msg+len-2)) ){ msg[len-1] = 0; } plp_snprintf( buffer, sizeof(buffer), "%-*s %*d ", CLASSW-1,priority, JOBW-1,jobnumber); DEBUGF(DLPQ3)("Get_queue_status: msg len %d '%s', buffer %d, '%s'", safestrlen(msg),msg, safestrlen(buffer), buffer ); DEBUGF(DLPQ3)("Get_queue_status: RANKW %d, OWNERW %d, CLASSW %d, JOBW %d", RANKW, OWNERW, CLASSW, JOBW ); s = buffer; while( safestrlen(buffer) > CLASSW+JOBW && (s = safestrchr(s,' ')) ){ if( cval(s+1) == ' ' ){ memmove(s,s+1,safestrlen(s)+1); } else { ++s; } } s = msg+safestrlen(msg)-1; while( safestrlen(msg) + safestrlen(buffer) > RANKW+OWNERW+CLASSW+JOBW ){ if( cval(s) == ' ' && cval(s-1) == ' ' ){ *s-- = 0; } else { break; } } s = buffer; while( safestrlen(msg) + safestrlen(buffer) > RANKW+OWNERW+CLASSW+JOBW && (s = safestrchr(s,' ')) ){ if( cval(s+1) == ' ' ){ memmove(s,s+1,safestrlen(s)+1); } else { ++s; } } len = safestrlen(msg); plp_snprintf(msg+len, sizeof(msg)-len, "%s",buffer); if( joberror ){ len = safestrlen(msg); plp_snprintf(msg+len,sizeof(msg)-len, "ERROR: %s", joberror ); } else { char jobb[32]; DEBUGF(DLPQ3)("Get_queue_status: jobname '%s'", jobname ); len = safestrlen(msg); plp_snprintf(msg+len,sizeof(msg)-len, "%-s",jobname?jobname:filenames); plp_snprintf(jobb,sizeof(jobb), "%0.0f", jobsize ); job_time = Time_str(1, Convert_to_time_t(job_time)); if( !Full_time_DYN && (t = safestrchr(job_time,'.')) ) *t = 0; plp_snprintf( sizestr, sizeof(sizestr), "%*s %-s", SIZEW-1,jobb, job_time ); DEBUGF(DLPQ3)("XGet_queue_status: size_str '%s'",sizestr); len = Max_status_line_DYN; if( len >= (int)sizeof(msg)) len = sizeof(msg)-1; len = len-safestrlen(sizestr); if( len > 0 ){ /* pad with spaces */ for( nx = safestrlen(msg); nx < len; ++nx ){ msg[nx] = ' '; } msg[nx] = 0; } /* remove spaces if necessary */ while( safestrlen(msg) + safestrlen(sizestr) > Max_status_line_DYN ){ if( isspace( cval(sizestr) ) ){ memmove(sizestr, sizestr+1, safestrlen(sizestr)+1); } else { s = msg+safestrlen(msg)-1; if( isspace(cval(s)) && isspace(cval(s-1)) ){ s[0] = 0; } else { break; } } } if( safestrlen(msg) + safestrlen(sizestr) >= Max_status_line_DYN ){ len = Max_status_line_DYN - safestrlen(sizestr); msg[len-1] = ' '; msg[len] = 0; } strcpy( msg+safestrlen(msg), sizestr ); } if( Max_status_line_DYN < (int)sizeof(msg) ) msg[Max_status_line_DYN] = 0; DEBUGF(DLPQ3)("Get_queue_status: adding '%s'", msg ); Add_line_list(&outbuf,msg,0,0,0); DEBUGF(DLPQ3)("Get_queue_status: destinations '%d'", destinations ); if( nodest == 0 && destinations ){ for( dcount = 0; dcount < destinations; ++dcount ){ if( Get_destination( &job, dcount ) ) continue; DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status: destination", &job.destination); d_error = Find_str_value(&job.destination,ERROR); d_dest = Find_str_value(&job.destination,DEST); d_copies = Find_flag_value(&job.destination,COPIES); d_copy_done = Find_flag_value(&job.destination,COPY_DONE); d_identifier = Find_str_value(&job.destination,IDENTIFIER); cs = Find_str_value(&job.destination, PRSTATUS); if( !cs ) cs = ""; plp_snprintf(number, sizeof(number), " - %-8s", cs ); plp_snprintf( msg, sizeof(msg), "%-*s %-*s ", RANKW, number, OWNERW, d_identifier ); len = safestrlen(msg); plp_snprintf(msg+len, sizeof(msg)-len, " ->%s", d_dest ); if( d_copies > 1 ){ len = safestrlen( msg ); plp_snprintf( msg+len, sizeof(msg)-len, _(" "), d_copy_done, d_copies ); } if( d_error ){ len = safestrlen(msg); plp_snprintf( msg+len, sizeof(msg)-len, " ERROR: %s", d_error ); } Add_line_list(&outbuf,msg,0,0,0); } } DEBUGF(DLPQ3)("Get_queue_status: after dests" ); } else if( displayformat == REQ_VERBOSE ){ plp_snprintf( header, sizeof(header), _(" Job: %s"), identifier ); plp_snprintf( msg, sizeof(msg), _("%s status= %s"), header, number ); Add_line_list(&outbuf,msg,0,0,0); plp_snprintf( msg, sizeof(msg), _("%s size= %0.0f"), header, jobsize ); Add_line_list(&outbuf,msg,0,0,0); plp_snprintf( msg, sizeof(msg), _("%s time= %s"), header, job_time ); Add_line_list(&outbuf,msg,0,0,0); if( joberror ){ plp_snprintf( msg, sizeof(msg), _("%s error= %s"), header, joberror ); Add_line_list(&outbuf,msg,0,0,0); } if( cftransfername ){ plp_snprintf( msg, sizeof(msg), _("%s CONTROL="), header ); Add_line_list(&outbuf,msg,0,0,0); s = Find_str_value(&job.info,CF_OUT_IMAGE); Add_line_list(&outbuf,s,0,0,0); } plp_snprintf( msg, sizeof(msg), _("%s HOLDFILE="), header ); Add_line_list(&outbuf,msg,0,0,0); s = Make_job_ticket_image(&job); Add_line_list(&outbuf,s,0,0,0); if( s ) free(s); s = 0; } else if( displayformat == REQ_DSHORT ){ if( printable ){ ++matches; } else if( held ){ ++total_held; } else if( move ){ ++total_move; } } } DEBUGF(DLPQ3)("Get_queue_status: matches %d", matches ); /* this gives a short 1 line format with minimum info */ if( displayformat == REQ_DSHORT ){ len = safestrlen( header ); plp_snprintf( header+len, sizeof(header)-len, ngettext(" %d job", " %d jobs", matches), matches); if( total_held ){ len = safestrlen( header ); plp_snprintf( header+len, sizeof(header)-len, _(" (%d held)"), total_held ); } if( total_move ){ len = safestrlen( header ); plp_snprintf( header+len, sizeof(header)-len, _(" (%d move)"), total_move ); } } len = safestrlen( header ); DEBUGFC(DLPQ4)Dump_line_list("Get_queue_status: job status",&outbuf); DEBUGF(DLPQ3)( "Get_queue_status: RemoteHost_DYN '%s', RemotePrinter_DYN '%s', Lp '%s'", RemoteHost_DYN, RemotePrinter_DYN, Lp_device_DYN ); if( displayformat != REQ_DSHORT ){ s = 0; if( (s = Comment_tag_DYN) == 0 ){ if( (nx = PC_alias_line_list.count) > 1 ){ s = PC_alias_line_list.list[nx-1]; } } if( s ){ s = Fix_str(s); len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _(" Comment: %s"), s ); } else { plp_snprintf( header+len, sizeof(header)-len, " '%s'", s ); } if(s) free(s); s = 0; } } len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Printing: %s\n Aborted: %s\n Spooling: %s"), Pr_disabled(&Spool_control)?"yes":"no", Pr_aborted(&Spool_control)?"yes":"no", Sp_disabled(&Spool_control)?"yes":"no"); } else if( displayformat == REQ_DLONG || displayformat == REQ_DSHORT ){ flag = 0; if( Pr_disabled(&Spool_control) || Sp_disabled(&Spool_control) || Pr_aborted(&Spool_control) ){ plp_snprintf( header+len, sizeof(header)-len, " (" ); len = safestrlen( header ); if( Pr_disabled(&Spool_control) ){ plp_snprintf( header+len, sizeof(header)-len, "%s%s", flag?", ":"", "printing disabled" ); flag = 1; len = safestrlen( header ); } if( Pr_aborted(&Spool_control) ){ plp_snprintf( header+len, sizeof(header)-len, "%s%s", flag?", ":"", "printing aborted" ); flag = 1; len = safestrlen( header ); } if( Sp_disabled(&Spool_control) ){ plp_snprintf( header+len, sizeof(header)-len, "%s%s", flag?", ":"", "spooling disabled" ); len = safestrlen( header ); } plp_snprintf( header+len, sizeof(header)-len, ")" ); len = safestrlen( header ); } } /* * check to see if this is a server or subserver. If it is * for subserver, then you can forget starting it up unless started * by the server. */ if( (s = Server_names_DYN) || (s = Destinations_DYN) ){ Split( &info, s, File_sep, 0,0,0,0,0,0); len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ if ( Server_names_DYN ) { cs = "Subservers"; } else { cs = "Destinations"; } plp_snprintf( header+len, sizeof(header)-len, _("\n %s: "), cs ); } else { if ( Server_names_DYN ) { cs = "subservers"; } else { cs = "destinations"; } plp_snprintf( header+len, sizeof(header)-len, _(" (%s"), cs ); } for( ix = 0; ix < info.count; ++ix ){ len = safestrlen( header ); plp_snprintf( header+len, sizeof(header)-len, "%s%s", (ix > 0)?", ":" ", info.list[ix] ); } Free_line_list( &info ); if( displayformat != REQ_VERBOSE ){ safestrncat( header, ") " ); } } else if( (s = Frwarding(&Spool_control)) ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Redirected_to: %s"), s ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (redirect %s)"), s ); } } else if( RemoteHost_DYN && RemotePrinter_DYN ){ len = safestrlen( header ); s = Frwarding(&Spool_control); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, "\n Destination: %s@%s", RemotePrinter_DYN, RemoteHost_DYN ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (dest %s@%s)"), RemotePrinter_DYN, RemoteHost_DYN ); } } if( Server_queue_name_DYN ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Serving: %s"), Server_queue_name_DYN ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (serving %s)"), Server_queue_name_DYN ); } } if( (s = Clsses(&Spool_control)) ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Classes: %s"), s ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (classes %s)"), s ); } } if( (Hld_all(&Spool_control)) ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Hold_all: on") ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (holdall)")); } } if( Auto_hold_DYN ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Auto_hold: on") ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (autohold)")); } } if( (s = Find_str_value( &Spool_control,MSG )) ){ len = safestrlen( header ); if( displayformat == REQ_VERBOSE ){ plp_snprintf( header+len, sizeof(header)-len, _("\n Message: %s"), s ); } else { plp_snprintf( header+len, sizeof(header)-len, _(" (message: %s)"), s ); } } safestrncat( header, "\n" ); if( Write_fd_str( *sock, header ) < 0 ) cleanup(0); header[0] = 0; if( displayformat == REQ_DSHORT ) goto remote; /* now check to see if there is a server and unspooler process active */ path = Make_pathname( Spool_dir_DYN, Queue_lock_file_DYN ); server_pid = Read_pid_from_file( path ); DEBUGF(DLPQ3)("Get_queue_status: checking server pid %d", server_pid ); free(path); if( server_pid > 0 && kill( server_pid, 0 ) ){ DEBUGF(DLPQ3)("Get_queue_status: server %d not active", server_pid ); server_pid = 0; } path = Make_pathname( Spool_dir_DYN, Queue_unspooler_file_DYN ); unspooler_pid = Read_pid_from_file( path ); if(path) free(path); path=0; DEBUGF(DLPQ3)("Get_queue_status: checking unspooler pid %d", unspooler_pid ); if( unspooler_pid > 0 && kill( unspooler_pid, 0 ) ){ DEBUGF(DLPQ3)("Get_queue_status: unspooler %d not active", unspooler_pid ); unspooler_pid = 0; } if( printable == 0 ){ safestrncpy( msg, _(" Queue: no printable jobs in queue\n") ); } else { /* check to see if there are files and no spooler */ plp_snprintf( msg, sizeof(msg), ngettext(" Queue: %d printable job\n", " Queue: %d printable jobs\n", printable), printable); } if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); if( held ){ plp_snprintf( msg, sizeof(msg), _(" Holding: %d held jobs in queue\n"), held ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); } msg[0] = 0; if( count && server_pid <= 0 ){ safestrncpy(msg, _(" Server: no server active") ); } else if( server_pid > 0 ){ len = safestrlen(msg); plp_snprintf( msg+len, sizeof(msg)-len, _(" Server: pid %d active"), server_pid ); } if( unspooler_pid > 0 ){ if( msg[0] ){ safestrncat( msg, (displayformat == REQ_VERBOSE )?", ":"\n"); } len = safestrlen(msg); plp_snprintf( msg+len, sizeof(msg)-len, _(" Unspooler: pid %d active"), unspooler_pid ); } if( msg[0] ){ safestrncat( msg, "\n" ); } if( msg[0] ){ if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); } msg[0] = 0; if( displayformat == REQ_VERBOSE ){ plp_snprintf( msg, sizeof(msg), _("%s SPOOLCONTROL=\n"), header ); if( Write_fd_str( *sock, msg ) < 0 ) cleanup(0); msg[0] = 0; for( ix = 0; ix < Spool_control.count; ++ix ){ s = safestrdup3(" ",Spool_control.list[ix],"\n",__FILE__,__LINE__); if( Write_fd_str( *sock, s ) < 0 ) cleanup(0); free(s); } } /* * get the last status of the spooler */ Print_status_info( sock, Queue_status_file_DYN, _(" Status: "), status_lines, max_size ); if( Status_file_DYN ){ Print_status_info( sock, Status_file_DYN, _(" Filter_status: "), status_lines, max_size ); } s = Join_line_list(&outbuf,"\n"); if( s ){ if( Write_fd_str(*sock,s) < 0 ) cleanup(0); free(s); } Free_line_list(&outbuf); remote: if( tempfd > 0 ){ /* we send the generated status back to the user */ *sock = savedfd; DEBUGF(DLPQ3)("Get_queue_status: reporting created status" ); if( lseek( tempfd, 0, SEEK_SET ) == -1 ){ logerr_die(LOG_INFO, "Get_queue_status: lseek of '%s' failed", tempfile ); } while( (ix = ok_read( tempfd, buffer, sizeof(buffer)-1 )) > 0 ){ if( write( *sock, buffer, ix ) < 0 ){ break; } } close(tempfd); tempfd = -1; DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status- cache", &cache ); /* now we update the cached information */ DEBUGF(DLPQ3)("Get_queue_status: hash_key '%s', cache_index %d", hash_key, cache_index ); modified = 0; nx = -1; for( ix = 0; cache_index < 0 && ix < cache.count; ++ix ){ s = cache.list[ix]; DEBUGF(DLPQ3)("Get_queue_status: [%d] '%s'", ix, s ); Free_line_list(&cache_info); if( s && (t = strchr(s,'=')) ){ Split(&cache_info,t+1,Arg_sep,1,Hash_value_sep,1,1,0,0); if( (file = Find_str_value(&cache_info,FILENAMES)) ){ /* we need to get the age of the file */ if( stat( file,&statb ) ){ /* the file is not there */ cache_index = ix; } else if( modified == 0 || statb.st_mtime < modified ){ nx = ix; modified = statb.st_mtime; } } else { cache_index = ix; } } else { DEBUGF(DLPQ3)("Get_queue_status: end of list [%d]", ix ); /* end of the list */ cache_index = ix; } } DEBUGF(DLPQ3)("Get_queue_status: cache_index %d", cache_index ); if( cache_index < 0 ) cache_index = nx; DEBUGF(DLPQ3)("Get_queue_status: using cache_index %d", cache_index ); if( cache_index < 0 ){ fatal(LOG_INFO, "Get_queue_status: cache entry not found"); } plp_snprintf(buffer,sizeof(buffer), "%s.%d", Lpq_status_file_DYN,cache_index); Free_line_list(&cache_info); Set_str_value(&cache_info,FILENAMES,buffer); modified = 0; if( Queue_status_file_DYN && stat(Queue_status_file_DYN,&statb) == 0 ){ modified = statb.st_mtime; } Set_flag_value(&cache_info,QUEUE_STATUS_FILE,modified); modified = 0; if( Status_file_DYN && stat(Status_file_DYN,&statb) == 0 ){ modified = statb.st_mtime; } Set_flag_value(&cache_info,PRSTATUS,modified); s = Join_line_list(&cache_info,","); /* now set up the new values */ if( cache.list[cache_index] ) free( cache.list[cache_index]); cache.list[cache_index] = 0; cache.list[cache_index] = safestrdup3(hash_key,"=",s,__FILE__,__LINE__); if( s ) free(s); s = 0; DEBUGFC(DLPQ3)Dump_line_list("Get_queue_status- new cache", &cache ); if( rename( tempfile, buffer ) ){ err = errno; unlink( Lpq_status_file_DYN ); errno = err; logerr_die(LOG_INFO, "Get_queue_status: rename of '%s' to '%s' failed", tempfile, buffer ); } s = Join_line_list( &cache,"\n" ); if( lseek( lockfd, 0, SEEK_SET) == -1 ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Get_queue_status: lseek failed write file '%s'", Lpq_status_file_DYN); } if( ftruncate( lockfd, 0 ) ){ Errorcode = JABORT; logerr_die(LOG_INFO, "Get_queue_status: ftruncate failed file '%s'", Lpq_status_file_DYN); } if( Write_fd_str( lockfd, s ) < 0 ){ unlink( Lpq_status_file_DYN ); Errorcode = JABORT; logerr_die(LOG_INFO, "Get_queue_status: write failed file '%s'", Lpq_status_file_DYN); } if(s) free(s); s = 0; close(lockfd); #if 0 tempfd = Make_temp_fd( &tempfile ); if( Write_fd_str( tempfd, s ) < 0 ){ err = errno; unlink( Lpq_status_file_DYN ); logerr_die(LOG_INFO, "Get_queue_status: write to '%s' failed", tempfile ); errno = err; cleanup(0); } close(tempfd); tempfd = -1; if(s) free(s); s = 0; if( rename( tempfile, Lpq_status_file_DYN ) ){ err = errno; unlink( Lpq_status_file_DYN ); errno = err; logerr_die(LOG_INFO, "Get_queue_status: rename of '%s' to '%s' failed", tempfile, Lpq_status_file_DYN ); } #endif Free_line_list(&cache_info); Free_line_list(&cache); close( lockfd ); lockfd = -1; } if( Server_names_DYN ){ Free_line_list(&info); Split(&info, Server_names_DYN, File_sep, 0,0,0,0,0,0); for( ix = 0; ix < info.count; ++ix ){ DEBUGF(DLPQ3)("Get_queue_status: getting subserver status '%s'", info.list[ix] ); Set_DYN(&Printer_DYN,info.list[ix]); Get_local_or_remote_status( tokens, sock, displayformat, status_lines, done_list, max_size, hash_key ); DEBUGF(DLPQ3)("Get_queue_status: finished subserver status '%s'", info.list[ix] ); } } else if( Destinations_DYN ){ Free_line_list(&info); Split(&info, Destinations_DYN, File_sep, 0,0,0,0,0,0); for( ix = 0; ix < info.count; ++ix ){ DEBUGF(DLPQ3)("Get_queue_status: getting destination status '%s'", info.list[ix] ); Set_DYN(&Printer_DYN,info.list[ix]); Get_local_or_remote_status( tokens, sock, displayformat, status_lines, done_list, max_size, hash_key ); DEBUGF(DLPQ3)("Get_queue_status: finished destination status '%s'", info.list[ix] ); } } else if( RemoteHost_DYN ){ /* now we look at the remote host */ if( Find_fqdn( &LookupHost_IP, RemoteHost_DYN ) && ( !Same_host(&LookupHost_IP,&Host_IP ) || !Same_host(&LookupHost_IP,&Localhost_IP )) ){ DEBUGF(DLPQ1)("Get_queue_status: doing local"); if( safestrcmp(RemotePrinter_DYN, Printer_DYN) ){ Set_DYN(&Printer_DYN,RemotePrinter_DYN); Get_queue_status( tokens, sock, displayformat, status_lines, done_list, max_size, hash_key ); } else { plp_snprintf(msg,sizeof(msg), "Error: loop in printcap- %s@%s -> %s@%s\n", Printer_DYN, FQDNHost_FQDN, RemotePrinter_DYN, RemoteHost_DYN ); Write_fd_str(*sock, msg ); } } else { DEBUGF(DLPQ1)("Get_queue_status: doing remote %s@%s", RemotePrinter_DYN, RemoteHost_DYN); if( Remote_support_DYN ) uppercase( Remote_support_DYN ); if( safestrchr( Remote_support_DYN, 'Q' ) ){ fd = Send_request( 'Q', displayformat, tokens->list, Connect_timeout_DYN, Send_query_rw_timeout_DYN, *sock ); if( fd >= 0 ){ char *tempfile; /* shutdown( fd, 1 ); */ tempfd = Make_temp_fd( &tempfile ); while( (nx = Read_fd_len_timeout(Send_query_rw_timeout_DYN, fd,msg,sizeof(msg))) > 0 ){ if( Write_fd_len(tempfd,msg,nx) < 0 ) cleanup(0); } close(fd); fd = -1; Print_different_last_status_lines( sock, tempfd, status_lines, 0 ); close(tempfd); tempfd = -1; unlink( tempfile ); } } } } DEBUGF(DLPQ3)("Get_queue_status: finished '%s'", Printer_DYN ); goto done; error: plp_snprintf(header,sizeof(header), "Printer: %s@%s - ERROR: %s", Printer_DYN, Report_server_as_DYN?Report_server_as_DYN:ShortHost_FQDN, error ); DEBUGF(DLPQ1)("Get_queue_status: error msg '%s'", header ); if( Write_fd_str( *sock, header ) < 0 ) cleanup(0); done: if( savedfd > 0 ) *sock = savedfd; Free_line_list(&info); Free_line_list(&lineinfo); Free_line_list(&outbuf); Free_line_list(&cache); Free_line_list(&cache_info); return; } static void Print_status_info( int *sock, char *file, char *prefix, int status_lines, int max_size ) { char *image; static const char *atmsg = " at "; struct line_list l; int start, i; Init_line_list(&l); DEBUGF(DLPQ1)("Print_status_info: '%s', lines %d, size %d", file, status_lines, max_size ); if( status_lines > 0 ){ i = (status_lines * 100)/1024; if( i == 0 ) i = 1; image = Get_file_image(file, i); Split(&l,image,Line_ends,0,0,0,0,0,0); if( l.count < status_lines ){ if( image ) free( image ); image = 0; image = Get_file_image(file, 0); Split(&l,image,Line_ends,0,0,0,0,0,0); } } else { image = Get_file_image(file, max_size); Split(&l,image,Line_ends,0,0,0,0,0,0); } DEBUGF(DLPQ1)("Print_status_info: line count %d", l.count ); start = 0; if( status_lines ){ start = l.count - status_lines; if( start < 0 ) start = 0; } for( i = start; i < l.count; ++i ){ char *s, *t, *u; s = l.list[i]; if( (t = strstr( s, " ## " )) ){ *t = 0; } /* make the date format short */ if( !Full_time_DYN ){ for( u = s; (t = strstr(u,atmsg)); u = t+safestrlen(atmsg) ); if( u != s && (t = strrchr( u, '-' )) ){ memmove( u, t+1, safestrlen(t+1)+1 ); } } if( prefix && Write_fd_str(*sock,prefix) < 0 ) cleanup(0); if( Write_fd_str(*sock,s) < 0 ) cleanup(0); if( Write_fd_str(*sock,"\n") < 0 ) cleanup(0); } Free_line_list(&l); if( image) free(image); image = 0; } void Print_different_last_status_lines( int *sock, int fd, int status_lines, int max_size ) { char header[SMALLBUFFER]; struct line_list l; int start, last_printed, i, j, same; char *s, *t; Init_line_list(&l); DEBUGF(DLPQ1)("Print_different_last_status_lines: status lines %d", status_lines ); Get_fd_image_and_split(fd,max_size,0,&l,Line_ends,0,0,0,0,0,0); DEBUGFC(DLPQ1)Dump_line_list( "Print_different_last_status_lines", &l ); header[0] = 0; last_printed = start = -1; if( status_lines > 0 ) for( i = 0; i < l.count; ++i ){ s = l.list[i]; /* find up to the first colon */ if( (t = safestrchr(s,':')) ){ *t = 0; } same = !safestrcmp( header, s ); if( !same ){ safestrncpy(header,s); } if( t ) *t = ':'; if( !same ){ /* we print from i-1-(status_lines-1) to i-1 */ start = i-status_lines; if( start <= last_printed ) start = last_printed + 1; for( j = start; j < i; ++j ){ if( Write_fd_str(*sock,l.list[j]) < 0 ) cleanup(0); if( Write_fd_str(*sock,"\n") < 0 ) cleanup(0); } last_printed = i-1; DEBUGF(DLPQ1)("Print_different_last_status_lines: start %d, last_printed %d", start, last_printed ); } } if( status_lines > 0 ){ start = l.count - status_lines; } if( start <= last_printed ) start = last_printed + 1; DEBUGF(DLPQ1)("Print_different_last_status_lines: done, start %d", start ); for( i = start; i < l.count ; ++i ){ if( Write_fd_str(*sock,l.list[i]) < 0 ) cleanup(0); if( Write_fd_str(*sock,"\n") < 0 ) cleanup(0); } Free_line_list(&l); } void Get_local_or_remote_status( struct line_list *tokens, int *sock, int displayformat, int status_lines, struct line_list *done_list, int max_size, char *hash_key ) { char msg[SMALLBUFFER]; int fd, n, tempfd; /* we have to see if the host is on this machine */ DEBUGF(DLPQ1)("Get_local_or_remote_status: %s", Printer_DYN ); if( !safestrchr(Printer_DYN,'@') ){ DEBUGF(DLPQ1)("Get_local_or_remote_status: doing local"); Get_queue_status( tokens, sock, displayformat, status_lines, done_list, max_size, hash_key ); return; } Fix_Rm_Rp_info(0,0); /* now we look at the remote host */ if( Find_fqdn( &LookupHost_IP, RemoteHost_DYN ) && ( !Same_host(&LookupHost_IP,&Host_IP ) || !Same_host(&LookupHost_IP,&Localhost_IP )) ){ DEBUGF(DLPQ1)("Get_local_or_remote_status: doing local"); Get_queue_status( tokens, sock, displayformat, status_lines, done_list, max_size, hash_key ); return; } uppercase( Remote_support_DYN ); if( safestrchr( Remote_support_DYN, 'Q' ) ){ DEBUGF(DLPQ1)("Get_local_or_remote_status: doing remote %s@%s", RemotePrinter_DYN, RemoteHost_DYN); fd = Send_request( 'Q', displayformat, tokens->list, Connect_timeout_DYN, Send_query_rw_timeout_DYN, *sock ); if( fd >= 0 ){ /* shutdown( fd, 1 ); */ tempfd = Make_temp_fd( 0 ); while( (n = Read_fd_len_timeout(Send_query_rw_timeout_DYN, fd,msg,sizeof(msg))) > 0 ){ if( Write_fd_len(tempfd,msg,n) < 0 ) cleanup(0); } close(fd); fd = -1; Print_different_last_status_lines( sock, tempfd, status_lines, 0 ); close(tempfd); } } } lprng-3.8.B/src/common/merge.c0000644000131400013140000002376611531672132013140 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: merge.c,v 1.74 2004/09/24 20:19:58 papowell Exp $"; /*- * copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Peter McIlroy. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)merge.c 8.2 (Berkeley) 2/14/94"; #endif /* LIBC_SCCS and not lint */ /* * Hybrid exponential search/linear search merge sort with hybrid * natural/pairwise first pass. Requires about .3% more comparisons * for random data than LSMS with pairwise first pass alone. * It works for objects as small as two bytes. */ #define NATURAL #define THRESHOLD 16 /* Best choice for natural merge cut-off. */ /* #define NATURAL to get hybrid natural merge. * (The default is pairwise merging.) */ #include "lp.h" #include "merge.h" static void setup(unsigned char *list1, unsigned char *list2, size_t n, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg); static void insertionsort(unsigned char *a, size_t n, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg); #define ISIZE sizeof(int) #define PSIZE sizeof(unsigned char *) #define ICOPY_LIST(src, dst, last) \ do \ *(int*)dst = *(int*)src, src += ISIZE, dst += ISIZE; \ while(src < last) #define ICOPY_ELT(src, dst, i) \ do \ *(int*) dst = *(int*) src, src += ISIZE, dst += ISIZE; \ while (i -= ISIZE) #define CCOPY_LIST(src, dst, last) \ do \ *dst++ = *src++; \ while (src < last) #define CCOPY_ELT(src, dst, i) \ do \ *dst++ = *src++; \ while (i -= 1) /* * Find the next possible pointer head. (Trickery for forcing an array * to do double duty as a linked list when objects do not align with word * boundaries. */ /* Assumption: PSIZE is a power of 2. */ #define EVAL(p) (unsigned char **) \ ((unsigned char *)0 + \ (((unsigned char *)p + PSIZE - 1 - (unsigned char *) 0) & ~(PSIZE - 1))) /* * We pass an additional arguement to the comparison routines. * This lack of a third argument is a real defect in the qsort, etc. * code */ int Mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg) { int i, sense; int big, iflag; unsigned char *f1, *f2, *t, *b, *tp2, *q, *l1, *l2; unsigned char *list2, *list1, *p2, *p, *last, **p1; if( nmemb < 2 ){ return(0); } if (size < PSIZE / 2) { /* Pointers must fit into 2 * size. */ errno = EINVAL; return (-1); } /* * XXX * Stupid subtraction for the Cray. */ iflag = 0; if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE)) iflag = 1; list2 = malloc_or_die( (nmemb * size + PSIZE),__FILE__,__LINE__); list1 = base; setup(list1, list2, nmemb, size, cmp, arg); last = list2 + nmemb * size; i = big = 0; while (*EVAL(list2) != last) { l2 = list1; p1 = EVAL(list1); for (tp2 = p2 = list2; p2 != last; p1 = EVAL(l2)) { p2 = *EVAL(p2); f1 = l2; f2 = l1 = list1 + (p2 - list2); if (p2 != last) p2 = *EVAL(p2); l2 = list1 + (p2 - list2); while (f1 < l1 && f2 < l2) { if ((*cmp)(f1, f2, arg) <= 0) { q = f2; b = f1, t = l1; sense = -1; } else { q = f1; b = f2, t = l2; sense = 0; } if (!big) { /* here i = 0 */ /*LINEAR:*/ while ((b += size) < t && cmp(q, b, arg) >sense) if (++i == 6) { big = 1; goto EXPONENTIAL; } } else { EXPONENTIAL: for (i = size; ; i <<= 1) if ((p = (b + i)) >= t) { if ((p = t - size) > b && (*cmp)(q, p, arg) <= sense) t = p; else b = p; break; } else if ((*cmp)(q, p, arg) <= sense) { t = p; if (i == (int)size) big = 0; goto FASTCASE; } else b = p; /*SLOWCASE:*/ while (t > b+size) { i = (((t - b) / size) >> 1) * size; if ((*cmp)(q, p = b + i, arg) <= sense) t = p; else b = p; } goto COPY; FASTCASE: while (i > (int)size) if ((*cmp)(q, p = b + (i >>= 1), arg) <= sense) t = p; else b = p; COPY: b = t; } i = size; if (q == f1) { if (iflag) { ICOPY_LIST(f2, tp2, b); ICOPY_ELT(f1, tp2, i); } else { CCOPY_LIST(f2, tp2, b); CCOPY_ELT(f1, tp2, i); } } else { if (iflag) { ICOPY_LIST(f1, tp2, b); ICOPY_ELT(f2, tp2, i); } else { CCOPY_LIST(f1, tp2, b); CCOPY_ELT(f2, tp2, i); } } } if (f2 < l2) { if (iflag) ICOPY_LIST(f2, tp2, l2); else CCOPY_LIST(f2, tp2, l2); } else if (f1 < l1) { if (iflag) ICOPY_LIST(f1, tp2, l1); else CCOPY_LIST(f1, tp2, l1); } *p1 = l2; } tp2 = list1; /* swap list1, list2 */ list1 = list2; list2 = tp2; last = list2 + nmemb*size; } if (base == list2) { memmove(list2, list1, nmemb*size); list2 = list1; } free(list2); return (0); } #define swap(a, b) { \ s = b; \ i = size; \ do { \ tmp = *a; *a++ = *s; *s++ = tmp; \ } while (--i); \ a -= size; \ } #define reverse(bot, top) { \ s = top; \ do { \ i = size; \ do { \ tmp = *bot; *bot++ = *s; *s++ = tmp; \ } while (--i); \ s -= size2; \ } while(bot < s); \ } /* * Optional hybrid natural/pairwise first pass. Eats up list1 in runs of * increasing order, list2 in a corresponding linked list. Checks for runs * when THRESHOLD/2 pairs compare with same sense. (Only used when NATURAL * is defined. Otherwise simple pairwise merging is used.) */ static void setup(unsigned char *list1, unsigned char *list2, size_t n, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg) { int i, length, size2, tmp, sense; unsigned char *f1, *f2, *s, *l2, *last, *p2; size2 = size*2; if (n <= 5) { insertionsort(list1, n, size, cmp, arg); *EVAL(list2) = (unsigned char*) list2 + n*size; return; } /* * Avoid running pointers out of bounds; limit n to evens * for simplicity. */ i = 4 + (n & 1); insertionsort(list1 + (n - i) * size, i, size, cmp, arg); last = list1 + size * (n - i); *EVAL(list2 + (last - list1)) = list2 + n * size; #ifdef NATURAL p2 = list2; f1 = list1; sense = (cmp(f1, f1 + size, arg) > 0); for (; f1 < last; sense = !sense) { length = 2; /* Find pairs with same sense. */ for (f2 = f1 + size2; f2 < last; f2 += size2) { if ((cmp(f2, f2+ size, arg) > 0) != sense) break; length += 2; } if (length < THRESHOLD) { /* Pairwise merge */ do { p2 = *EVAL(p2) = f1 + size2 - list1 + list2; if (sense > 0) swap (f1, f1 + size); } while ((f1 += size2) < f2); } else { /* Natural merge */ l2 = f2; for (f2 = f1 + size2; f2 < l2; f2 += size2) { if ((cmp(f2-size, f2, arg) > 0) != sense) { p2 = *EVAL(p2) = f2 - list1 + list2; if (sense > 0) reverse(f1, f2-size); f1 = f2; } } if (sense > 0) reverse (f1, f2-size); f1 = f2; if (f2 < last || cmp(f2 - size, f2, arg) > 0) p2 = *EVAL(p2) = f2 - list1 + list2; else p2 = *EVAL(p2) = list2 + n*size; } } #else /* pairwise merge only. */ for (f1 = list1, p2 = list2; f1 < last; f1 += size2) { p2 = *EVAL(p2) = p2 + size2; if (cmp (f1, f1 + size, arg) > 0) swap(f1, f1 + size); } #endif /* NATURAL */ } /* * This is to avoid out-of-bounds addresses in sorting the * last 4 elements. */ static void insertionsort(unsigned char *a, size_t n, size_t size, int (*cmp)(const void *, const void *, const void *), const void * arg) { unsigned char *ai, *s, *t, *u, tmp; int i; for (ai = a+size; --n >= 1; ai += size) for (t = ai; t > a; t -= size) { u = t - size; if (cmp(u, t, arg) <= 0) break; swap(u, t); } } lprng-3.8.B/src/common/gethostinfo.c0000644000131400013140000004752411531672131014367 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ /******************************************************************** * char *get_fqdn (char *shorthost) * get the fully-qualified domain name for a host. * * NOTE: get_fqdn returns a pointer to static data, so copy the result!! * i.e.- strcpy (fqhostname, get_fqdn (hostname)); * ********************************************************************/ #include "lp.h" #include "gethostinfo.h" #include "linksupport.h" #include "getqueue.h" #include "globmatch.h" #if defined(HAVE_ARPA_NAMESER_H) # include #endif #if defined(HAVE_RESOLV_H) # include #endif /**** ENDINCLUDE ****/ #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN 256 #endif /* prototypes of forward-declarations */ static char *Fixup_fqdn( const char *shorthost, struct host_information *info, struct hostent *host_ent ); static void Clear_host_information( struct host_information *info ) { Free_line_list( &info->host_names ); Free_line_list( &info->h_addr_list ); if( info->shorthost ) free(info->shorthost ); info->shorthost = 0; if( info->fqdn ) free(info->fqdn ); info->fqdn = 0; } void Clear_all_host_information(void) { Clear_host_information( &Localhost_IP ); /* IP from localhost lookup */ Clear_host_information( &Host_IP ); /* IP from localhost lookup */ Clear_host_information( &RemoteHost_IP ); /* IP from localhost lookup */ Clear_host_information( &LookupHost_IP ); /* IP from localhost lookup */ Clear_host_information( &PermHost_IP ); /* IP from localhost lookup */ } /*************************************************************************** * void Check_for_dns_hack( struct hostent *h_ent ) * Check to see that you do not have some whacko type returned by DNS ***************************************************************************/ static void Check_for_dns_hack( struct hostent *h_ent ) { int count = 1; switch( h_ent->h_addrtype ){ case AF_INET: count = (h_ent->h_length != sizeof(struct in_addr )); break; #if defined(IPV6) case AF_INET6: count = (h_ent->h_length != sizeof(struct in6_addr)); break; #endif } if( count ){ fatal(LOG_ALERT, "Check_for_dns_hack: HACKER ALERT! DNS address length wrong, prot %d len %d", h_ent->h_addrtype, h_ent->h_length ); } } /******************************************************************** * char *Find_fqdn ( * struct host_information *info - we put information here * char *shorthost - hostname * * Finds IP address and fully qualified domain name for a host * * ASSUMES: shorthost name is shorter than LINEBUFFER * RETURNS: FQDN if found, 0 if not found ********************************************************************/ char *Find_fqdn( struct host_information *info, const char *shorthost ) { struct hostent *host_ent = 0; DEBUG3( "Find_fqdn: host '%s'", shorthost ); Clear_host_information( info ); if( shorthost == 0 || *shorthost == 0 ){ logmsg( LOG_ALERT, "Find_fqdn: called with '%s', HACKER ALERT", shorthost ); return(0); } if( safestrlen(shorthost) > 64 ){ fatal(LOG_ALERT, "Find_fqdn: hostname too long, HACKER ALERT '%s'", shorthost ); } #if defined(HAVE_GETHOSTBYNAME2) if( host_ent == 0 ){ host_ent = gethostbyname2( shorthost, AF_Protocol() ); DEBUG3( "Find_fqdn: gethostbyname2 returned 0x%lx", Cast_ptr_to_long(host_ent)); } #endif if( host_ent == 0 ){ host_ent = gethostbyname( shorthost ); DEBUG3( "Find_fqdn: gethostbyname returned 0x%lx", Cast_ptr_to_long(host_ent)); } if( host_ent == 0 ){ DEBUG3( "Find_fqdn: no entry for host '%s'", shorthost ); return( 0 ); } return( Fixup_fqdn( shorthost, info, host_ent) ); } static char *Fixup_fqdn( const char *shorthost, struct host_information *info, struct hostent *host_ent ) { char **list, *s, *fqdn = 0; /* sigh... */ Check_for_dns_hack(host_ent); /* problem: some gethostbyname() implementations do not return FQDN * apparently the gethostbyaddr does... This is really quite silly, * but here is a work around * LINUX BRAIN DAMAGE - as of Version 4.0 RedHat, Jan 2, 1997 * it has been observed that the LINUX gethostbyname() clobbers * buffers returned by gethostbyaddr() BEFORE they are * used and this is not documented. This has the side effect that using * buffers returned by gethostbyname to gethostbyaddr() calls will * get erroneous results, and in addition will also modify the original * values in the structures pointed to by gethostbyaddr. * * After the call to gethostbyaddr, you will need to REPEAT the call to * gethostbyname()... * * This implementation of gethostbyname()/gethostbyaddr() violates an * important principle of library design, which is functions should NOT * interact, or if they do, they should be CLEARLY documented. * * To say that I am not impressed with this is a severe understatement. * Patrick Powell, Jan 29, 1997 */ fqdn = 0; if( safestrchr( host_ent->h_name, '.' ) ){ fqdn = (char *)host_ent->h_name; } else if( (list = host_ent->h_aliases) ){ for( ; *list && !safestrchr(*list,'.'); ++list ); fqdn = *list; } if( fqdn == 0 ){ char buffer[64]; struct sockaddr temp_sockaddr; /* this will fit as sockaddr contains subfields */ memcpy( &temp_sockaddr, *host_ent->h_addr_list, host_ent->h_length ); DEBUG3("Fixup_fqdn: using gethostbyaddr for host '%s', addr '%s'", host_ent->h_name, inet_ntop( host_ent->h_addrtype, *host_ent->h_addr_list, buffer, sizeof(buffer)) ); host_ent = gethostbyaddr( (void *)&temp_sockaddr, host_ent->h_length, host_ent->h_addrtype ); if( host_ent ){ /* sigh... */ Check_for_dns_hack(host_ent); DEBUG3("Fixup_fqdn: gethostbyaddr found host '%s', addr '%s'", host_ent->h_name, inet_ntop( host_ent->h_addrtype, *host_ent->h_addr_list, buffer, sizeof(buffer)) ); } else { /* this failed */ /* we have to do the lookup AGAIN */ #if defined(HAVE_GETHOSTBYNAME2) host_ent = gethostbyname2( shorthost, AF_Protocol() ); #else host_ent = gethostbyname( shorthost ); #endif if( host_ent == 0 ){ fatal(LOG_ERR, "Fixup_fqdn: 2nd search failed for host '%s'", shorthost ); } /* sigh... */ Check_for_dns_hack(host_ent); } } if( fqdn == 0 ){ if( safestrchr( host_ent->h_name, '.' ) ){ fqdn = (char *)host_ent->h_name; } else if( (list = host_ent->h_aliases) ){ for( ; *list && !safestrchr(*list,'.'); ++list ); fqdn = *list; } if( fqdn == 0 ) fqdn = (char *)host_ent->h_name; } info->h_addrtype = host_ent->h_addrtype; info->h_length = host_ent->h_length; /* put the names in the database */ fqdn = info->fqdn = safestrdup(fqdn,__FILE__,__LINE__); info->shorthost = safestrdup(fqdn,__FILE__,__LINE__); if( (s = safestrchr(info->shorthost,'.')) ) *s = 0; Add_line_list(&info->host_names,(char *)host_ent->h_name,0,0,0 ); for( list = host_ent->h_aliases; list && (s = *list); ++list ){ Add_line_list(&info->host_names,s,0,0,0 ); } for( list = host_ent->h_addr_list; list && *list; ++list ){ s = malloc_or_die(info->h_length,__FILE__,__LINE__); memcpy(s, *list, info->h_length ); Check_max( &info->h_addr_list, 2 ); info->h_addr_list.list[ info->h_addr_list.count++ ] = s; info->h_addr_list.list[ info->h_addr_list.count ] = 0; } if(DEBUGL3) Dump_host_information( "Fixup_fqdn", info ); DEBUG2("Fixup_fqdn '%s': returning '%s'", shorthost, fqdn ); return(fqdn); } /*************************************************************************** * char *Get_local_host() * Get the fully-qualified hostname of the local host. * Tricky this; needs to be run after the config file has been read; * also, it depends a lot on the local DNS/NIS/hosts-file/etc. setup. * * Patrick Powell Fri Apr 7 07:47:23 PDT 1995 * 1. we use the gethostname() call if it is available * If we have the sysinfo call, we use it instead. * 2. we use the uname() call if it is available * 3. we get the $HOST environment variable ***************************************************************************/ #if defined(HAVE_SYS_SYSTEMINFO_H) # include #endif #if !defined(HAVE_GETHOSTNAME_DEF) extern int gethostname (char *nbuf, long nsiz); #endif #if !defined(HAVE_GETHOSTNAME) int gethostname( char *nbuf, long nsiz ) { # if defined(HAVE_SYSINFO) int i; i = sysinfo(SI_HOSTNAME,nbuf, nsiz ); DEBUG4("gethostname: using sysinfo '%s'", nbuf ); return( i ); # else # ifdef HAVE_UNAME # if defined(HAVE_SYS_UTSNAME_H) # include # endif # if defined(HAVE_UTSNAME_H) # include # endif # struct utsname unamestuff; /* structure to catch data from uname */ if (uname (&unamestuff) < 0) { return -1; } (void) mystrncpy (nbuf, unamestuff.nodename, nsiz); return( 0 ); # else char *name; name = getenv( "HOST" ); if( name == 0 ){ return( -1 ); } (void) mystrncpy (nbuf, name, nsiz); return( 0 ); # endif /* HAVE_UNAME */ # endif /* HAVE_SYSINFO */ } # endif /* HAVE_GETHOSTNAME */ /**************************************************************************** * void Get_local_host() * 1. We try the usual method of getting the host name. * This may fail on a PC based system where the host name is usually * not available. * 2. If we have no host name, then we try to use the IP address * This will almost always work on a system with a single interface. ****************************************************************************/ void Get_local_host( void ) { char host[LINEBUFFER]; char *fqdn; /* * get the Host computer Name */ host[0] = 0; if( gethostname (host, sizeof(host)) < 0 || host[0] == 0 ) { fatal(LOG_ERR, "Get_local_fqdn: no host name" ); } fqdn = Find_fqdn( &Host_IP, host ); DEBUG3("Get_local_host: fqdn=%s", fqdn); if( fqdn == 0 ){ fatal(LOG_ERR, "Get_local_host: hostname '%s' bad", host ); } Set_DYN( &FQDNHost_FQDN, Host_IP.fqdn ); Set_DYN( &ShortHost_FQDN, Host_IP.shorthost ); DEBUG1("Get_local_host: ShortHost_FQDN=%s, FQDNHost_FQDN=%s", ShortHost_FQDN, FQDNHost_FQDN); if( Find_fqdn( &Localhost_IP, LOCALHOST) == 0 ){ fatal(LOG_ERR, "Get_local_host: 'localhost' IP address not available!"); } } /*************************************************************************** * void Get_remote_hostbyaddr( struct sockaddr *sin ); * 1. look up the address using gethostbyaddr() * 2. if not found, we have problems ***************************************************************************/ static char *Get_hostinfo_byaddr( struct host_information *info, struct sockaddr *sinaddr, int addr_only ) { struct hostent *host_ent = 0; void *addr = 0; int len = 0; char *fqdn = 0; char *s; char buffer[64]; const char *const_s; DEBUG3("Get_remote_hostbyaddr: %s", inet_ntop_sockaddr( sinaddr, buffer, sizeof(buffer) ) ); Clear_host_information( info ); if( sinaddr->sa_family == AF_INET ){ addr = &((struct sockaddr_in *)sinaddr)->sin_addr; len = sizeof( ((struct sockaddr_in *)sinaddr)->sin_addr ); #if defined(IPV6) } else if( sinaddr->sa_family == AF_INET6 ){ addr = &((struct sockaddr_in6 *)sinaddr)->sin6_addr; len = sizeof( ((struct sockaddr_in6 *)sinaddr)->sin6_addr ); #endif } else { fatal(LOG_ERR, "Get_remote_hostbyaddr: bad family '%d'", sinaddr->sa_family); } if( !addr_only ){ host_ent = gethostbyaddr( addr, len, sinaddr->sa_family ); } if( host_ent ){ fqdn = Fixup_fqdn( host_ent->h_name, info, host_ent ); } else { /* We will need to create a dummy record. - no host */ info->h_addrtype = sinaddr->sa_family; info->h_length = len; s = malloc_or_die( len,__FILE__,__LINE__ ); memcpy( s, addr, len ); Check_max( &info->h_addr_list, 2); info->h_addr_list.list[info->h_addr_list.count++] = s; info->h_addr_list.list[info->h_addr_list.count] = 0; const_s = inet_ntop_sockaddr( sinaddr, buffer, sizeof(buffer) ); fqdn = info->fqdn = safestrdup(const_s,__FILE__,__LINE__); info->shorthost = safestrdup(fqdn,__FILE__,__LINE__); Add_line_list( &info->host_names,info->fqdn,0,0,0); } return( fqdn ); } char *Get_remote_hostbyaddr( struct host_information *info, struct sockaddr *sinaddr, int force_ip_addr_use ) { char *fqdn; fqdn = Get_hostinfo_byaddr( info, sinaddr, force_ip_addr_use ); DEBUG3("Get_remote_hostbyaddr: %s", fqdn ); Set_DYN( &FQDNRemote_FQDN, info->fqdn ); Set_DYN( &ShortRemote_FQDN, info->shorthost ); if(DEBUGL4) Dump_host_information( "Get_remote_hostbyaddr", info ); return( fqdn ); } /*************************************************************************** * int Same_host( struct host_information *h1, *h2 ) * returns 1 on failure, 0 on success * - compares the host addresses for an identical one ***************************************************************************/ int Same_host( struct host_information *host, struct host_information *remote ) { int i, j; char **hl1, **hl2; unsigned char *h1, *h2 ; int c1, c2, l1, l2; int result = 1; if( host && remote ){ hl1 = host->h_addr_list.list; c1 = host->h_addr_list.count; l1 = host->h_length; hl2 = remote->h_addr_list.list; c2 = remote->h_addr_list.count; l2 = remote->h_length; if( l1 == l2 ){ for( i = 0; result && i < c1; ++i ){ h1 = (unsigned char *)(hl1[i]); for( j = 0; result && j < c2; ++j ){ h2 = (unsigned char *)(hl2[j]); result = memcmp( h1, h2, l1 ); if(DEBUGL4){ char ls[64], rs[64]; int n; ls[0] = 0; rs[0] = 0; for( n = 0; n < l1; ++n ){ plp_snprintf( ls + safestrlen(ls), 3, "%02x", h1[n] ); } for( n = 0; n < l1; ++n ){ plp_snprintf( rs + safestrlen(rs), 3, "%02x", h2[n] ); } LOGDEBUG("Same_host: comparing %s to %s, result %d", ls, rs, result ); } } } } } return( result != 0 ); } /*************************************************************************** * Dump_host_information( char *title, struct host_information *info ) * Dump file information ***************************************************************************/ void Dump_host_information( const char *title, struct host_information *info ) { int i, j; char **list; char *s; if( title ) LOGDEBUG( "*** %s (0x%lx) ***", title, Cast_ptr_to_long(info) ); if( info ){ LOGDEBUG( " info name count %d", info->host_names.count ); list = info->host_names.list; for( i = 0; i < info->host_names.count; ++i ){ LOGDEBUG( " [%d] '%s'", i, list[i] ); } LOGDEBUG( " address type %d, length %d count %d", info->h_addrtype, info->h_length, info->h_addr_list.count ); for( i = 0; i < info->h_addr_list.count; ++i ){ char msg[64]; int len; plp_snprintf( msg, sizeof(msg), " [%d] 0x", i ); s = info->h_addr_list.list[i]; for( j = 0; j < info->h_length; ++j ){ len = safestrlen( msg ); plp_snprintf( msg+len, sizeof(msg)-len, "%02x",((unsigned char *)s)[j] ); } LOGDEBUG( "%s", msg ); } } } /*************************************************************************** * void form_addr_and_mask( char *v, *addr, *mask, int addrlen, int family) * form address and mask from string * with the format: IPADDR/MASK, mask is x.x.x.x or n (length) ***************************************************************************/ static int form_addr_and_mask(char *v, char *addr,char *mask, int addrlen, int family ) { char *s, *t; unsigned char *p; int i, m, bytecount, bitcount; char buffer[SMALLBUFFER]; if( v == 0 ) return 0; DEBUG5("form_addr_and_mask: '%s'", v ); if( 4*addrlen+1 >= (int)(sizeof(buffer)) ){ fatal(LOG_ERR, "form_addr_and_mask: addrlen too large - hacker attack?"); } memset( addr, 0, addrlen ); memset( mask, ~0, addrlen ); /* be paranoid, only allow / in ipv4 and ipv6 addresses */ if( family == AF_INET #if defined(IPV6) || family == AF_INET6 #endif ) s = safestrchr( v, '/' ); else s = NULL; if( s ) *s = 0; if( inet_pton(family, v, addr ) <= 0 ) { DEBUG1("form_addr_and_mask: failed to parse '%s'", v ); if( s ) *s++ = '/'; return 0; } if( s ){ *s++ = '/'; t = 0; m = strtol( s, &t, 0 ); if( t == 0 || *t ){ /* Not a number, so must be a mask: */ if( inet_pton(family, s, mask ) <= 0 ) { DEBUG1("form_addr_and_mask: failed to parse mask '%s' of '%s'", s, v ); return 0; } } else if( m >= 0 ){ /* set as many bits as specified by number */ bytecount = m/8; bitcount = m & 0x7; DEBUG6("form_addr_and_mask: m '%s' %d, bytecount %d, bitcount %d", s, m, bytecount, bitcount ); if( bytecount >= addrlen){ bytecount = addrlen; bitcount = 0; } p = (unsigned char*)mask; for( i = 0; i < bytecount; ++i ){ *p++ = 0xFF; } if( bitcount && i < addrlen ){ *p++ = (~((1<<(8-bitcount))-1))&0xFF; ++i; } for( ; i < addrlen; ++i ){ *p++ = 0x00; } } else return 0; } if(DEBUGL5){ LOGDEBUG("form_addr_and_mask: addr '%s'", inet_ntop( family, addr, buffer, sizeof(buffer) ) ); LOGDEBUG("form_addr_and_mask: mask '%s'", inet_ntop( family, mask, buffer, sizeof(buffer) ) ); } return 1; } /* * cmp_ip_addr() * do a masked string compare */ static int cmp_ip_addr( const char *h, const char *a, const char *m, int len ) { int match = 0, i; if( len == 0 ) match = 1; for( i = 0; match == 0 && i < len; ++i ){ DEBUG5("cmp_ip_addr: [%d] mask 0x%02x addr 0x%02x host 0x%02x", i, ((unsigned char *)m)[i], ((unsigned char *)a)[i], ((unsigned char *)h)[i] ); match = (m[i] & ( a[i] ^ h[i] )) & 0xFF; } DEBUG5("cmp_ip_addr: result %d", match ); return( match ); } /* * int Match_ipaddr_value( char *str, struct host_information *host ) * str has format addr,addr,addr * addr is @netgroup * *globmatch* to the host FQDN or alias names * nn.nn.nn/mak * Match the indicated address against the host * * returns: 0 if match * 1 if no match */ int Match_ipaddr_value( struct line_list *list, struct host_information *host ) { int result = 1, i, j, invert = 0; char *str, *addr, *mask; DEBUGF(DDB1)("Match_ipaddr_value: host %s", host?host->fqdn:0 ); DEBUGFC(DDB1)Dump_host_information("Match_ipaddr_value - host ", host ); if( host == 0 || host->fqdn == 0 ) return(result); addr = malloc_or_die(host->h_length,__FILE__,__LINE__); mask = malloc_or_die(host->h_length,__FILE__,__LINE__); for( i = 0; result && i < list->count; ++i ){ if( !(str = list->list[i]) ) continue; if( cval(str) == '!' ){ invert = 1; ++str; } if( cval(str) == '@' ) { /* look up host in netgroup */ #ifdef HAVE_INNETGR result = !innetgr( str+1, host->shorthost, NULL, NULL ); if( result ) result = !innetgr( str+1, host->fqdn, NULL, NULL ); #else /* HAVE_INNETGR */ DEBUGF(DDB3)("match: no innetgr() call, netgroups not permitted"); #endif /* HAVE_INNETGR */ } else if( str[0] == '<' && str[1] == '/' ){ struct line_list users; Init_line_list(&users); Get_file_image_and_split(str+1,0,0,&users,Whitespace, 0,0,0,0,0,0); DEBUGFC(DDB3)Dump_line_list("Match_ipaddr_value- file contents'", &users ); result = Match_ipaddr_value( &users,host); Free_line_list(&users); } else { lowercase(str); for( j = 0; result && j < host->host_names.count; ++j ){ lowercase(host->host_names.list[j]); result = Globmatch( str, host->host_names.list[j] ); } if( result ){ DEBUGF(DDB2)("Match_ipaddr_value: mask '%s'", str ); if( form_addr_and_mask(str,addr,mask,host->h_length, host->h_addrtype ) ){ for( j = 0; result && j < host->h_addr_list.count; ++j ){ const char *v; v = host->h_addr_list.list[j]; result = cmp_ip_addr( v, addr, mask, host->h_length ); } } } DEBUGF(DDB2)("Match_ipaddr_value: checked '%s', result %d", str, result); } if( invert ) result = !result; } DEBUGF(DDB2)("Match_ipaddr_value: result %d", result ); if(addr) free(addr); addr = 0; if(mask) free(mask); mask = 0; if( result ) return 1; else return 0; } lprng-3.8.B/src/psbanner.in0000644000131400013140000002640311531672134012536 00000000000000#!@SHELL@ # Patrick Powell # Sat Aug 19 20:40:33 PDT 1995 # # psbanner [-FLAGvalue]* [accountingfile] # # Important flags: Postscript Variable # -j number - job number /Seq # -J banner - banner /Job # -h host - host /Host # -C class - job class /Class # -n user - user /User # -t date - date /Date # -L name - name /Name # # Example: # # banner -Pt1 -w80 -l66 -x0 -y0 -Ff # -kcfA684taco.astart.com -Lpapowell -J../VERSION -CA # -npapowell -htaco.astart.com -Htaco.astart.com # -d/tmp/LPD/t1/dfA684 taco.astart.com accnt # # Output needed: # # %!PS-Adobe-2.0 # /Seq (number) def # /Job (banner) def (with '()\' escaped ) # /Host (HOST) def # /Class (CLASS) def # /User (USER) def # /Date (DATE) def # /Name (NAME) def # < followed by the contents of the banner file > # These variables are used by the banner printing script to # produce output. ## # ----------- start version 1 ------------ # PATH=/bin:/usr/bin Args="" vAr="" vAlue="" iI="" Args="$@" while expr "$1" : '-.*' >/dev/null ; do vAr=`expr "$1" : '-\(.\).*'`; vAlue=`expr "$1" : '-.\(.*\)'`; case "$vAr" in - ) break;; c ) c=1;; [a-zA-Z] ) if test "X$vAlue" = "X" ; then shift; vAlue="$1"; fi; eval $vAr='$vAlue'; #setvar $vAr "$vAlue" ;; esac; shift; done number=0; if [ -n "$j" ] ; then number="$j"; fi banner=NONE; if [ -n "$J" ] ; then banner="$J"; fi host=UNKNOWN; if [ -n "$h" ] ; then host="$h"; fi class=UNKNOWN; if [ -n "$C" ] ; then class="$C"; fi user=UNKNOWN; if [ -n "$n" ] ; then user="$n"; fi date=`date`; name=UNKNOWN; if [ -n "$L" ] ; then name="$L"; fi # put out the values cat < 612 x 792 # a4 = 8.5 x 11.75 => 612 x 846 cat <<'EOF' ; /entries [(User:) (Name:) (Host:) (Date:) (Job:) (Class:)] def /low-point-size 10 def %% /high-point-size 120 def /high-point-size 80 def /line-spacing low-point-size 1.2 mul def /left-margin 22 def % a4 /first-baseline 840 def % 8.5x11 /first-baseline 786 def /first-baseline 786 def /last-baseline 30 def /user-baseline 150 def /user-margin left-margin low-point-size 4.2 mul add def /banner-baseline 630 def /banner-line-spacing high-point-size 1.1 mul def /Courier findfont low-point-size scalefont setfont 0 1 5 { dup line-spacing mul exch 2 gt { first-baseline exch sub } { last-baseline add } ifelse left-margin exch moveto (****************************************) show (**************************************** Id: ) show Seq show } for 0 1 5 { dup line-spacing mul user-baseline exch sub left-margin exch moveto entries exch get show } for /i 0 def [User Name Host Date Job Class] { user-margin user-baseline i line-spacing mul sub moveto i 0 eq { show (@) show Host } if show /i i 1 add def } forall /i 0 def %%%%%% FANCY HEADER %%%%%%%%%%%%%%%%% %% [Seq User Host Job] { gsave left-margin banner-baseline banner-line-spacing i mul sub translate 0 0 moveto i 0 eq i 3 eq or { i 0 eq { /Helvetica } { /Courier /high-point-size 76 def } ifelse } { /Palatino-Italic } ifelse findfont high-point-size scalefont setfont { /charcode exch def /thechar (-) dup 0 charcode put def thechar true charpath stroke thechar stringwidth pop 0 translate 0 0 moveto } forall /i i 1 add def grestore } forall %% %%%% Neat little Printer ICON %%%% if you don't mind waiting, remove the comments %%%% %% gsave %% /$F2psDict 200 dict def %% $F2psDict begin %% $F2psDict /mtrx matrix put %% /l {lineto} bind def %% /m {moveto} bind def %% /s {stroke} bind def %% /n {newpath} bind def %% /gs {gsave} bind def %% /gr {grestore} bind def %% /clp {closepath} bind def %% /graycol {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul %% 4 -2 roll mul setrgbcolor} bind def %% /col-1 {} def %% /col0 {0 0 0 setrgbcolor} bind def %% /col1 {0 0 1 setrgbcolor} bind def %% /col2 {0 1 0 setrgbcolor} bind def %% /col3 {0 1 1 setrgbcolor} bind def %% /col4 {1 0 0 setrgbcolor} bind def %% /col5 {1 0 1 setrgbcolor} bind def %% /col6 {1 1 0 setrgbcolor} bind def %% /col7 {1 1 1 setrgbcolor} bind def %% /col8 {.68 .85 .9 setrgbcolor} bind def %% /col9 {0 .39 0 setrgbcolor} bind def %% /col10 {.65 .17 .17 setrgbcolor} bind def %% /col11 {1 .51 0 setrgbcolor} bind def %% /col12 {.63 .13 .94 setrgbcolor} bind def %% /col13 {1 .75 .8 setrgbcolor} bind def %% /col14 {.7 .13 .13 setrgbcolor} bind def %% /col15 {1 .84 0 setrgbcolor} bind def %% end %% /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def %% /$F2psEnd {$F2psEnteredState restore end} def %% %%EndProlog %% %% $F2psBegin %% 0 setlinecap 0 setlinejoin %% 412.0 205.0 translate 0.900 -0.900 scale %% 1.000 setlinewidth %% % Polyline %% n 64 107 m 64 101 l 124 101 l 124 107 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 64 106 m 64 110 l gs col0 s gr %% % Polyline %% n 124 106 m 124 110 l gs col0 s gr %% % Polyline %% n 128 128 m 128 119 l 59 119 l 59 128 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 59 119 m 59 104 l 44 104 l 44 119 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 143 119 m 143 104 l 128 104 l 128 119 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 146 92 m 146 116 l 143 116 l 143 92 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 44 92 m 44 116 l 41 116 l 41 92 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 50 95 m 50 92 l 44 92 l 44 95 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% % Polyline %% n 137 95 m 137 92 l 143 92 l 143 95 l clp gs 0.00 setgray fill gr %% gs col-1 s gr %% 1.000 setlinewidth %% % Polyline %% n 146 77 m 146 89 l 41 89 l 41 77 l clp gs col-1 s gr %% % Polyline %% n 43 90 m 43 78 l gs col-1 s gr %% % Polyline %% n 144 89 m 144 77 l gs col-1 s gr %% % Polyline %% n 41 77 m 41 71 l gs col-1 s gr %% % Polyline %% n 146 77 m 146 71 l gs col-1 s gr %% % Polyline %% n 50 65 m 59 65 l gs col-1 s gr %% 0.500 setlinewidth %% % Polyline %% n 59 70 m 128 70 l gs col-1 s gr %% % Polyline %% n 59 41 m 59 71 l gs col-1 s gr %% % Polyline %% n 59 71 m 128 71 l gs col-1 s gr %% % Polyline %% n 59 41 m 122 41 l gs col-1 s gr %% % Polyline %% n 128 48 m 128 71 l gs col-1 s gr %% % Polyline %% n 122 41 m 128 48 l gs col-1 s gr %% % Polyline %% n 116 41 m 116 53 l 128 53 l gs col-1 s gr %% 1.000 setlinewidth %% % Polyline %% n 128 65 m 131 65 l gs col-1 s gr %% % Polyline %% n 129 65 m 140 65 l 146 72 l gs col-1 s gr %% 0.500 setlinewidth %% % Polyline %% n 128 66 m 131 66 l gs col-1 s gr %% % Polyline %% n 128 67 m 131 67 l gs col-1 s gr %% % Polyline %% n 133 66 m 140 66 l gs col-1 s gr %% % Polyline %% n 133 67 m 141 67 l gs col-1 s gr %% % Polyline %% n 131 68 m 133 68 l gs col-1 s gr %% % Polyline %% n 131 69 m 133 69 l gs col-1 s gr %% 1.000 setlinewidth %% % Polyline %% n 51 65 m 41 72 l gs 0.85 setgray fill gr %% gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 143 88 m 143 78 l 44 78 l 44 88 l clp gs 0.60 setgray fill gr %% gs col0 s gr %% % Polyline %% n 132 77 m 41 77 l 41 72 l 51 65 l 59 65 l 59 71 l %% 128 71 l 128 67 l 131 67 l gs 0.75 setgray fill gr %% gs col0 s gr %% % Polyline %% n 132 77 m 145 77 l 146 77 l 146 71 l 146 72 l 141 66 l %% 133 66 l 133 68 l 133 68 l 133 69 l 131 69 l gs 0.75 setgray fill gr %% gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 141 89 m 141 92 l gs col0 s gr %% % Polyline %% n 46 89 m 46 93 l gs col0 s gr %% % Polyline %% n 138 80 m 140 80 l gs col0 s gr %% % Polyline %% n 138 85 m 140 85 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 128 104 m 143 104 l 143 95 l 137 95 l 137 92 l 141 92 l %% 141 92 l 140 92 l 141 92 l 141 89 l 46 89 l %% 46 92 l 50 92 l 50 95 l 44 95 l 44 104 l %% 59 104 l gs 0.50 setgray fill gr %% gs col0 s gr %% % Polyline %% n 59 104 m 59 119 l 128 119 l 128 104 l gs 0.35 setgray fill gr %% gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 65 102 m 69 102 l gs col0 s gr %% % Polyline %% n 124 102 m 120 102 l gs col0 s gr %% % Polyline %% n 121 102 m 119 102 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 64 104 m 64 108 l gs col0 s gr %% % Polyline %% n 124 104 m 124 108 l gs col0 s gr %% % Polyline %% n 125 108 m 131 108 l gs col0 s gr %% % Polyline %% n 57 108 m 63 108 l gs col0 s gr %% % Polyline %% n 120 108 m 124 108 l gs col0 s gr %% % Polyline %% n 64 108 m 68 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 67 110 m 71 110 l gs col0 s gr %% % Polyline %% n 67 106 m 71 106 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 71 108 m 73 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 73 110 m 76 110 l gs col0 s gr %% % Polyline %% n 73 106 m 76 106 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 76 108 m 78 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 78 110 m 82 110 l gs col0 s gr %% % Polyline %% n 78 106 m 82 106 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 82 108 m 86 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 64 106 m 64 100 l 124 100 l 124 106 l gs col0 s gr %% % Polyline %% n 86 106 m 89 106 l gs col0 s gr %% % Polyline %% n 86 110 m 89 110 l gs col0 s gr %% % Polyline %% n 117 106 m 121 106 l gs col0 s gr %% % Polyline %% n 117 110 m 121 110 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 115 108 m 117 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 112 110 m 115 110 l gs col0 s gr %% % Polyline %% n 112 106 m 115 106 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 110 108 m 112 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 106 110 m 110 110 l gs col0 s gr %% % Polyline %% n 106 106 m 110 106 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 102 108 m 106 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 99 106 m 102 106 l gs col0 s gr %% % Polyline %% n 99 110 m 102 110 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 89 108 m 93 108 l gs col0 s gr %% % Polyline %% n 95 108 m 99 108 l gs col0 s gr %% 1.000 setlinewidth %% % Polyline %% n 77 101 m 77 105 l gs col0 s gr %% % Polyline %% n 72 101 m 72 105 l gs col0 s gr %% % Polyline %% n 83 101 m 83 105 l gs col0 s gr %% % Polyline %% n 85 101 m 85 105 l gs col0 s gr %% % Polyline %% n 103 101 m 103 105 l gs col0 s gr %% % Polyline %% n 105 101 m 105 105 l gs col0 s gr %% % Polyline %% n 111 101 m 111 105 l gs col0 s gr %% % Polyline %% n 116 101 m 116 105 l gs col0 s gr %% % Polyline %% n 90 101 m 90 105 l gs col0 s gr %% % Polyline %% n 92 101 m 92 105 l gs col0 s gr %% % Polyline %% n 96 101 m 96 105 l gs col0 s gr %% % Polyline %% n 98 101 m 98 105 l gs col0 s gr %% % Polyline %% n 94 104 m 94 107 l gs col0 s gr %% % Polyline %% n 94 108 m 94 111 l gs col0 s gr %% 0.500 setlinewidth %% % Polyline %% n 64 109 m 64 113 l gs col0 s gr %% % Polyline %% n 124 109 m 124 113 l gs col0 s gr %% % Polyline %% n 64 116 m 64 120 l gs col0 s gr %% %/Times-Roman findfont 24.00 scalefont setfont %% %69 64 m %% /Times-Roman findfont 20.00 scalefont setfont %% 63 64 m %% gs 1 -1 scale (LPRng) col0 show gr %% $F2psEnd %% grestore showpage EOF lprng-3.8.B/src/AUTHENTICATE/0000777000131400013140000000000011531672401012330 500000000000000lprng-3.8.B/src/AUTHENTICATE/sclient.c0000644000131400013140000001115711531672131014056 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: sclient.c,v 1.74 2004/09/24 20:19:57 papowell Exp $"; /* * Simple Kerberos client tester. * Derived from the Kerberos 5 SCLIENT code - * Note carefully that there are NO MIT copyrights here. */ #include "lp.h" #include "child.h" #include "krb5_auth.h" char *msg[] = { "[-D options] [-p port] [-s service] [-k keytab] [-P principal] host file", " -D turns debugging on", 0 }; char *progname; void send_to_logger( int sfd, int mfd, struct job *job, const char *header, char *msg ){;} void usage() { int i; FPRINTF(STDERR, "usage: %s %s\n", progname, msg[0]); for( i = 1; msg[i]; ++i ){ FPRINTF(STDERR, "%s\n", msg[i]); } } int main(argc, argv) int argc; char *argv[]; { struct hostent *host_ent; struct sockaddr_in sin; int sock; int port = 1234; char *host; int c; extern int opterr, optind, getopt(); extern char * optarg; char buffer[SMALLBUFFER]; char msg[SMALLBUFFER]; char *file; char *keytab = 0; char *principal = 0; progname = argv[0]; while( (c = getopt(argc, argv, "D:p:s:k:P:")) != EOF){ switch(c){ default: FPRINTF(STDERR,"bad option '%c'\n", c ); usage(progname); exit(1); break; case 'k': keytab = optarg; break; case 'D': Parse_debug(optarg,1); break; case 'p': port= atoi(optarg); break; case 's': Set_DYN(&Kerberos_service_DYN,optarg); break; case 'P': principal = optarg; break; } } if( argc - optind != 2 ){ FPRINTF(STDERR,"missing host or file name\n" ); usage(progname); exit(1); } host = argv[optind++]; file = argv[optind++]; /* clear out the structure first */ (void) memset((char *)&sin, 0, sizeof(sin)); if(Kerberos_service_DYN == 0 ) Set_DYN(&Kerberos_service_DYN,"lpr"); if( principal ){ FPRINTF(STDERR, "using '%s'\n", principal ); } else { remote_principal_krb5( Kerberos_service_DYN, host, buffer, sizeof(buffer) ); FPRINTF(STDERR, "default remote principal '%s'\n", buffer ); principal = buffer; } /* look up the server host */ host_ent = gethostbyname(host); if(host_ent == 0){ FPRINTF(STDERR, "unknown host %s\n",host); exit(1); } /* set up the address of the foreign socket for connect() */ sin.sin_family = host_ent->h_addrtype; (void) memcpy((char *)&sin.sin_addr, (char *)host_ent->h_addr, sizeof(host_ent->h_addr)); sin.sin_port = htons(port); /* open a TCP socket */ sock = socket(PF_INET, SOCK_STREAM, 0); Max_open(sock); if( sock < 0 ){ perror("socket"); exit(1); } /* connect to the server */ if( connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){ perror("connect"); close(sock); exit(1); } buffer[0] = 0; if( client_krb5_auth( keytab, Kerberos_service_DYN, host, 0, 0, 0, 0, sock, buffer, sizeof(buffer), file ) ){ FPRINTF( STDERR, "client_krb5_auth failed: %s\n", buffer ); exit(1); } fflush(STDOUT); fflush(STDERR); plp_snprintf(msg, sizeof(msg), "starting read from %d\n", sock ); write(1,msg, safestrlen(msg) ); while( (c = read( sock, buffer, sizeof(buffer) ) ) > 0 ){ buffer[c] = 0; plp_snprintf(msg, sizeof(msg), "read %d from fd %d '%s'\n", c, sock, buffer ); write( 1, msg, safestrlen(msg) ); } plp_snprintf(msg, sizeof(msg), "last read status %d from fd %d\n", c, sock ); write( 1, msg, safestrlen(msg) ); return(0); } /* VARARGS2 */ #ifdef HAVE_STDARGS void setstatus (struct job *job,char *fmt,...) #else void setstatus (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *fmt; #endif char msg[LARGEBUFFER]; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (fmt, char *); msg[0] = 0; if( Verbose ){ (void) plp_vsnprintf( msg, sizeof(msg)-2, fmt, ap); strcat( msg,"\n" ); if( Write_fd_str( 2, msg ) < 0 ) cleanup(0); } VA_END; return; } /* VARARGS2 */ #ifdef HAVE_STDARGS void setmessage (struct job *job,const char *header, char *fmt,...) #else void setmessage (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *fmt, *header; #endif char msg[LARGEBUFFER]; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (header, char * ); VA_SHIFT (fmt, char *); msg[0] = 0; if( Verbose ){ (void) plp_vsnprintf( msg, sizeof(msg)-2, fmt, ap); strcat( msg,"\n" ); if( Write_fd_str( 2, msg ) < 0 ) cleanup(0); } VA_END; return; } lprng-3.8.B/src/AUTHENTICATE/sserver.c0000644000131400013140000001252511531672131014106 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-2003, Patrick Powell, San Diego, CA * papowell@lprng.com * See LICENSE for conditions of use. * ***************************************************************************/ static char *const _id = "$Id: sserver.c,v 1.74 2004/09/24 20:19:57 papowell Exp $"; /* * * Simple authentictor test for kerberos. * Based on the SSERVER code in the Kerberos5 distibution. * See Copyrights, etc. */ #include "lp.h" #include "krb5_auth.h" #include "child.h" #include "fileopen.h" char *msg[] = { "[-D options] [-p port] [-s service] [-S keytab] file", " -D turns debugging on", 0 }; char *progname; void usage() { int i; FPRINTF(STDOUT, "usage: %s %s\n", progname, msg[0]); for( i = 1; msg[i]; ++i ){ FPRINTF(STDOUT, "%s\n", msg[i]); } } int main(int argc, char *argv[]) { struct sockaddr_in peername; int namelen = sizeof(peername); int sock = -1; /* incoming connection fd */ short port = 1234; /* If user specifies port */ extern int opterr, optind, getopt(), atoi(); extern char * optarg; int ch, fd = -1, len; int on = 1; int acc; struct sockaddr_in sin; char auth[128]; char *client = 0; char err[128]; char *file; char buffer[SMALLBUFFER]; struct stat statb; progname = argv[0]; setlinebuf(STDOUT); /* * Parse command line arguments * */ opterr = 0; while ((ch = getopt(argc, argv, "D:p:S:s:")) != EOF) switch (ch) { case 'D': Parse_debug(optarg,1); break; case 'p': port = atoi(optarg); break; case 's': Set_DYN(&Kerberos_service_DYN,optarg); break; case 'S': Set_DYN(&Kerberos_keytab_DYN,optarg); break; default: usage(); exit(1); break; } Spool_file_perms_DYN = 0600; if( argc - optind != 1 ){ usage(); exit(1); } file = argv[optind++]; if( Kerberos_keytab_DYN == 0 ) Set_DYN(&Kerberos_keytab_DYN, "/etc/lpd.keytab"); if( Kerberos_service_DYN == 0 ) Set_DYN(&Kerberos_service_DYN,"lpr"); if( port == 0 ){ FPRINTF( STDOUT, "bad port specified\n" ); exit(1); } /* * If user specified a port, then listen on that port; otherwise, * assume we've been started out of inetd. */ remote_principal_krb5( Kerberos_service_DYN, 0, auth, sizeof(auth)); FPRINTF(STDOUT, "server principal '%s'\n", auth ); if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { FPRINTF(STDOUT, "socket: %s\n", Errormsg(errno)); exit(3); } Max_open(sock); /* Let the socket be reused right away */ (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons(port); if (bind(sock, (struct sockaddr *) &sin, sizeof(sin))) { FPRINTF(STDOUT, "bind: %s\n", Errormsg(errno)); exit(3); } if (listen(sock, 1) == -1) { FPRINTF(STDOUT, "listen: %s", Errormsg(errno)); exit(3); } while(1){ if ((acc = accept(sock, (struct sockaddr *)&peername, &namelen)) == -1){ FPRINTF(STDOUT, "accept: %s\n", Errormsg(errno)); exit(3); } err[0] = 0; auth[0] = 0; client = 0; if( server_krb5_auth( Kerberos_keytab_DYN, Kerberos_service_DYN, acc, &client, err, sizeof(err), file ) ){ FPRINTF( STDOUT, "server_krb5_auth error '%s'\n", err ); goto done; } plp_snprintf(buffer,sizeof(buffer), "client '%s'", client ); FPRINTF(STDOUT,"%s\n",buffer); fd = Checkread( file, &statb ); DEBUG1( "main: opened for write '%s', fd %d, size %ld", file, fd, (long)(statb.st_size) ); if( fd < 0 ){ plp_snprintf( err, sizeof(err), "file open failed: %s", Errormsg(errno)); goto done; } FPRINTF(STDOUT,"RECEVIED:\n"); while( (len = read(fd, buffer,sizeof(buffer)-1)) > 0 ){ write(1,buffer,len); } close(fd); fd = Checkwrite( file, &statb, O_WRONLY|O_TRUNC, 1, 0 ); if( fd < 0 ){ plp_snprintf( err, sizeof(err), "main: could not open for writing '%s' - '%s'", file, Errormsg(errno) ); goto done; } plp_snprintf(buffer,sizeof(buffer), "credentials '%s'\n", client ); Write_fd_str(fd,buffer); close(fd); if( server_krb5_status( acc, err, sizeof(err), file ) ){ FPRINTF( STDOUT, "server_krb5_status error '%s'\n", err ); goto done; } done: close(acc); } exit(0); } /* VARARGS2 */ #ifdef HAVE_STDARGS void setstatus (struct job *job,char *fmt,...) #else void setstatus (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *fmt; #endif char msg[LARGEBUFFER]; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (fmt, char *); msg[0] = 0; if( Verbose ){ (void) plp_vsnprintf( msg, sizeof(msg)-2, fmt, ap); strcat( msg,"\n" ); if( Write_fd_str( 2, msg ) < 0 ) cleanup(0); } VA_END; return; } void send_to_logger( int sfd, int mfd, struct job *job, const char *header, char *msg ){;} /* VARARGS2 */ #ifdef HAVE_STDARGS void setmessage (struct job *job,const char *header, char *fmt,...) #else void setmessage (va_alist) va_dcl #endif { #ifndef HAVE_STDARGS struct job *job; char *fmt, *header; #endif char msg[LARGEBUFFER]; VA_LOCAL_DECL VA_START (fmt); VA_SHIFT (job, struct job * ); VA_SHIFT (header, char * ); VA_SHIFT (fmt, char *); msg[0] = 0; if( Verbose ){ (void) plp_vsnprintf( msg, sizeof(msg)-2, fmt, ap); strcat( msg,"\n" ); if( Write_fd_str( 2, msg ) < 0 ) cleanup(0); } VA_END; return; } lprng-3.8.B/acinclude.m40000644000131400013140000001366511531672127012010 00000000000000define([ENABLE_BOOLEAN],[dnl AC_ARG_ENABLE([$1],AS_HELP_STRING([$2],[$3]),[v="$enableval"],[v=$4]) AC_MSG_NOTICE([$5]) AS_IF([test "x$v" = "xyes"], [$6], [$7]) ]) define([WITH_DIR],[dnl AC_ARG_WITH([$1],AS_HELP_STRING([$2],[$3]),[$4="$withval"],[$4=$5]) AC_MSG_NOTICE([$6]) AC_SUBST($4) ]) dnl The following code is taken from "po.m4 serial 7 (gettext-0.14.3)" dnl "gettext.m4 serial 37 (gettext-0.14.4)" and "nls.m4 serial 2 (gettext-0.14.3)" dnl and mangled heavily to do a bare minimum. dnl The original files state: dnl # Copyright (C) 1995-2005 Free Software Foundation, Inc. dnl # This file is free software; the Free Software Foundation dnl # gives unlimited permission to copy and/or distribute it, dnl # with or without modifications, as long as this notice is preserved. dnl # Authors: dnl # Ulrich Drepper , 1995-2000. dnl # Bruno Haible , 2000-2003. AC_DEFUN([MY_GETTEXT], [ AC_MSG_CHECKING([whether NLS is requested]) dnl Default is disabled NLS AC_ARG_ENABLE(nls,AS_HELP_STRING([--enable-nls],[use Native Language Support]), USE_NLS=$enableval, USE_NLS=no) AC_MSG_RESULT($USE_NLS) AC_SUBST(USE_NLS) dnl If we use NLS, test it if test "$USE_NLS" = "yes"; then dnl If GNU gettext is available we use this. Fallback to external dnl library is not yet supported, but should be easy to request by just dnl adding the correct CFLAGS and LDFLAGS to ./configure dnl (note that gettext and ngettext must exist) AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext1_libc, [AC_TRY_LINK([#include extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings;], [bindtextdomain ("", ""); return * gettext ("") + _nl_msg_cat_cntr + *_nl_domain_bindings], gt_cv_func_gnugettext1_libc=yes, gt_cv_func_gnugettext1_libc=no)]) if test "$gt_cv_func_gnugettext1_libc" = "yes" ; then AC_CHECK_FUNC(ngettext,[ AC_DEFINE(ENABLE_NLS, 1, [Define to 1 if translation of program messages to the user's native language is requested.]) ], [USE_NLS=no]) else USE_NLS=no fi fi AC_MSG_CHECKING([whether to use NLS]) AC_MSG_RESULT([$USE_NLS]) dnl Perform the following tests also without --enable-nls, as dnl they might be needed to generate the files (for make dist and so on) dnl Search for GNU msgfmt in the PATH. dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. dnl The second test excludes FreeBSD msgfmt. AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) dnl Search for GNU xgettext 0.12 or newer in the PATH. dnl The first test excludes Solaris xgettext and early GNU xgettext versions. dnl The second test excludes FreeBSD xgettext. AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], :) dnl Remove leftover from FreeBSD xgettext call. rm -f messages.po dnl Search for GNU msgmerge 0.11 or newer in the PATH. AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) ]) define([CHECK_PLUGINS],[dnl AC_ARG_VAR(PLUGIN_LDFLAGS, [Additional LDFLAGS for plugins (default --shared)]) AC_ARG_VAR(PLUGIN_CFLAGS, [Additional CFLAGS for plugins (default -fPIC)]) AC_ARG_VAR(PLUGINUSER_LDFLAGS, [Additional LDFLAGS for a program loading plugins (default -export-dynamic)]) AC_ARG_ENABLE([plugins],AS_HELP_STRING([--enable-plugins],[build authentication modules as plugins]),[enable_plugins=$enableval],[enable_plugins=no]) DL_LIBS="" if test $enable_plugins != no ; then mysaved_LIBS="$LIBS" AC_SEARCH_LIBS(dlopen, dl, [dnl if test "x$LIBS" != "x$mysaved_LIBS" ; then DL_LIBS="-ldl" fi ], [dnl if test $enable_plugins = default ; then enable_plugins=no else AC_MSG_ERROR([Plugins requested with --enable-plugins but did not find dlopen]) enable_plugins=no fi ]) LIBS="$mysaved_LIBS" fi if test $enable_plugins != no ; then if test "${PLUGIN_CFLAGS+set}" != set ; then PLUGIN_CFLAGS="-fPIE" fi if test "${PLUGIN_LDFLAGS+set}" != set ; then PLUGIN_LDFLAGS="--shared" fi if test "${PLUGINUSER_LDFLAGS+set}" != set ; then PLUGINUSER_LDFLAGS="-export-dynamic" fi AC_CACHE_CHECK([whether dynamic plugins can be generated and work],[my_cv_sys_shared_with_callback_works],[dnl mysaved_LDFLAGS="$LDFLAGS" mysaved_CFLAGS="$CFLAGS" LDFLAGS="$LDFLAGS $PLUGIN_LDFLAGS" CFLAGS="$CFLAGS $PLUGIN_CFLAGS" AC_LINK_IFELSE([[int test(void);int test(void) {return callback();}]], [cp conftest$ac_exeext libmyXYZtest.so || AC_MSG_ERROR([Internal error, perhaps autoconf changed soem internals]) my_cv_sys_shared_with_callback_works=yes], [my_cv_sys_shared_with_callback_works=no]) if test $my_cv_sys_shared_with_callback_works = yes ; then LDFLAGS="$mysaved_LDFLAGS $PLUGINUSER_LDFLAGS -L. -lmyXYZtest" CFLAGS="$mysaved_CFLAGS" AC_TRY_LINK([int callback(void) { return 17; } return test();], [my_cv_sys_shared_with_callback_works=yes], [my_cv_sys_shared_works=no]) fi LDFLAGS="$mysaved_LDFLAGS" CFLAGS="$mysaved_CFLAGS" rm -f libmyXYZtest.so] ) if test $my_cv_sys_shared_with_callback_works = no ; then if test $enable_plugins = default ; then enable_plugins=no else AC_MSG_ERROR([Plugins requested with --enable-plugins but shared libraries cannot be created (might only work with gcc on linux yet, also make sure you have no -Wl,-z,defs or similar set)]) enable_plugins=no fi fi fi AM_CONDITIONAL(WITHPLUGINS, [test $enable_plugins != no]) if test $enable_plugins != no ; then AC_DEFINE([WITHPLUGINS], 1, [Build dynamic loadable plugins]) fi AC_SUBST(DL_LIBS) AC_SUBST(PLUGINUSER_LDFLAGS) AC_SUBST(PLUGIN_LDFLAGS) AC_SUBST(PLUGIN_CFLAGS) ]) lprng-3.8.B/UTILS/0000777000131400013140000000000011531672374010574 500000000000000lprng-3.8.B/UTILS/termcap.c0000644000131400013140000003547211531672127012316 00000000000000/* Work-alike for termcap, plus extra features. Copyright (C) 1985, 1986, 1993 Free Software Foundation, Inc. This program 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, or (at your option) any later version. This program 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 this program; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Emacs config.h may rename various library functions such as malloc. */ #include "lp.h" #ifndef NULL #define NULL (char *) 0 #endif /* BUFSIZE is the initial size allocated for the buffer for reading the termcap file. It is not a limit. Make it large normally for speed. Make it variable when debugging, so can exercise increasing the space dynamically. */ #ifndef BUFSIZE #ifdef DEBUG #define BUFSIZE bufsize int bufsize = 128; #else #define BUFSIZE 2048 #endif #endif /* Looking up capabilities in the entry already found. */ /* The pointer to the data made by tgetent is left here for tgetnum, tgetflag and tgetstr to find. */ static char *term_entry; static char *tgetst1 (); /* Search entry BP for capability CAP. Return a pointer to the capability (in BP) if found, 0 if not found. */ static char * find_capability (bp, cap) register char *bp, *cap; { for (; *bp; bp++) if (bp[0] == ':' && bp[1] == cap[0] && bp[2] == cap[1]) return &bp[4]; return NULL; } int tgetnum (cap) char *cap; { register char *ptr = find_capability (term_entry, cap); if (!ptr || ptr[-1] != '#') return -1; return atoi (ptr); } int tgetflag (cap) char *cap; { register char *ptr = find_capability (term_entry, cap); return ptr && ptr[-1] == ':'; } /* Look up a string-valued capability CAP. If AREA is non-null, it points to a pointer to a block in which to store the string. That pointer is advanced over the space used. If AREA is null, space is allocated with `malloc'. */ char * tgetstr (cap, area) char *cap; char **area; { register char *ptr = find_capability (term_entry, cap); if (!ptr || (ptr[-1] != '=' && ptr[-1] != '~')) return NULL; return tgetst1 (ptr, area); } /* Table, indexed by a character in range 0100 to 0140 with 0100 subtracted, gives meaning of character following \, or a space if no special meaning. Eight characters per line within the string. */ static char esctab[] = " \007\010 \033\014 \ \012 \ \015 \011 \013 \ "; /* PTR points to a string value inside a termcap entry. Copy that value, processing \ and ^ abbreviations, into the block that *AREA points to, or to newly allocated storage if AREA is NULL. Return the address to which we copied the value, or NULL if PTR is NULL. */ static char * tgetst1 (ptr, area) char *ptr; char **area; { register char *p, *r; register int c; register int size; char *ret; register int c1; if (!ptr) return NULL; /* `ret' gets address of where to store the string. */ if (!area) { /* Compute size of block needed (may overestimate). */ p = ptr; while ((c = *p++) && c != ':' && c != '\n') ; ret = (char *) malloc (p - ptr + 1); } else ret = *area; /* Copy the string value, stopping at null or colon. Also process ^ and \ abbreviations. */ p = ptr; r = ret; while ((c = *p++) && c != ':' && c != '\n') { if (c == '^') c = *p++ & 037; else if (c == '\\') { c = *p++; if (c >= '0' && c <= '7') { c -= '0'; size = 0; while (++size < 3 && (c1 = *p) >= '0' && c1 <= '7') { c *= 8; c += c1 - '0'; p++; } } else if (c >= 0100 && c < 0200) { c1 = esctab[(c & ~040) - 0100]; if (c1 != ' ') c = c1; } } *r++ = c; } *r = '\0'; /* Update *AREA. */ if (area) *area = r + 1; return ret; } /* Outputting a string with padding. */ short ospeed; /* If OSPEED is 0, we use this as the actual baud rate. */ int tputs_baud_rate; char PC; /* Actual baud rate if positive; - baud rate / 100 if negative. */ static short speeds[] = { #ifdef VMS 0, 50, 75, 110, 134, 150, -3, -6, -12, -18, -20, -24, -36, -48, -72, -96, -192 #else /* not VMS */ 0, 50, 75, 110, 135, 150, -2, -3, -6, -12, -18, -24, -48, -96, -192, -384 #endif /* not VMS */ }; void tputs (str, nlines, outfun) register char *str; int nlines; register int (*outfun) (); { register int padcount = 0; register int speed; #ifdef emacs extern baud_rate; speed = baud_rate; #else if (ospeed == 0) speed = tputs_baud_rate; else speed = speeds[ospeed]; #endif if (!str) return; while (*str >= '0' && *str <= '9') { padcount += *str++ - '0'; padcount *= 10; } if (*str == '.') { str++; padcount += *str++ - '0'; } if (*str == '*') { str++; padcount *= nlines; } while (*str) (*outfun) (*str++); /* padcount is now in units of tenths of msec. */ padcount *= speeds[ospeed]; padcount += 500; padcount /= 1000; if (speeds[ospeed] < 0) padcount = -padcount; else { padcount += 50; padcount /= 100; } while (padcount-- > 0) (*outfun) (PC); } /* Finding the termcap entry in the termcap data base. */ struct buffer { char *beg; int size; char *ptr; int ateof; int full; }; /* Forward declarations of static functions. */ static int scan_file (); static char *gobble_line (); static int compare_contin (); static int name_match (); #ifdef VMS #include #include #include static int valid_filename_p (fn) char *fn; { struct FAB fab = cc$rms_fab; struct NAM nam = cc$rms_nam; char esa[NAM$C_MAXRSS]; fab.fab$l_fna = fn; fab.fab$b_fns = strlen(fn); fab.fab$l_nam = &nam; fab.fab$l_fop = FAB$M_NAM; nam.nam$l_esa = esa; nam.nam$b_ess = sizeof esa; return SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL; } #else /* !VMS */ #define valid_filename_p(fn) (*(fn) == '/') #endif /* !VMS */ /* Find the termcap entry data for terminal type NAME and store it in the block that BP points to. Record its address for future use. If BP is null, space is dynamically allocated. Return -1 if there is some difficulty accessing the data base of terminal types, 0 if the data base is accessible but the type NAME is not defined in it, and some other value otherwise. */ int tgetent (bp, name) char *bp, *name; { register char *termcap_name; register int fd; struct buffer buf; register char *bp1; char *bp2; char *term; int malloc_size = 0; register int c; char *tcenv = 0; /* TERMCAP value, if it contains :tc=. */ char *indirect = NULL; /* Terminal type in :tc= in TERMCAP value. */ int filep; termcap_name = getenv ("TERMCAP"); if (termcap_name && *termcap_name == '\0') termcap_name = NULL; filep = termcap_name && valid_filename_p (termcap_name); /* If termcap_name is non-null and starts with / (in the un*x case, that is), it is a file name to use instead of /etc/termcap. If it is non-null and does not start with /, it is the entry itself, but only if the name the caller requested matches the TERM variable. */ if (termcap_name && !filep && !strcmp (name, getenv ("TERM"))) { indirect = tgetst1 (find_capability (termcap_name, "tc"), (char **) 0); if (!indirect) { if (!bp) bp = termcap_name; else strcpy (bp, termcap_name); goto ret; } else { /* It has tc=. Need to read /etc/termcap. */ tcenv = termcap_name; termcap_name = NULL; } } if (!termcap_name || !filep) #ifdef VMS termcap_name = "emacs_library:[etc]termcap.dat"; #else termcap_name = "/etc/termcap"; #endif /* Here we know we must search a file and termcap_name has its name. */ fd = open (termcap_name, 0, 0); if (fd < 0) return -1; buf.size = BUFSIZE; /* Add 1 to size to ensure room for terminating null. */ buf.beg = (char *) malloc (buf.size + 1); term = indirect ? indirect : name; if (!bp) { malloc_size = indirect ? strlen (tcenv) + 1 : buf.size; bp = (char *) malloc (malloc_size); } bp1 = bp; if (indirect) /* Copy the data from the environment variable. */ { strcpy (bp, tcenv); bp1 += strlen (tcenv); } while (term) { /* Scan the file, reading it via buf, till find start of main entry. */ if (scan_file (term, fd, &buf) == 0) { close (fd); free (buf.beg); if (malloc_size) free (bp); return 0; } /* Free old `term' if appropriate. */ if (term != name) free (term); /* If BP is malloc'd by us, make sure it is big enough. */ if (malloc_size) { malloc_size = bp1 - bp + buf.size; termcap_name = (char *) realloc (bp, malloc_size); bp1 += termcap_name - bp; bp = termcap_name; } bp2 = bp1; /* Copy the line of the entry from buf into bp. */ termcap_name = buf.ptr; while ((*bp1++ = c = *termcap_name++) && c != '\n') /* Drop out any \ newline sequence. */ if (c == '\\' && *termcap_name == '\n') { bp1--; termcap_name++; } *bp1 = '\0'; /* Does this entry refer to another terminal type's entry? If something is found, copy it into heap and null-terminate it. */ term = tgetst1 (find_capability (bp2, "tc"), (char **) 0); } close (fd); free (buf.beg); if (malloc_size) bp = (char *) realloc (bp, bp1 - bp + 1); ret: term_entry = bp; if (malloc_size) return (int) bp; return 1; } /* Given file open on FD and buffer BUFP, scan the file from the beginning until a line is found that starts the entry for terminal type STR. Return 1 if successful, with that line in BUFP, or 0 if no entry is found in the file. */ static int scan_file (str, fd, bufp) char *str; int fd; register struct buffer *bufp; { register char *end; bufp->ptr = bufp->beg; bufp->full = 0; bufp->ateof = 0; *bufp->ptr = '\0'; lseek (fd, 0L, 0); while (!bufp->ateof) { /* Read a line into the buffer. */ end = NULL; do { /* if it is continued, append another line to it, until a non-continued line ends. */ end = gobble_line (fd, bufp, end); } while (!bufp->ateof && end[-2] == '\\'); if (*bufp->ptr != '#' && name_match (bufp->ptr, str)) return 1; /* Discard the line just processed. */ bufp->ptr = end; } return 0; } /* Return nonzero if NAME is one of the names specified by termcap entry LINE. */ static int name_match (line, name) char *line, *name; { register char *tem; if (!compare_contin (line, name)) return 1; /* This line starts an entry. Is it the right one? */ for (tem = line; *tem && *tem != '\n' && *tem != ':'; tem++) if (*tem == '|' && !compare_contin (tem + 1, name)) return 1; return 0; } static int compare_contin (str1, str2) register char *str1, *str2; { register int c1, c2; while (1) { c1 = *str1++; c2 = *str2++; while (c1 == '\\' && *str1 == '\n') { str1++; while ((c1 = *str1++) == ' ' || c1 == '\t'); } if (c2 == '\0') { /* End of type being looked up. */ if (c1 == '|' || c1 == ':') /* If end of name in data base, we win. */ return 0; else return 1; } else if (c1 != c2) return 1; } } /* Make sure that the buffer <- BUFP contains a full line of the file open on FD, starting at the place BUFP->ptr points to. Can read more of the file, discard stuff before BUFP->ptr, or make the buffer bigger. Return the pointer to after the newline ending the line, or to the end of the file, if there is no newline to end it. Can also merge on continuation lines. If APPEND_END is non-null, it points past the newline of a line that is continued; we add another line onto it and regard the whole thing as one line. The caller decides when a line is continued. */ static char * gobble_line (fd, bufp, append_end) int fd; register struct buffer *bufp; char *append_end; { register char *end; register int nread; register char *buf = bufp->beg; register char *tem; if (!append_end) append_end = bufp->ptr; while (1) { end = append_end; while (*end && *end != '\n') end++; if (*end) break; if (bufp->ateof) return buf + bufp->full; if (bufp->ptr == buf) { if (bufp->full == bufp->size) { bufp->size *= 2; /* Add 1 to size to ensure room for terminating null. */ tem = (char *) realloc (buf, bufp->size + 1); bufp->ptr = (bufp->ptr - buf) + tem; append_end = (append_end - buf) + tem; bufp->beg = buf = tem; } } else { append_end -= bufp->ptr - buf; bcopy (bufp->ptr, buf, bufp->full -= bufp->ptr - buf); bufp->ptr = buf; } if (!(nread = read (fd, buf + bufp->full, bufp->size - bufp->full))) bufp->ateof = 1; bufp->full += nread; buf[bufp->full] = '\0'; } return end + 1; } #ifdef TEST #ifdef NULL #undef NULL #endif #include main (argc, argv) int argc; char **argv; { char *term; char *buf; term = argv[1]; printf ("TERM: %s\n", term); buf = (char *) tgetent (0, term); if ((int) buf <= 0) { printf ("No entry.\n"); return 0; } printf ("Entry: %s\n", buf); tprint ("cm"); tprint ("AL"); printf ("co: %d\n", tgetnum ("co")); printf ("am: %d\n", tgetflag ("am")); } tprint (cap) char *cap; { char *x = tgetstr (cap, 0); register char *y; printf ("%s: ", cap); if (x) { for (y = x; *y; y++) if (*y <= ' ' || *y == 0177) printf ("\\%0o", *y); else putchar (*y); free (x); } else printf ("none"); putchar ('\n'); } #endif /* TEST */ lprng-3.8.B/UTILS/test_rw_pipe.c0000644000131400013140000000176011531672127013360 00000000000000#include #include #include #include #define HAVE_SOCKETPAIR main() { int fds[2], i; char line[4]; int pid; char *m1 = "to"; char *m2 = "fro"; #ifdef HAVE_SOCKETPAIR i = socketpair( AF_UNIX, SOCK_STREAM, 0, fds); #else i = pipe( fds ); #endif if( i < 0 ) exit(1); printf("pipe\n"); if( (pid = fork()) < 0) exit(1); if( pid == 0 ){ /* Child */ printf("child\n"); if( write( fds[0], m1, strlen(m1) ) < 0 ) exit(1); printf("child write\n"); i = read( fds[0], line, sizeof(line) ); if( i < 0 ) exit(1); line[i] = 0; if( strcmp( line, m2 ) ) exit(1); printf("child read OK\n"); fflush(stdout); exit(0); } else { printf("mother\n"); i = read( fds[1], line, sizeof(line) ); if( i < 0 ) exit(1); line[i] = 0; if( strcmp( line, m1 ) ) exit(1); printf("mother read\n"); if( write( fds[1], m2, strlen(m2) ) < 0 ) exit(1); printf("mother write OK\n"); wait(&i); printf("child exit %d\n", i); } exit(0); } lprng-3.8.B/UTILS/tcpsend.c0000644000131400013140000000730211531672127012312 00000000000000/* * tcpsend [-t timeout] host port [files] * * open a TCP/IP connection to port on host and send files * Super lightweight LPR ??? * tcpsend.c,v 1.1 2000/10/14 21:11:23 papowell Exp */ #include #include #include #include #include #include #include #include #include #include #include #include char *Prog = "???"; char *msg[] = { "use: %s [-t timeout] host port [files]", " -t timeout - try connecting for timeout seconds", 0 }; int max_try = 10; void do_send( int sock, int fd, char *name ); void Set_linger( int sock, int n ); void usage(void) { int i; fprintf( stderr, msg[0], Prog ); fprintf( stderr, "\n"); for( i = 1; msg[i]; ++i ){ fprintf( stderr, "%s\n", msg[i] ); } exit(1); } char buffer[10*1024]; int main( int argc, char **argv ) { int n, try; int sock; /* socket */ char *s, *host, *port; struct sockaddr_in dest_sin; /* inet socket address */ struct hostent *host_ent = 0; (void)signal( SIGPIPE, SIG_IGN ); if( argv[0] ) Prog = argv[0]; if( (s = strrchr(Prog,'/')) ){ Prog = s+1; } while( (n = getopt(argc, argv, "t:")) != EOF ){ switch(n){ case 't': max_try = atoi(optarg); break; default: usage(); break; } } if( argc - optind < 2 ) usage(); sock = -1; memset(&dest_sin, 0, sizeof (dest_sin)); host = argv[optind++]; port = argv[optind++]; if( (host_ent = gethostbyname( host )) ){ dest_sin.sin_family = host_ent->h_addrtype; if( host_ent->h_length > sizeof( dest_sin.sin_addr ) ){ fprintf(stderr,"%s: address length wrong\n", Prog); exit(1); } memcpy(&dest_sin.sin_addr, host_ent->h_addr_list[0], host_ent->h_length ); } else /* if( inet_pton( AF_INET, host, &dest_sin.sin_addr ) != 1 ){ */ if( (dest_sin.sin_addr.s_addr = inet_addr( host )) == -1 ){ fprintf(stderr,"%s: cannot find address for '%s'\n", Prog, host ); exit(1); } n = atoi(port); if( n <= 0 ){ fprintf(stderr,"%s: bad port '%s'\n", Prog, port ); exit(1); } dest_sin.sin_port = htons(n); /* we get the printable from the socket address */ #if 0 fprintf(stderr, "connect to '%s',port %d\n", inet_ntoa( dest_sin.sin_addr )), (int) ntohs(dest_sin.sin_port) ); #endif try = 0; do{ if( sock != -1 ) close(sock ); sock = -1; sock = socket(AF_INET, SOCK_STREAM, 0 ); if( sock == -1 ){ fprintf(stderr,"%s: socket() failed '%s'\n", Prog, strerror(errno) ); exit(1); } n = connect(sock, (void *)&dest_sin, sizeof(dest_sin) ); if( n == -1 && ++try < max_try ){ sleep(1); } else { break; } }while( n == -1 ); if( n == -1 ){ fprintf(stderr, "%s: connect to '%s',port %d failed after %d tries - %s\n", Prog, inet_ntoa( dest_sin.sin_addr), (int) ntohs(dest_sin.sin_port), try, strerror(errno) ); exit(1); } if( optind == argc ){ do_send( sock, 0, "stdin" ); } else for(; optind < argc; ++optind ){ if( (n = open(argv[optind], O_RDONLY, 0)) == -1 ){ fprintf(stderr, "%s: cannot open '%s' - %s\n", Prog, argv[optind], strerror(errno) ); exit(1); } do_send( sock, n, argv[optind] ); close(n); } /* we shut down the connection */ shutdown(sock,1); while( (n = read(sock,&buffer,sizeof(buffer))) > 0 ); close(sock); return(0); } void do_send( int sock, int fd, char *name ) { int cnt, n, i; while( (n = read(fd,buffer,sizeof(buffer))) > 0 ){ for( cnt = i = 0; cnt >= 0 && i < n; i += cnt ){ cnt = write(sock,buffer+i,n-i); } if( cnt < 0 ){ fprintf(stderr, "%s: cannot write to remote host - %s\n", Prog, strerror(errno) ); exit(1); } } if( n < 0 ){ fprintf(stderr, "%s: cannot read from '%s' - %s\n", Prog, name, strerror(errno) ); exit(1); } } lprng-3.8.B/UTILS/lpq_in_perl.in0000644000131400013140000000301211531672127013334 00000000000000#!@PERL@ eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) use strict; use English; use Socket; use LPRng; use Getopt::Std; my( $Printer, $Pc_value, $Debug, %Args, $pr, $remote, $port, $option, $options, $SOCK, $line, $prefix, $firstpart, $count, $max, ); $| = 1; $Debug = 0; Set_Debug($Debug); getopts( "P:svl", \%Args); Setup_LPRng( %Args ); # get the printer name $Printer = Get_printer_name( %Args ); if( not $Printer ){ die "missing printer name"; } print "Printer '$Printer'\n" if $Debug; $Pc_value = Setup_pc_entry( $Printer ); ($pr, $remote, $port ) = Get_remote_pr_host( $Printer, $Pc_value ); print "pr '$pr', remote '$remote', port '$port'\n" if $Debug; $option = 4; $option = 3 if( $Args{'s'} ); $option = 8 if( $Args{'v'} ); $max = 0; $max += $Args{'l'} if $Args{'l'}; if( $max > 4 ){ $max = 0; } else { $max = (1 << $max ); } print "max $max\n" if $Debug; $SOCK = getconnection( $remote, $port ); $options = join (" ", @ARGV); printf $SOCK "%c%s%s\n", $option, $pr, $options ? (" " . $options) : ""; $prefix = ""; while ( defined( $line = <$SOCK> ) ) { if( $max ){ ($firstpart) = split( ":", $line ); print "firstpart '$firstpart', count $count\n" if $Debug; $firstpart ||= ""; if( $prefix eq $firstpart ){ if( ++$count >= $max ){ next; } } else { $count = 0; $prefix = $firstpart; } } print $line; } close ($SOCK) or die "close: $!"; exit 0; lprng-3.8.B/UTILS/remote_active.in0000644000131400013140000000610011531672127013657 00000000000000#!@PERL@ use English; use IO::Socket; my $JSUCC = 0; my $JABORT = 33; my $JNOSPOOL = 38; my $JNOPRINT = 39; my $debug = 0; my $optind; # pull out the options my($key,$value,$opt,$long,$opt_c); for( $i = 0; $i < @ARGV; ++$i ){ $opt = $ARGV[$i]; print STDERR "XX opt= $opt\n" if $debug; if( $opt eq '-c' ){ $opt_c = 1; } elsif( ($key, $value) = ($opt =~ /^-(.)(.*)/) ){ if( $value eq "" ){ $value = $ARGV[++$i]; } ${"opt_$key"} = $value; print STDERR "XX opt_$key = " . ${"opt_$key"} . "\n" if $debug; } else { $optind = $i; last; } print STDERR "XX opt_P = $opt_P\n" if $debug; } $long = 0; # short if( defined($opt_T) ){ print STDERR "XX CHECK_REMOTE opt_T=$opt_T\n" if $debug; if( $opt_T =~ /debug/ ){ $debug = 1; } if( $opt_T =~ /short/ ){ $long = 1; } if( $opt_T =~ /long/ ){ $long = 0; } } print STDERR "XX CHECK_REMOTE opt_P=$opt_P\n" if $debug; print STDERR "XX CHECK_REMOTE " . join(" ",@ARGV) . "\n" if $debug; if( !defined($opt_P) ){ print STDERR "$0: no -P value\n"; exit( $JABORT ); } $printer = $opt_P; while( checkstatus( $printer, $long ) ){ print STDERR "XX CHECK_REMOTE sleeping\n" if $debug; sleep(10); } exit $JSUCC; sub checkstatus { my ($printer,$long) = @_; my ($remote,$port); my ($count, $socket, $line); if( $long ){ $long = 4; } else { $long = 3; } if( $printer =~ /@/ ){ ($printer,$remote) = $printer =~ m/(.*)@(.*)/; } $remote="localhost" unless $remote; if( $remote =~ /%/ ){ ($remote,$port) = $remote =~ m/(.*)%(.*)/; } $port = 515 unless $port; print STDERR "XX CHECK_REMOTE remote='$remote', port='$port', pr='$printer', op='$long'\n" if $debug; $socket = getconnection( $remote, $port ); $count = -1; # send the command printf $socket "%c%s\n", $long, $printer; while ( defined( $line = <$socket>) && $count < 0 ){ chomp $line; print STDERR "XX CHECKREMOTE '$line'\n" if $debug; if( $line =~ /printing disa/ ){ print STDERR "XX CHECKREMOTE printing disable\n" if $debug; exit $JNOPRINT; } elsif( $line =~ /spooling disa/ ){ print STDERR "XX CHECKREMOTE printing disable\n" if $debug; exit $JNOSPOOL; } elsif( $line =~ /([0-9]*)\s+job.?$/ ){ $count = $1; print STDERR "XX CHECKREMOTE $count jobs\n" if $debug; } } close $socket; if( $count < 0 ){ print STDERR "CHECKREMOTE cannot decode status\n"; exit $JABORT; } return $count; } sub getconnection { my ($remote,$port) = @_; my ($socket); print STDERR "XX CHECK_REMOTE remote='$remote', port=$port\n" if $debug; $socket = IO::Socket::INET->new( Proto => "tcp", PeerAddr => $remote, PeerPort => $port, ); if( !$socket ){ print STDERR "CHECK_REMOTE IO::Socket::INET failed - $!\n"; exit $JABORT; } $socket->autoflush(1); $socket; } lprng-3.8.B/UTILS/extract_pjl0000755000131400013140000001222511531672127012753 00000000000000#!/usr/bin/perl use strict; use FileHandle; use Getopt::Std; use IO::Select; use IO::Socket::INET; sub usage(){ print <{d}; $debug = 2 if $opt->{D}; $host = $opt->{h} if $opt->{h}; $port = $opt->{p} if $opt->{p}; $timeout = $opt->{t} if $opt->{t}; $verbose = 1 if $opt->{v}; if( $host ){ my $socket = IO::Socket::INET->new( PeerAddr=>$host, PeerPort=>$port, Proto=>"tcp", Type=>SOCK_STREAM) or die "could not connect to $host, port $port"; print $socket "\033%-12345X" . "\@PJL\n" . "\@PJL INFO VARIABLES\n" . "\@PJL INFO ID\n" . "\@PJL INFO CONFIG\n" . "\@PJL ENTER LANGUAGE = PCL\n" . "\033%-12345X" or die "write to socket failed"; my $s = IO::Select->new(); my $in = ""; my $input; while(1){ $s->add($socket); print "starting wait, timeout $timeout\n" if $debug; my @ready = $s->can_read($timeout); print "ready '" . scalar @ready . "'\n" if $debug; last if( @ready == 0 ); my $len = sysread $socket, $input, 1024; print "Read $len\n" if $debug > 1; last if not $len; $input =~ s/[\015\014]//g; print " INPUT '$input'\n" if $debug > 1; $in .= $input; } close($socket); @lines = map( "$_\n", split("\n",$in )); } else { @lines = <> or die "No input"; } print "Input " . join("", @lines) . "\n" if $debug; if( $verbose ){ print join("", @lines); exit(0); } $inbody = 0; $outputline = ""; foreach (@lines){ chomp; s/\015//; $line = $_; print "# INPUT $_ \n" if $debug; if( /^\@PJL/ ){ if( /^\@PJL\s+INFO\s+VARIABLES/ ){ $inbody = 1; } else { $inbody = 0; } } if( not $inbody and $outputline ){ print STDERR "# Unexpected end of information\n"; print $outputline . "\n"; exit(1); } next if( not $inbody ); if ($line =~ m/^\s*([\w\s:]*)\s*=\"?([\w\.]*)\"?\s*\[([0-9]*)\s*(\w*)\s*(\w*)\]/) { # Option header if( $outputline ){ print STDERR "# Incomplete option '$outputline'\n"; exit(1); } my $typestr; my $modifierstr; ($option, $default, $numchoices, $typestr, $modifierstr) = ($1, $2, $3, $4, $5); print "# Option: '$option', Default '$default', Numchoices '$numchoices', Typestr '$typestr', Modifier '$modifierstr'\n" if $debug; if ($modifierstr eq "READONLY") { # Ignore READONLY options $numchoices = -2; print "# WARNING: Read-only option '$option', ignored!\n"; next; } $choicesfound = 0; @choices = (); my $optstr = $option; $optstr =~ s/\W/_/g; $outputline = $optstr . "="; if( $optstr ne $option ){ $optstr = "($option)"; $optstr =~ s/\s/+/g; $outputline .= $optstr; } if (($modifierstr eq "STRING") || ($typestr eq "STRING")) { $outputline .= "STRING;"; print $outputline . "\n"; $outputline = ""; $numchoices = -2; next; } if ($numchoices == 1 && $typestr eq "ENUMERATED") { # Ignore enumerated with 1 choice $numchoices = -2; print "# WARNING: enumerated option '$option' with one choice, ignored!\n"; $outputline = ""; $numchoices = -2; next; } $outputline .= "$typestr;"; } else { $choicesfound = @choices; print "# option: '$line', numchoices '$numchoices', found '$choicesfound'\n" if $debug>1; next if( $numchoices < 0 ); $line =~ s/\s//g; next if( $line eq "" ); if( not $numchoices or ($numchoices <= $choicesfound) ){ print "# Unexpected option '$line'\n"; next; } push @choices, $line; if( @choices == $numchoices ){ print $outputline . join(",",@choices). "\n"; $outputline = ""; } } } if( $outputline ){ print STDERR "# Unexpected EOF\n"; print $outputline . "\n"; exit(1); } lprng-3.8.B/UTILS/ncpprint0000755000131400013140000000360511531672127012273 00000000000000#!/bin/sh # $Id: ncpprint,v 1.74 2004/09/24 20:19:56 papowell Exp $ # This script is an input filter for printcap printing on a unix machine. It # uses the nprint program to print the file to the specified ncp-based # server and queue. # For example you could have a printcap entry like this # # ncp:lp=/dev/null:sd=/usr/spool/ncp:sh:if=/usr/local/bin/ncpprint # # which would create a unix printer called "ncp" that will print via this # script. You will need to create the spool directory /usr/spool/ncp with # appropriate permissions and ownerships for your system. # # This version reads from a ${SPOOLDIR}/general.cfg # file or uses the PRINTCAP_ENTRY environment variable # passed by LPRng, and the 'ncp_options' value in it. # The username and password information are in an 'authfile' # # # If you use the ${SPOOLDIR}/general.cfg file, it should contain: # server=PC_SERVER # printer=PRINTER_QUEUE # authfile=auth # # # Example: # server=NWSERVER # printer=P_QUEUE1 # authfile=auth # authfile has: # username=fred # password= # # You can also put options into the printcap ncp_options entry # ncp:lp=/dev/null:sd=/usr/spool/ncp:sh:if=/usr/local/bin/ncpprint # ncp_options= server=NWSERVER printer=P_QUEUE1 authfile=authfile # if [ -f ./general.cfg ] ; then . ./general.cfg fi options=`echo "${PRINTCAP_ENTRY}" | sed -n -e 's/:ncp_options=//' ` if [ -n "$options" ] ; then eval export $options fi # get username and password values if [ -n "$authfile' -a -f "$authfile" ] ; then . $authfile fi usercmd="" if [ "$username" != "" ]; then if [ "$password" != "" ]; then usercmd="-U $username -P $password" else usercmd="-U $username -n" fi fi #cat > /tmp/printout #x_command="" #case $translate in # yes) x_command="translate" ;; #esac #echo $server $password $translate $x_command > /tmp/ncpprint.log /usr/bin/nprint -S $server -q $printer $usercmd -N - 2>/dev/null lprng-3.8.B/UTILS/read_conf.in0000644000131400013140000003152511531672127012762 00000000000000#!@PERL@ # read the lpd.conf file, and set up values from it use strict; use FileHandle; use Sys::Hostname; use Socket; use Getopt::Std; sub FixStrVals( $ \% ); sub Setup_pc_entry( $ \% \% \%); sub Real_printer( $ \% ); sub MatchHost( \@ $ ); sub MakeMask( $ ); sub Read_printcap_file( $ \% \% $ $ \@ ); sub CheckRecurse( $ \% \% $ $ \@ ); sub Read_pc_entry( $ ); sub Dump_index( $ \% ); sub Dump_pc( $ \% ); sub Read_conf( $ \% ); sub Dump_conf( $ \% ); sub Fix_value( $ ); sub trimall( $ ); # permanent values # Debug level my($Debug) = 0; # # %Init_hash: lpd.conf file values # %Pc_hash: printcap entries # %Pc_index: printcap entry names # @Hostname: hostname information, used for 'oh' printcap information # %pc: current printcap information # %Args: command line arguments, processed by getopt # $Printer: selected or current printer # my(%Init_hash, %Pc_hash,%Pc_index,@Hostname,%Keyvals,$Pc_value,%Args); my($Printer); # maximum depth of recursion for printcap file lookup my($Max_depth) = 10; sub trimall( $ ) { my($line) = @_; $line ||= ""; $line =~ s/^\s+//; $line =~ s/\s+$//; return( $line ); } # convert a printcap or config file value into # a corresponding string or integer value sub Fix_value( $ ) { my($value) = @_; if( $value =~ /^=/ or $value =~ /^#/ ){ $value = trimall( substr( $value, 1 ) ); } elsif ( $value =~ /^\@/ ){ $value = 0; } else { $value = 1; } return $value; } # sub Read_conf( $conf_file, \%conf_values ) # Read a configuration file # $conf_file = configuration file # $conf_values = hash to store values in # sub Dump_conf( $ \% ) { my($title, $hash) = @_; my($key); print "$title config\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } sub Read_conf( $ \% ) { my($conf_file,$conf_values) = @_; my($file,$key,$value,$line); # open the conf file $file = new FileHandle; if( not defined( $file->open("<$conf_file")) ){ return "cannot open $conf_file - $!"; } while( defined( $line = <$file>) ){ chomp $line; next if not $line or $line =~ /^\s*#/; ($key,$value) = ($line =~ /^\s*([\w-]*)(.*)/); $value = trimall($value); ($key = trimall($key)) =~ s/-/_/g; print "key '$key'='$value'\n" if $Debug > 2; $conf_values->{$key} = Fix_value( $value ); print "set key '$key'='" . $conf_values->{$key} . "'\n" if $Debug > 2; } $file->close; Dump_conf( "Read_conf", %$conf_values ) if $Debug > 1; return ""; } # Dump_pc( $title, %Pc_hash ) # dump the printcap hash # sub Dump_pc( $ \% ) { my($title, $hash) = @_; my($key, $name); $name = (); $name = \@{$hash->{'NAME'}}; print "Dump_pc: $title pc '". join( "','",@$name) . "'\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } sub Dump_index( $ \% ) { my($title, $hash) = @_; my($key); print "Dump_index: $title index\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } # sub Read_pc_entry( $file ) # $file = filehandle # find and read a printcap entry # my($lastline); sub Read_pc_entry( $ ) { my($file) = @_; my($hash,$state,$escape,$line,@lines,$len,$i,@names); my($key,$value,$add_next); $state = ""; $hash = (); $add_next = 0; print "Read_pc_entry: starting\n" if $Debug > 1; while( $lastline or defined( $lastline = <$file> ) ){ $line = trimall( $lastline ); print "line '$line'\n" if $Debug > 3; if( not $line or $line =~ /^\s*#/ ){ $lastline = ""; next; } # beginning of next entry? last if not $add_next and $line =~ /^\s*\w/ and $state ne ""; # we get rid of escapes at the end of the line $lastline = ""; $add_next = 0; ($line, $escape) = ($line =~ /^(.*?)(\\*)$/); if( defined( $escape ) ){ print "escape '$escape'\n" if $Debug > 3; $len = length($escape); if( $len % 2 ){ $escape = substr($escape,0,$len-1); $add_next = 1; } $line .= $escape; } last if( not $state and $line =~ /^\s*include\s/ ); $state .= $line; print "state '$state'\n" if $Debug > 3; } print "Read_pc_entry: final state '$state'\n" if $Debug > 2; if( $state eq "" ){ return undef; } @lines = split( /\s*:+/,$state); if( $Debug > 3 ){ print "Read_pc_entry: split values=\n"; for( $i = 0 ; $i < @lines; ++$i ){ print "[$i] '$lines[$i]'\n"; } } @names = split( /\s*\|+/, shift(@lines)); @names = map { trimall($_) } @names; @{$hash->{'NAME'}} = @names; foreach $line (@lines){ ($key,$value) = ($line =~ /^\s*([\w-]*)(.*)/); $value = trimall($value); ($key = trimall($key)) =~ s/-/_/g; print " key '$key'='$value'\n" if $Debug > 3; $hash->{$key} = Fix_value( $value ); print " set key '$key'='" . $hash->{$key} . "'\n" if $Debug > 3; } Dump_pc( "Read_pc_entry: final value", %$hash ) if $Debug > 1; return $hash; } sub CheckRecurse( $ \% \% $ $ \@ ) { if( defined $lastline ){ my($v,$file) = split( ' ', $lastline ); if( $v eq 'include' ){ $lastline = ""; print "CheckRecurse: file '$file'\n" if $Debug>0; my( $pc_file, $Pc_hash, $Pc_index, $server, $depth, $hostname ) = @_; Read_printcap_file($file, %$Pc_hash, %$Pc_index, $server, $depth, @$hostname ); } } } # sub Read_printcap_file( # $pc_file - file name # %Pc_hash - hash to store printcap values in # %Pc_index - index of all printcap names # $server - if $server != 0 then a server, and use server printcap entries # $depth - recursion depth # @Hostname - hostname information # # read the printcap file and produce a # hash with pointers to hashes of printcap vars # # Algorithm: # open file # while (read a printcap entry){ # decode the printcap entry # if printcap values exist then # merge values # else # create printcap entry # endif # endwhile sub Read_printcap_file( $ \% \% $ $ \@ ) { my( $pc_file, $Pc_hash, $Pc_index, $server, $depth, $hostname ) = @_; my($file,$file_name,$hash,$key,$value,$names,$first,$name); my($i,@n,@Hostentry); # open the conf file $file = new FileHandle; ++$depth; print "Read_printcap_file: file '$pc_file', depth $depth\n" if $Debug>0; if( $depth > $Max_depth ){ return "nesting too deep for '$pc_file'"; } # get either file or filter $file_name = trimall($pc_file); if( ($file_name =~ s/^\|//) ){ $file_name = $file_name . '|'; } else { $file_name = '<' . $file_name; } $file_name = FixStrVals( $file_name, %Keyvals ); print "Read_printcap_file: opening '$file_name'\n" if $Debug>0; if( not defined( $file->open($file_name)) ){ return "cannot open '" . $file_name . "' - $!"; } for(; defined( $hash = Read_pc_entry($file) ); CheckRecurse($pc_file, %$Pc_hash, %$Pc_index, $server, $depth, @$hostname ) ){ Dump_pc( "Read_printcap_file: checking", %$hash ) if $Debug > 1; if( $hash->{'server'} and not $server ){ print "Read_printcap_file: " . "server=(pc '$hash->{server}', need '$server')\n" if $Debug>1; next; } if( $hash->{'oh'} and not MatchHost( @$hostname, $hash->{'oh'} ) ){ print "Read_printcap_file: " . "oh '$hash->{oh}' not matched\n" if $Debug>1; next; } $names = $hash->{'NAME'}; $first = $names->[0]; # find out if we need to add or merge printcap # entries my(%k) = (); for( $i = 1; $i < @$names; ++$i ){ $name = $names->[$i]; $k{$name} = $name; } $value = $Pc_hash->{$first}->{'NAME'}; if( defined @$value ){ for( $i = 1; $i < @$value; ++$i ){ $name = $value->[$i]; $k{$name} = $name; } } @n = ( $first, sort keys %k ); @{$Pc_hash->{$first}->{'NAME'}} = @n; foreach $key (keys %$hash){ $value = $hash->{$key}; if( $key ne 'NAME' ){ $Pc_hash->{$first}->{$key} = $value; } } foreach $name (@$names){ $Pc_index->{$name} = $first; } if( not $Pc_index->{'FIRST'} ){ $Pc_index->{'FIRST'} = $first; } if( $Debug > 1 ){ Dump_index( "Read_printcap_file: after adding '$first'", %$Pc_index ); foreach $name (sort keys %$Pc_hash){ Dump_pc( "Read_printcap_file: after adding '$first'", %{$Pc_hash->{$name}} ); } } } if( $Debug > 0 ){ Dump_index( "Read_printcap_file: after '$pc_file'", %$Pc_index ); foreach $name (sort keys %$Pc_hash){ Dump_pc( "Read_printcap_file: after '$pc_file'", %{$Pc_hash->{$name}} ); } } } sub MakeMask( $ ) { my($mask) = @_; my($mnum,$v,@v,$x,$i,$j,@d); if( defined $mask ){ if( $mask =~ /\./ ){ $mnum = inet_aton( $mask ); } else { if( $mask < 32 and $mask >= 0 ){ $v = pack( "N", (1 << $mask ) - 1); @v = reverse split( '', unpack( "B32", $v )); for( $i = 0; $i < 4; ++$i ){ $x = 0; for( $j = 0; $j < 8; ++$j ){ $x *= 2; $x += $v[$i*8+$j]; } $d[$i] = $x; } $i = join(".", @d ); #print "MakeMask: generated $mask = '$i'\n" if $Debug > 5; $mnum = inet_aton( $i ); } else { $mnum = inet_aton( "255.255.255.255" ); } } } else { $mnum = inet_aton( "255.255.255.255" ); } print "MakeMask: $mask = '" . inet_ntoa( $mnum ) . "'\n" if $Debug > 5; return $mnum; } # sub MatchHost( @Hostinfo, $matches ) # @Hostinfo is value returned by gethostbyname() # ($name, $alises, $addrtype, $length, @addrs ) # 0 1 2 3 4 # matches has format: ((glob|ip/mask),)* sub MatchHost( \@ $ ) { my($hostinfo,$matches) = @_; my(@list,$value,$addr,$mask,$anum,$mnum,$null,@v,$i,$ipaddr); @list = split( '[,\s]', $matches ); foreach $value ( @list ){ print "Matchhost: '$value' to $hostinfo->[0]\n" if $Debug>2; if( $value =~ /^\d/ ){ # we have addr/mask $null = inet_aton("0.0.0.0"); ($addr,$mask) = split( '/',$value ); $anum = inet_aton( $addr ); $mnum = MakeMask( $mask ); print "Matchhost: addr '" . inet_ntoa($anum) . "', mask '" . inet_ntoa($mnum) . "'\n" if $Debug>3; for($i = 4; $i < @$hostinfo; ++$i ){ $ipaddr = $hostinfo->[$i]; print "Matchhost: ipaddr '" . inet_ntoa($ipaddr) . "'\n" if $Debug>3; $ipaddr = ($ipaddr ^ $anum) & $mnum; print "Matchhost: result '" . inet_ntoa($ipaddr) . "'\n" if $Debug>3; if( $ipaddr eq $null ){ print "Matchhost: found '".inet_ntoa( $hostinfo->[$i])."'\n" if $Debug>3; return 1; } } } else { # we have glob str $value =~ s/\./\\./g; $value =~ s/\*/.*/g; print "Matchhost: new value '$value'\n" if $Debug>3; if( $hostinfo->[0] =~ /$value/ ){ print "Matchhost: found\n" if $Debug>3; return 1; } } } return 0; } # sub Setup_pc_entry( $name ) # 1. look up the pc entry # 2. set the initial values to configuration defaults # 3. combine the pc values # returns: hash of combined values sub Real_printer( $ \% ) { my($name, $Pc_index) = @_; $name = $Pc_index->{$name}; return $name; } sub Setup_pc_entry( $ \% \% \%) { my($name, $Pc_hash, $Pc_index, $Init_hash ) = @_; my($real, %hash, $value, $key ); $real = Real_printer( $name, %$Pc_index ); if( not $real ){ return undef; } print "Setup_pc_entry: pr '$name', using real '$real'\n" if $Debug > 2; %hash = %$Init_hash; Dump_pc( "Setup_pc_entry: after init", %hash ) if $Debug > 3; $value = $Pc_hash->{$real}; Dump_pc( "Setup_pc_entry: pc value for '$real'", %$value ) if $Debug > 3; foreach $key (keys %$value){ print "Setup_pc_entry: setting '$key'='$value->{$key}'\n" if $Debug > 5; $hash{$key} = $value->{$key}; } Dump_pc( "Setup_pc_entry: pr '$name', real '$real'; result", %hash ) if $Debug > 1; return \%hash; } sub FixStrVals( $ \% ) { my($str, $hash ) = @_; my( $key, $val ); while( $str =~ /%(.)/ ){ $key = $1; print "FixStrVals: fixing '$key' in '$str'\n" if $Debug > 5; $val = $hash->{$key}; $val = "" if( not defined $val ); $str =~ s/%$key/$val/g; } print "FixStrVals: final '$str'\n" if $Debug > 5; return $str; } sub Get_printer_name( \% \% \%) { my($args,$pc_index,$config) = @_; my($printer); $printer ||= $args->{'P'}; $printer ||= $pc_index->{'FIRST'}; $printer ||= $config->{'default_printer'}; print "Get_printer_name: '$printer'\n" if $Debug>0; return( $printer ); } # working values my($pc_path,$file); $| = 1; $Debug = 0; # get the command line options die "bad command line options" unless getopts('P:',\%Args); # get the hostname information @Hostname = gethostbyname( hostname() ); print "hostname '" . join( "','", @Hostname ) . "'\n"; # set up the key values $Keyvals{'H'} = $Hostname[0]; Read_conf("/var/tmp/LPD/lpd.conf", %Init_hash); $pc_path = "/etc/printcap"; if( $Init_hash{'printcap_path'} ){ $pc_path = $Init_hash{'printcap_path'}; } foreach $file ( split( '[:,]', $pc_path ) ){ $file = FixStrVals( $file, %Keyvals ); Read_printcap_file($file, %Pc_hash, %Pc_index, 1, 0, @Hostname); } if( $Debug > 0 ){ my($name); Dump_index( "Main:", %Pc_index ); foreach $name (sort keys %Pc_hash){ Dump_pc( "Main:", %{$Pc_hash{$name}} ); } } # get the printer name $Printer = Get_printer_name( %Args, %Pc_index, %Init_hash ); if( not $Printer ){ die "missing printer name"; } $Pc_value = Setup_pc_entry( $Printer, %Pc_hash, %Pc_index, %Init_hash ); print "DONE\n"; exit 0; %Pc_hash=(); %Pc_index=(); Read_printcap_file("/tmp/printcap", %Pc_hash, %Pc_index, 1, 0, @Hostname); print "DONE\n"; lprng-3.8.B/UTILS/decode_args_with_sh.in0000644000131400013140000000420711531672127015023 00000000000000#!@SHELL@ # this is an example of how to use /bin/sh and LPRng # to get the command line and printcap option values # and set shell variables from them # Note that we use a couple of variables #PATH=/bin:/usr/bin Args="" vAr="" vAlue="" vAls="" iI="" Tf="" if -n $Debug ; then set >/tmp/before fi Args="$@" if -n $Debug ; then echo "$@" >>/tmp/before fi while expr "$1" : '-.*' >/dev/null ; do vAr=`expr "$1" : '-\(.\).*'`; vAlue=`expr "$1" : '-.\(.*\)'`; case "$vAr" in - ) break;; c ) c=1;; [a-zA-Z] ) if test "X$vAlue" = "X" ; then shift; vAlue=$1; fi; eval $vAr='$vAlue'; #setvar $vAr "$vAlue" ;; esac; shift; done # set shell variables to the printcap options # flag -> flag=1 # flag@ -> flag=0 # option=value -> option='value' # setpcvals () { while test "$#" -gt 0 ; do iI=$1 if expr "$iI" : " *\:" >/dev/null ; then vAr=`expr "$iI" : " *\:\([^#=][^#=]*\)[#=].*"`; vAlue=`expr "$iI" : " *\:[^#=][^#=]*[#=]\(.*\)"`; if test "X$vAr" = "X" ; then vAr=`expr "$iI" : " *:\(.*\)@"`; vAlue=0; fi if test "X$vAr" = "X" ; then vAr=`expr "$iI" : " *:\(.*\)"`; vAlue=1; fi if test "X$vAr" != "X" ; then eval $vAr='$vAlue'; #setvar $vAr "$vAlue" fi else vAr=`expr "$iI" : " *\([^|][^|]*\).*"`; if test "X$vAr" != "X" ; then eval Printer="$vAr" fi fi; shift done } # set shell variables to the printcap options # flag -> flag=1 # flag@ -> flag=0 # option=value -> option='value' # setcontrolvals () { while test "$#" -gt 0 ; do iI=$1 vAr=`expr "$iI" : " *\([A-Z]\).*"`; vAlue=`expr "$iI" : " *[A-Z]\(.*\)"`; if test "X$vAr" != "X" ; then eval $vAr='$vAlue'; #setvar $vAr "$vAlue"; fi; shift done } Tf=$IFS IFS=" " setpcvals $PRINTCAP_ENTRY setcontrolvals $CONTROL IFS=$Tf # # restore argument list set -- $Args Args="" vAr="" vAlue="" vAls="" iI="" Tf="" if test -n "$Debug" ; then set >/tmp/after echo "$@" >>/tmp/after diff /tmp/before /tmp/after fi cat exit 0 lprng-3.8.B/UTILS/linetest.c0000644000131400013140000000522311531672127012501 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-1995 Patrick Powell, San Diego State University * papowell@sdsu.edu * See LICENSE for conditions of use. * *************************************************************************** * MODULE: linetest.c * PURPOSE: print a rolling banner pattern **************************************************************************/ /* * linetest: print the rolling banner pattern * linetest [width] * Sat Jun 18 09:47:06 CDT 1988 Patrick Powell * linetest.c,v * Revision 3.1 1996/12/28 21:40:52 papowell * Update * * Revision 3.1 1996/12/28 21:32:47 papowell * Update * * Revision 1.1 1996/12/28 21:07:15 papowell * Update * * Revision 4.1 1996/11/05 06:38:20 papowell * Update * * Revision 3.0 1996/05/19 04:06:49 papowell * Update * * Revision 3.0 1996/05/19 04:06:49 papowell * Update * * Revision 2.7 1996/05/13 03:26:13 papowell * Update * * Revision 2.7 1996/05/13 03:26:13 papowell * Update * * Revision 2.6 1996/03/03 22:31:37 papowell * Update * * Revision 2.6 1996/03/03 22:31:37 papowell * Update * * Revision 2.5 1995/12/03 02:52:29 papowell * Update * * Revision 2.5 1995/12/03 02:52:29 papowell * Update * * Revision 2.4 1995/11/22 14:58:52 papowell * Update * * Revision 2.4 1995/11/22 14:58:52 papowell * Update * * Revision 2.3 1995/11/08 14:28:25 papowell * Update * * Revision 2.3 1995/11/08 14:28:25 papowell * Update * * Revision 2.2 1995/11/06 01:38:35 papowell * Update * * Revision 2.2 1995/11/06 01:38:35 papowell * Update * * Revision 2.1 1995/11/05 01:27:39 papowell * Update * * Revision 2.1 1995/11/05 01:27:39 papowell * Update * * Revision 2.0 1995/11/04 06:29:04 papowell * *** empty log message *** * * Revision 2.0 1995/11/04 06:29:04 papowell * *** empty log message *** * * Revision 2.0 1995/11/04 06:28:06 papowell * *** empty log message *** * * */ #include #include static char id_str1[] = "linetest.c,v 3.1 1996/12/28 21:40:52 papowell Exp PLP Copyright 1988 Patrick Powell"; char *Name; main(argc, argv) int argc; char **argv; { int width = 132; int i,j; Name = argv[0]; if( argc > 2 || argc < 1 ){ usage(); } if( argc == 2 ){ i = atoi( argv[1] ); if( i != 0 ){ width = i; } else { usage(); } } i = ' '; while(1){ for( j = 0; j < width; ++j ){ if( !isprint(i) || isspace(i) ){ i = ' '+1; } putchar( i ); i = i + 1; } putchar( '\n' ); } } usage() { fprintf( stderr, "%s [width]\n", Name ); exit( 0 ); } lprng-3.8.B/UTILS/decode_args_with_perl.in0000644000131400013140000000203011531672127015343 00000000000000#!@PERL eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) use Getopt::Std; my(%args,%options); # get the arguments getopts( "a:b:cd:e:f:g:h:i:j:l:m:n:o:p:q:r:s:t:u:v:w:x:y:z:" . "A:B:C:D:E:F:G:H:I:J:L:M:N:O:P:Q:R:S:T:U:V:W:X:Y:Z:", \%args ); # Now handle options # set :key=value -> $option{$key}=$value # set :key@ -> $option{$key}="0" # set :key -> $option{$key}="1" map { if( m/^\s*:([^=]+)=(.*)/ ){ $options{$1}=$2; } elsif( m/^\s*:([^=]+)\@$/ ){ $options{$1}="0"; } elsif( m/^\s*:([^=]+)/ ){ $options{$1}="1"; } elsif( m/^\s*([^|]+)/ ){ $options{"Printer"}=$1; } } split( "\n", $ENV{'PRINTCAP_ENTRY'}); # get the control file entries map { if( m/^\s*([A-Z])(.*)/ ){ $options{$1}=$2; } elsif( m/^\s*([a-z])/ ){ $options{'Format'}=$1; } } split( "\n", $ENV{'CONTROL'}); for (keys %options){ print "option $_='$options{$_}'\n"; } while( <> ){ print; } lprng-3.8.B/UTILS/test_read.in0000644000131400013140000000112011531672127013000 00000000000000#!@PERL@ package test_read; use strict; use LPRng; use Sys::Hostname; # working values my($pc_path,$file,$Printer,$key,$value,$Pc_value); $| = 1; Set_Debug(5); Setup_LPRng( "P:"); # get the printer name $Printer = Get_printer_name(); if( not $Printer ){ die "missing printer name"; } print "Printer '$Printer'\n"; $Pc_value = Setup_pc_entry( $Printer ); if( not defined $Pc_value ){ print "no printcap information for printer '$Printer'\n"; exit 1; } print "Printcap '$Printer'\n"; foreach $key (sort keys %$Pc_value ){ print " '$key'='$Pc_value->{$key}'\n"; } print "DONE\n"; exit 0; lprng-3.8.B/UTILS/xlate.c0000644000131400013140000001131111531672127011762 00000000000000/*************************************************************************** * LPRng - An Extended Print Spooler System * * Copyright 1988-1995 Patrick Powell, San Diego State University * papowell@sdsu.edu * See LICENSE for conditions of use. * *************************************************************************** * MODULE: xlate.c * PURPOSE: translate the FC, FS, SX, XS fields * * xlate ":fc#0000374:fs#0000003:xc#0:xs#0040040:" * - makes best guesses about the various fields **************************************************************************/ #include #include static char _id[] = "xlate.c,v 3.1 1996/12/28 21:40:53 papowell Exp"; struct bits{ char *name; int bitfields; char *comment; char *try; int mask; }; /* f flags - used with the TIOCGET and the struct sgttyb.sg_flags field */ struct bits tiocget[] = { { "TANDEM",00000001, "send stopc on out q full", "tandem" }, { "CBREAK",00000002, "half-cooked mode", "cbreak" }, { "LCASE",00000004, "simulate lower case", "lcase" }, { "ECHO",00000010, "echo input", "echo" }, { "CRMOD",00000020, "map \\r to \\r\\n on output", "crmod" }, { "RAW",00000040, "no i/o processing", "raw" }, { "ODDP",00000100, "get/send odd parity", "oddp" }, { "EVENP",00000200, "get/send even parity", "evenp" }, { "ANYP",00000300, "get any parity/send none", "parity? anyp? pass8? (caution)" }, { "NL0",0000000, "new line delay", "nl??",00001400 }, { "NL1",00000400, "new line delay tty 37", "nl??",00001400 }, { "NL2",00001000, "new line delay vt05", "nl??",00001400 }, { "NL3",00001400, "new line delay", "nl??",00001400 }, { "TAB0",00000000, "tab expansion delay", "tab??",00006000 }, { "TAB1",00002000, "tab expansion delay tty 37", "tab??",00006000 }, { "TAB2",00004000, "tab expansion delay", "tab??",00006000 }, { "XTABS",00006000, "expand tabs on output", "tabs" }, { "CR0",00000000, "cr??", "",00030000 }, { "CR1",00010000, "tn 300", "cr??",00030000 }, { "CR2",00020000, "tty 37", "cr??",00030000 }, { "CR3",00030000, "concept 100", "cr??",00030000}, { "FF1",00040000, "form feed delay tty 37", "ff??" }, { "BS1",0010000, "backspace timing", "bs??" }, { 0 } }; /* x flags - used with the TIOCLGET and the struct sgttyb.sg_flags field */ struct bits tiolget[] = { { "CRTBS",00000001, "do backspacing for crt", "crterase" }, { "PRTERA",00000002, "\\ ... / erase", "prterase" }, { "CRTERA",00000004, "\"\\b\" to wipe out char", "crterase" }, { "TILDE",00000010, "hazeltine tilde kludge", "don't even think about this" }, { "MDMBUF",00000020, "start/stop output on carrier intr", "crtscts" }, { "LITOUT",00000040, "literal output", "litout" }, { "TOSTOP",00000100, "SIGSTOP on background output", "tostop" }, { "FLUSHO",00000200, "flush output to terminal", "noflsh?? (caution)" }, { "NOHANG",00000400, "no SIGHUP on carrier drop", "nohand" }, { "CRTKIL",00002000, "kill line with \"\\b\"", "crtkill" }, { "PASS8",00004000, "pass 8 bits", "pass8" }, { "CTLECH",00010000, "echo control chars as ^X", "echok" }, { "PENDIN",00020000, "tp->t_rawq needs reread", "don't even think about this" }, { "DECCTQ",00040000, "only ^Q starts after ^S", "decctlq? -ixany? (caution)" }, { "NOFLSH",00100000, "no output flush on signal", "noflsh" }, { 0 } }; char *msg[] = { "xlate optionstrings", " Example", " xlate \":fc#0000374:fs#0000003:xc#0:xs#0040040:\"", 0 }; usage() { char **m; for( m = msg; *m; ++m ){ fprintf( stderr, "%s\n", *m ); } exit( 1 ); } main( argc, argv ) int argc; char *argv[]; { char *s, *end; char *value; int c, v, set; struct bits *table; if( argc != 2 ) usage(); for( s = argv[1]; s && *s; s = end ){ end = strchr( s, ':' ); if( end ){ *end++ = 0; } while( (c = *s) && isspace( c ) ) ++s; if( c == 0 ) continue; /* now translate option */ value = strchr( s, '#' ); if( value == 0 ) usage(); *value++ = 0; v = strtol( value, (char **)0, 0 ); printf( "%s = %o\n", s, v); switch( s[0] ){ case 'f': table = tiocget; break; case 'x': table = tiolget; break; default: usage(); } switch( s[1] ){ case 's': set = 1; break; case 'c': set = 0; break; default: usage(); } /* now we scan down the values */ for(; table->name; ++table ){ if( (table->bitfields & v) && ( ((table->bitfields & v) ^ table->bitfields) & (table->mask?table->mask:~0) ) == 0 ){ printf( " %s %s (%s) try '%s%s'\n", set?"set":"clear", table->name, table->comment, set? "":"-", table->try ); } } } } lprng-3.8.B/UTILS/one.pcl0000644000131400013140000000007711531672127011771 00000000000000E&u600D&l2A&l0O&l0E(0N(s1p0s0b4101T(s24V*p655x942Y1 Elprng-3.8.B/UTILS/Makefile.am0000644000131400013140000000124211531672127012537 00000000000000MAINTAINERCLEANFILES = Makefile.in CONFIGURE_GENERATED_FILES = LPRng.pm accounting.pl decode_args_with_perl decode_args_with_sh fixid fixupdate lpq_in_perl lpr_in_perl lprm_in_perl make_lpd_conf make_printcap_use makeinc read_conf remote_active test_read update_z.pl DISTCLEANFILES = $(CONFIGURE_GENERATED_FILES) EXTRA_DIST = $(patsubst %,%.in,$(CONFIGURE_GENERATED_FILES)) $(UNCHECKEDSTUFF) # TODO: decide which to include, which to remove: UNCHECKEDSTUFF = atalkprint chooser.in extract_pjl freefs.c linetest.c ncpprint one.pcl one.pjl ps.draft README.ForKerberosHackers set_file_time.c smbprint tcpsend.c termcap.c testpr test_rw_pipe.c VeryFlexibleChooser.pl xlate.c lprng-3.8.B/UTILS/README.ForKerberosHackers0000644000131400013140000001226611531672127015116 00000000000000# KERBEROS 5 and the Horror! Oh, the Horror! # # Patrick ("Don't go there... or carry a lute and sing very softly") Powell # # OK, if you are reading this, you are tough enough to take it. # # Get the latest version of kerberos # # http://web.mit.edu/kerberos/www/ # and follow links. # # Compile/Install kerberos # - this is for 1.2.4, but should be same # # tar xf krb5-1.2.4.tar # -- unpacks the dist and you get signature + dist # tar zxf krb5-1.2.4.tar.gz # cd krb5-1.2.4 # # --- the README # more README -- for latest dope, if any # # --- the documents # gv doc/install-guide.ps -- the real stuff # gv doc/admin-guide.ps # gv doc/user-guide.ps # # ---- but since you have not read them, you will need to know: # a) your realm (I use 'LPRNG.COM') # b) the secret password for the key distribution server # - write this down... :-) # c) a ready source of asprin or ibuprofin # # ----- # USE GMAKE repeat GNU Make!!! # # cd src # ./configure # gmake (and a LOOONG pause. Coffee time) # gmake check (and an even longer pause) # # su # gmake install # # ---------- # # --- here is the default /etc/krb5.conf file: # # [libdefaults] # ticket_lifetime = 600 # default_realm = ATHENA.MIT.EDU # default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc # default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc # # [realms] # ATHENA.MIT.EDU = { # kdc = kerberos.mit.edu:88 # kdc = kerberos-1.mit.edu:88 # kdc = kerberos-2.mit.edu:88 # admin_server = kerberos.mit.edu:749 # default_domain = mit.edu # } # # [domain_realm] # .mit.edu = ATHENA.MIT.EDU # mit.edu = ATHENA.MIT.EDU # # [logging] # kdc = FILE:/var/log/krb5kdc.log # admin_server = FILE:/var/log/kadmin.log # default = FILE:/var/log/krb5lib.log # ---- after editting: # # [libdefaults] # ticket_lifetime = 600 # default_realm = ASTART.COM # default_tkt_enctypes = des3-hmac-sha1 des-cbc-crc # default_tgs_enctypes = des3-hmac-sha1 des-cbc-crc # # [realms] # ASTART.COM = { # kdc = h110.private:88 # admin_server = h110.private:749 # default_domain = private # } # # [domain_realm] # .private = ASTART.COM # private = ASTART.COM # .astart.com = ASTART.COM # astart.com = ASTART.COM # # [logging] # kdc = FILE:/var/log/krb5kdc.log # admin_server = FILE:/var/log/kadmin.log # default = FILE:/var/log/krb5lib.log # # --------------- default /usr/local/var/krb5kdc/kdc.conf # # [kdcdefaults] # kdc_ports = 88,750 # # [realms] # ATHENA.MIT.EDU = { # database_name = /usr/local/var/krb5kdc/principal # admin_keytab = /usr/local/var/krb5kdc/kadm5.keytab # acl_file = /usr/local/var/krb5kdc/kadm5.acl # dict_file = /usr/local/var/krb5kdc/kadm5.dict # key_stash_file = /usr/local/var/krb5kdc/.k5.ATHENA.MIT.EDU # kadmind_port = 749 # max_life = 10h 0m 0s # max_renewable_life = 7d 0h 0m 0s # master_key_type = des3-hmac-sha1 # supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal # } # # To add Kerberos V4 support, add `des-cbc-crc:v4' to the # `supported_enctypes' line. # # -------------- after editting it: # # [kdcdefaults] # kdc_ports = 88,750 # # [realms] # ASTART.COM = { # database_name = /usr/local/var/krb5kdc/principal # admin_keytab = /usr/local/var/krb5kdc/kadm5.keytab # acl_file = /usr/local/var/krb5kdc/kadm5.acl # dict_file = /usr/local/var/krb5kdc/kadm5.dict # key_stash_file = /usr/local/var/krb5kdc/.k5.ASTART.COM # kadmind_port = 749 # max_life = 10h 0m 0s # max_renewable_life = 7d 0h 0m 0s # master_key_type = des3-hmac-sha1 # supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal des-cbc-crc:v4 # } # # -------- now create database: # echo "create database" kdb5_util create -r ASTART.COM -s # (you will need the password) # # ------- create ACL # echo "creating acl" echo "*/admin@ASTART.COM *" >/usr/local/var/krb5kdc/kadm5.acl # -- now run kadmin: # echo " Add principle commands. Change papowell and host h110.private to the apprpriate ones for your site: addprinc admin/admin@ASTART.COM addprinc papowell/admin@ASTART.COM addprinc papowell --- for the host addprinc -randkey host/h110.private --- for kadmin to use ktadd host/h110.private --- this is for the printer addprinc -randkey lpd/h110.private ktadd -k /etc/lpd.h110.private lpd/h110.private ktadd -k /usr/local/var/krb5kdc/kadm5.keytab kadmin/admin kadmin/changepw quit " kadmin.local cp /etc/lpd.h110.private /etc/lpd.krb # change the perms on /etc/lpr.krb5 # cp /etc/lpr.krb5 /etc/lpr.krb5.public # chown papowell /etc/lpr.krb5.public ############ echo "start servers" krb5kdc cat /var/log/krb5kdc.log kadmind cat /var/log/kadmind.log ############ # # Here is the printcap # # lp # :auth=kerberos5 # :kerberos_id=lpd/h110.private # :kerberos_keytab=/etc/lpd.krb # :lp=/dev/null # :sd=/var/spool/lpd # # set this up, and then do: # checkpc -f # kinit (you may have to specify a principle) # lpq # Enjoy # lprng-3.8.B/UTILS/README0000644000131400013140000000207011531672127011363 00000000000000Utilities for LPRng README - this file Makefile - does various operations accounting.pl - accounting script in Perl See the documentation in the script. You should use this as follows: printcap: :af=accnt :as=|/.../accounting.pl start :ae=|/.../accounting.pl end lpr_in_perl, lpq_in_porl - perl scripts to do really simple LPQ, LPR simulation. Can also be extended to lprm, lpc, etc. remote_active: script to do checking for a remote active printer linetest.c - test a serial line make_lpd_conf - makes the sample lpd.conf file from the src/vars.c file makeinc - makes the various dependencies. Used by 'make depend' test_rw_pipe.c - tests read-write pipe support xlate.c - translates xf,xc,... printcap to sy format update_z - control file filter that updates the Z options according to the queue name. Replacement for apsfilter, when used with the wildcard queue name matching. Example: pr|pr_*:lp=%P@server pr|pr_* :incoming_control_filter=/.../update_z :filter=/.../ifhp :sd=/var/spool/lpd/%P :lp=.... lprng-3.8.B/UTILS/chooser.in0000755000131400013140000000343311531672127012504 00000000000000#!@PERL@ use Getopt::Std; my $debug = 1; # always... sigh... my(%opt, @pc, %options); exit 1; # get command line options getopts( 'A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:T:S:U:V:W:X:Y:Z:' . 'a:b:cd:e:f:g:h:i:j:k:l:m:n:o:p:q:r:t:s:u:v:w:x:y:z:', \%opt ); while( @ARGV ){ $opt{acct} = pop @ARGV ; }; # split up the PRINTCAP_ENTRY environment variable value @pc = split /\n\s*:/s, ($ENV{PRINTCAP_ENTRY} || ""); shift @pc; # throw way first entry field, printer name # set the options foreach (@pc){ # set the options values if( /^(.+)=(.*)/ ){ $options{$1} = $2; } elsif ( /^(.+)@/ ){ $options{$1} = 0; } else { $options{$_} = 1; } } if( $debug ){ # for those interested my $s = ""; foreach my $v (sort keys %options ){ $s .= "$v='$options{$v}',"; } print STDERR "Printcap: '$s'\n"; $s=""; foreach my $v (sort keys %opt){ $s .= "$v='$opt{$v}',"; } print STDERR "Args: '$s'\n"; } my (@list, @destinations); if( $options{sv} ){ # if we have :sv then we read them from STDIN while( ){ chomp; push @destinations, $_; } } else { # else we use the 'destinations' printcap value @list = split /[,\s]+/, ($options{destinations} || ""); # and we randomize - this is a bit of perl magic while( @list ){ push @destinations, splice( @list,rand(@list),1); } } # and we split the destinations up... print STDERR "Destinations '@destinations'\n";# if $debug; # and now we search my $lpq="/usr/bin/lpq"; foreach ( @destinations ){ my $status = ""; # run lpq eval { alarm(10); $status = `$lpq -s -P$_`; }; alarm(0); chomp $status; print STDERR "STATUS '$_' $status\n" if $debug;; # we discard the various queues # this has to be configured on an individual basis next if( $status =~ /disabled/ or $status != / 0 jobs/ ); print STDERR "chose '$_' from @destinations\n"; print $_; last; } exit 0 lprng-3.8.B/UTILS/lprm_in_perl.in0000644000131400013140000000232711531672127013522 00000000000000#!@PERL@ eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) use strict; use English; use Socket; use LPRng; use Sys::Hostname; use Getopt::Std; my( $Printer, $Pc_value, $Debug, $pr, $remote, $port, $option, $options, $SOCK, $line, $prefix, $firstpart, $count, $username, %Args ); $| = 1; $Debug = 0; Set_Debug($Debug); getopts( "P:", \%Args ); Setup_LPRng( %Args ); # get the printer name $Printer = Get_printer_name(%Args); if( not $Printer ){ die "missing printer name"; } print "Printer '$Printer'\n" if $Debug; $Pc_value = Setup_pc_entry( $Printer ); ($pr, $remote, $port ) = Get_remote_pr_host( $Printer, $Pc_value ); print "pr '$pr', remote '$remote', port '$port'\n" if $Debug; $option = 5; $username = getpwuid($UID); $SOCK = getconnection( $remote, $port ); $options = join (" ", @ARGV); printf "%d%s %s%s\n", $option, $pr, $username, $options ? (" " . $options) : "" if $Debug; printf $SOCK "%c%s %s%s\n", $option, $pr, $username, $options ? (" " . $options) : ""; $prefix = ""; while ( defined( $line = <$SOCK> ) ) { print $line; } close ($SOCK) or die "close: $!"; exit 0; lprng-3.8.B/UTILS/lpr_in_perl.in0000644000131400013140000000474411531672127013352 00000000000000#!@PERL@ eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) use strict; use English; use Socket; use LPRng; use Getopt::Std; use Sys::Hostname; my($Printer, $Pc_value, $Debug ); my($pr, $remote, $port, @files, $file, $f, $hostname, $username); my($cf, $df, $idn, $cfn, @dfn, $fn, $filecount, $i, $v, $SOCK, $sendcf,%Args); my($options) = "Z:O:"; $| = 1; $Debug = 0; Set_Debug($Debug); getopts( $options . "P:", \%Args ); Setup_LPRng( %Args ); # get the printer name $Printer = Get_printer_name( %Args ); if( not $Printer ){ die "missing printer name"; } print "Printer '$Printer'\n" if $Debug; $Pc_value = Setup_pc_entry( $Printer ); ($pr, $remote, $port ) = Get_remote_pr_host( $Printer, $Pc_value ); print "pr '$pr', remote '$remote', port '$port'\n" if $Debug; if( !(@files = @ARGV) ){ $f = "/tmp/lpr$$"; @files = $f; open TEMP, ">$f" or die "cannot open $f - $!\n"; while( defined( $i = <> ) ){ print TEMP $i or die "cannot write $f - $!\n"; } close TEMP or die "cannot close $f - $!\n"; } print "files " . join(",",@files) . "\n" if $Debug; $hostname = hostname(); $username = getpwuid($UID); $cf = "H$hostname\n" . "P$pr\n" . "L$username\n" ; foreach $i ( split //, $options ){ print "option $i\n" if $Debug; $v = $Args{$i}; if( $i ne ":" and $v ){ print "option $i='$v'\n" if $Debug; $cf .= "$i$v\n"; } } $idn = $$ % 100; $cfn = sprintf( "cfA%03d%s", $idn, $hostname ); print "cfn='$cfn'\n" if $Debug; $fn = "A"; $filecount = 0; for( $i = 0; $i < @files; ++$i ){ $file = $files[$i]; if( ! -f $file || ! -r _ || ! -s _ ){ print "not a readable, nonzero length file - $file\n"; } else { $df = sprintf( "df%s%03d%s", $fn, $idn, $hostname ); $dfn[$i] = $df; $cf .= "N$file\n" . "f$df\n" . "U$df\n"; ++$filecount; ++$fn; if( $filecount == 26 ){ $fn = "a"; } } } if( $filecount > 52 ){ print STDERR "too many files\n"; exit 2; } if( $filecount == 0 ){ print "nothing to print\n"; exit( 1 ); } if( $Debug ){ print "cf contents = '$cf'\n"; print "cf len " . length( $cf ) . "\n"; } $SOCK = getconnection( $remote, $port ); sendit( $SOCK, sprintf( "\002%s\n", $pr ));; $sendcf = "\002" . length( $cf ) . " $cfn\n"; sendbuffer( $SOCK, $sendcf, $cf ); print "sending files '@files'\n" if $Debug; for( $i = 0; $i < @files; ++$i ){ if( $dfn[$i] ){ sendfile( $SOCK, $dfn[$i], $files[$i] ); } } close ($SOCK) or die "close: $!"; exit 0; lprng-3.8.B/UTILS/fixupdate.in0000644000131400013140000000231311531672127013024 00000000000000#!@PERL@ use strict; for (@ARGV){ my($hfile,$cfile,$s,$t,$h); #print "arg '$_'\n"; $hfile = $_; ($cfile = $hfile) =~ s/.*\///; $cfile =~ s/\.h$/.c/; if( not -f $cfile ){ my @files = glob( "*/$cfile" ); if( @files > 1 ){ warn "too many matching sourc3 files - @files\n"; exit 1; } if( @files == 0 ){ warn "no matching source files\n"; next; } $cfile = $files[0]; } #print "cfile '$cfile', hfile '$hfile'\n"; if( !open( CFILE, "<$cfile") ){ warn "cannot open '$cfile'"; next; } while () { chomp; # strip record separator if (/^[A-Za-z]/ .. /^{/) { chomp; if( /{/ ){ $s .= ";\n"; $t .= $s; $s = ""; } elsif( $s ){ $s .= "\n" . $_; } else { $s = $_; } } if (/VARARGS[0-9]/ .. /^{/) { chomp; if( /{/ ){ $s .= "\n;\n"; $t .= $s; $s = ""; } elsif( $s ){ $s .= "\n" . $_; } else { $s = $_; } } } close CFILE ; $t .= "\n#endif\n"; #print $t; open( HFILE, "<$hfile") or die "cannot open '$hfile'"; while( ){ $h .= $_; if( /PROTOTYPE/ ) { $h .= $t; last; } } # print $h; `cp $hfile $hfile.bak`; open( HFILE,">$hfile") or die "cannot open '$hfile'"; print HFILE $h; close HFILE; } lprng-3.8.B/UTILS/Makefile.in0000644000131400013140000003075411531672272012563 00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = UTILS DIST_COMMON = README $(srcdir)/LPRng.pm.in $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/accounting.pl.in \ $(srcdir)/decode_args_with_perl.in \ $(srcdir)/decode_args_with_sh.in $(srcdir)/fixid.in \ $(srcdir)/fixupdate.in $(srcdir)/lpq_in_perl.in \ $(srcdir)/lpr_in_perl.in $(srcdir)/lprm_in_perl.in \ $(srcdir)/make_lpd_conf.in $(srcdir)/make_printcap_use.in \ $(srcdir)/makeinc.in $(srcdir)/read_conf.in \ $(srcdir)/remote_active.in $(srcdir)/test_read.in \ $(srcdir)/update_z.pl.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LPRng.pm accounting.pl decode_args_with_perl \ decode_args_with_sh fixid fixupdate lpq_in_perl lpr_in_perl \ lprm_in_perl make_lpd_conf make_printcap_use makeinc read_conf \ remote_active test_read update_z.pl SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHGRP = @CHGRP@ CHOWN = @CHOWN@ CLEAR = @CLEAR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_LIBS = @DL_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FILTER_LD_PATH = @FILTER_LD_PATH@ FILTER_PATH = @FILTER_PATH@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ INCLUDELPDCONFLOCAL = @INCLUDELPDCONFLOCAL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_MAN = @INSTALL_MAN@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KERBEROS = @KERBEROS@ KRB5CONFIG = @KRB5CONFIG@ KRB_LIBS = @KRB_LIBS@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCKFILE = @LOCKFILE@ LPD_CONF_PATH = @LPD_CONF_PATH@ LPD_LISTEN_PORT = @LPD_LISTEN_PORT@ LPD_PERMS_PATH = @LPD_PERMS_PATH@ LPD_PRINTCAP_PATH = @LPD_PRINTCAP_PATH@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NOREMOTE = @NOREMOTE@ OBJEXT = @OBJEXT@ OPENSSL = @OPENSSL@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PLUGINUSER_LDFLAGS = @PLUGINUSER_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PRINTCAP_PATH = @PRINTCAP_PATH@ PRIV_PORTS = @PRIV_PORTS@ PRUTIL = @PRUTIL@ SD_DEFAULT = @SD_DEFAULT@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSL_CA_FILE = @SSL_CA_FILE@ SSL_CA_KEY = @SSL_CA_KEY@ SSL_CERTS_DIR = @SSL_CERTS_DIR@ SSL_CRL_FILE = @SSL_CRL_FILE@ SSL_LDADD = @SSL_LDADD@ SSL_SERVER_CERT = @SSL_SERVER_CERT@ SSL_SERVER_PASSWORD_FILE = @SSL_SERVER_PASSWORD_FILE@ STRIP = @STRIP@ UNIXSOCKETPATH = @UNIXSOCKETPATH@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ filterdir = @filterdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lpdbindir = @lpdbindir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in CONFIGURE_GENERATED_FILES = LPRng.pm accounting.pl decode_args_with_perl decode_args_with_sh fixid fixupdate lpq_in_perl lpr_in_perl lprm_in_perl make_lpd_conf make_printcap_use makeinc read_conf remote_active test_read update_z.pl DISTCLEANFILES = $(CONFIGURE_GENERATED_FILES) EXTRA_DIST = $(patsubst %,%.in,$(CONFIGURE_GENERATED_FILES)) $(UNCHECKEDSTUFF) # TODO: decide which to include, which to remove: UNCHECKEDSTUFF = atalkprint chooser.in extract_pjl freefs.c linetest.c ncpprint one.pcl one.pjl ps.draft README.ForKerberosHackers set_file_time.c smbprint tcpsend.c termcap.c testpr test_rw_pipe.c VeryFlexibleChooser.pl xlate.c all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign UTILS/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign UTILS/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh LPRng.pm: $(top_builddir)/config.status $(srcdir)/LPRng.pm.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ accounting.pl: $(top_builddir)/config.status $(srcdir)/accounting.pl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ decode_args_with_perl: $(top_builddir)/config.status $(srcdir)/decode_args_with_perl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ decode_args_with_sh: $(top_builddir)/config.status $(srcdir)/decode_args_with_sh.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fixid: $(top_builddir)/config.status $(srcdir)/fixid.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ fixupdate: $(top_builddir)/config.status $(srcdir)/fixupdate.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lpq_in_perl: $(top_builddir)/config.status $(srcdir)/lpq_in_perl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lpr_in_perl: $(top_builddir)/config.status $(srcdir)/lpr_in_perl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ lprm_in_perl: $(top_builddir)/config.status $(srcdir)/lprm_in_perl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ make_lpd_conf: $(top_builddir)/config.status $(srcdir)/make_lpd_conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ make_printcap_use: $(top_builddir)/config.status $(srcdir)/make_printcap_use.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ makeinc: $(top_builddir)/config.status $(srcdir)/makeinc.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ read_conf: $(top_builddir)/config.status $(srcdir)/read_conf.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ remote_active: $(top_builddir)/config.status $(srcdir)/remote_active.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ test_read: $(top_builddir)/config.status $(srcdir)/test_read.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ update_z.pl: $(top_builddir)/config.status $(srcdir)/update_z.pl.in cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lprng-3.8.B/UTILS/VeryFlexibleChooser.pl0000644000131400013140000000726311531672127014774 00000000000000 #!/usr/local/bin/perl =head POSTING From lprng@www.lprng.com Thu Nov 27 10:16:08 2003 Date: Thu, 27 Nov 2003 17:54:01 +0100 (CET) From: Henrik Edlund To: lprng@lprng.com Subject: LPRng: Chooser script using SNMP I hereby release the following Chooser script into the public domain on 27 November 2003. The following Chooser script uses SNMP to check printer status, and then uses the status information to in a smart way select the _most_ available printer. A printer without toner/paper warnings is always chosen over one with toner/paper warnings. Within each of those groups; an idle printer is chosen first, then a standby printer (after idle because it takes time for it to warm up), then a printing printer, and last a warming up printer (after printing as it has most likely received a print job and given the guess that each print job is of equal size, a printing printer will be done before a printer in warm up). This script is known to fully work with the Xerox Phaser 4400 and the Xerox DocuPrint N32. Your mileage may vary with printers from other manufacturers. Yours, Henrik PS. There are "spies" from Xerox on this list; so *wink* *wink* to the fellas over at Xerox. =cut # Released into the Public Domain by Henrik Edlund # 27 November 2003 # This program 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. use strict; use warnings; use Net::SNMP; my $printers; my $exit_job_fail = 1; my $printer; my $priority; my $session; my $error; my $result; my $snmp_hr_device_status = '1.3.6.1.2.1.25.3.2.1.5.1'; my $snmp_hr_printer_status = '1.3.6.1.2.1.25.3.5.1.1.1'; my @printers = ([], [], [], [], [], [], [], []); my $exit_job_success = 0; # get printers from STDIN $printers = ; if (not(defined($printers))) { # no printers given, try again in a while exit($exit_job_fail); } chomp($printers); foreach $printer (split(/,/, $printers)) { $priority = -1; # talk SNMP to printer ($session, $error) = Net::SNMP->session(-hostname => $printer); if (defined($session)) { # fetch hrDeviceStatus and hrPrinterStatus $result = $session->get_request(-varbindlist => [$snmp_hr_device_status, $snmp_hr_printer_status]); # check status of printer and assign priority if (defined($result)) { if ($result->{$snmp_hr_device_status} == 2) { # running if ($result->{$snmp_hr_printer_status} == 3) { # idle $priority = 0; } elsif ($result->{$snmp_hr_printer_status} == 1) { # standby $priority = 1; } elsif ($result->{$snmp_hr_printer_status} == 4) { # printing $priority = 2; } elsif ($result->{$snmp_hr_printer_status} == 5) { # warmup $priority = 3; } } elsif ($result->{$snmp_hr_device_status} == 3) { # warning if ($result->{$snmp_hr_printer_status} == 3) { # idle $priority = 4; } elsif ($result->{$snmp_hr_printer_status} == 1) { # standby $priority = 5; } elsif ($result->{$snmp_hr_printer_status} == 4) { # printing $priority = 6; } elsif ($result->{$snmp_hr_printer_status} == 5) { # warmup $priority = 7; } } if ($priority != -1) { push(@{$printers[$priority]}, $printer); } } # close the udp transport layer to printer $session->close(); } } # of those available with highest priority; pick a random one foreach $priority (@printers) { $printers = scalar(@$priority); if ($printers > 0) { # success, found available printer print "$priority->[rand($printers)]\n"; exit($exit_job_success); } } # no printers available right now, try again in a while exit($exit_job_fail); lprng-3.8.B/UTILS/update_z.pl.in0000644000131400013140000000424411531672127013265 00000000000000#!@PERL@ eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) use Getopt::Std; my $debug = 0; # always... sigh... my(%opt, @pc, %options); # get command line options getopts( 'A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:T:S:U:V:W:X:Y:Z:' . 'a:b:cd:e:f:g:h:i:j:k:l:m:n:o:p:q:r:t:s:u:v:w:x:y:z:', \%opt ); while( @ARGV ){ $opt{acct} = pop @ARGV ; }; # split up the PRINTCAP_ENTRY environment variable value @pc = split /\n\s*:/s, ($ENV{PRINTCAP_ENTRY} || ""); shift @pc; # throw way first entry field, printer name # set the options foreach (@pc){ # set the options values if( /^(.+)=(.*)/ ){ $options{$1} = $2; } elsif ( /^(.+)@/ ){ $options{$1} = 0; } else { $options{$_} = 1; } } if( $debug ){ # for those interested $s=""; foreach my $v (sort keys %ENV){ $s .= "$v='$ENV{$v}',"; } print STDERR "ENV: '$s'\n"; my $s = ""; foreach my $v (sort keys %options ){ $s .= "$v='$options{$v}',"; } print STDERR "Printcap: '$s'\n"; #$s=""; #foreach my $v (sort keys %opt){ $s .= "$v='$opt{$v}',"; } #print STDERR "Args: '$s'\n"; } # read stdin my( $file, $Zopts, $Q ); $file = join "", ; print STDERR "File '$file'\n" if $debug; $Zopts = ""; # first use command line Queue name $Q = $opt{Q}; ($Q) = $file =~ /^Q(.*)$/m if not $Q; # if no queue name fall back to printer name $Q = $opt{P} if not $Q; ($Q) = $file =~ /^P(.*)$/m if not $Q; $Q = "" if not $Q; ($Zopts) = $file =~ /^Z(.*)$/m; $Zopts = "" if not $Zopts; print STDERR "Q '$Q', Zopts '$Zopts'\n" if $debug; # now we split up the name and use as parameters for Z options while( $Q =~ /_([^_]+)/g ){ # you can simply append them: $Zopts .= ",$1"; # or you can test and then append translated format # if( $1 eq "11" ){ $Zopts .= ",legal"; } # elsif( $1 eq "15" ){ $Zopts .= ",ledger"; } # #if( $1 eq "landscape" # or $1 eq "legal" # or $1 eq "ledger" ){ # $Zopts .= ",$1" #} } print "Final '$Zopts'\n" if $debug; if( $Zopts ){ # remove leading comma $Zopts =~ s/^,//; #replace or prefix Z options $file = "Z$Zopts\n" . $file if( not ($file =~ s/^Z.*$/Z$Zopts/m)); } print $file; exit 0 lprng-3.8.B/UTILS/testpr0000755000131400013140000000156111531672127011756 00000000000000#!/usr/local/bin/bash # # use: testpr [last job number [first job number]] # testpr script # # Throughput and lost file test script # # Set up a print queue with: # lp:sd=/tmp/lpd/%P # :filter=/tmp/testfilter # :lp=/dev/null # # /tmp/testfilter: # #!/bin/sh # # The filter will create files in /tmp/files with the name # # corresponding to the first word in file # if [ ! -d /tmp/files ] ; then mkdir /tmp/files ; fi # read var # var=`echo $var | sed -e 's,.*/,,'` # date >/tmp/files/$var # # now do: # # chmod a+x /tmp/testfilter # run checkpc # # Send jobs using: # bash testpr (10 jobs) # bash testpr 100 (100 jobs) # bash testpr 200 100 (100, starting at id 100 jobs) P=-Pp set -x lprm $P all d=/tmp/files if [ ! -d $d ] ; then mkdir -p $d; fi chmod 777 $d; (cd $d; rm -f *;) for((i=${2:-0}; i < ${1:-10}; ++i)) ; do echo $i |lpr $P ; done; lprng-3.8.B/UTILS/LPRng.pm.in0000644000131400013140000004471211531672127012441 00000000000000#!@PERL@ # read the lpd.conf file, and set up values from it package LPRng; require 5.003; use Exporter (); @ISA = qw(Exporter); @EXPORT = qw( Set_Debug Setup_LPRng Get_printer_name FixStrVals Setup_pc_entry Real_printer MatchHost MakeMask Read_printcap_file CheckRecurse Read_pc_entry Dump_index Dump_pc Read_conf Dump_conf Fix_value trimall Get_remote_pr_host getconnection sendit sendbuffer sendfile ); use strict; use FileHandle; use Sys::Hostname; use Socket; use English; sub FixStrVals( $ \% ); sub Setup_pc_entry( $ ); sub Real_printer( $ ); sub MatchHost( \@ $ ); sub MakeMask( $ ); sub Read_printcap_file( $ \% \% $ $ \@ ); sub CheckRecurse( $ \% \% $ $ \@ ); sub Read_pc_entry( $ ); sub Dump_index( $ \% ); sub Dump_pc( $ \% ); sub Read_conf( $ \% ); sub Dump_conf( $ \% ); sub Fix_value( $ ); sub trimall( $ ); my( $Debug, %Init_hash, %Pc_hash, %Pc_index, @Hostname, %Keyvals, ); # permanent values # Debug level # # %Init_hash: lpd.conf file values # %Pc_hash: printcap entries # %Pc_index: printcap entry names # @Hostname: hostname information, used for 'oh' printcap information # # maximum depth of recursion for printcap file lookup my($Max_depth) = 10; sub trimall( $ ) { my($line) = @_; $line ||= ""; $line =~ s/^\s+//; $line =~ s/\s+$//; return( $line ); } # convert a printcap or config file value into # a corresponding string or integer value sub Fix_value( $ ) { my($value) = @_; if( $value =~ /^=/ or $value =~ /^#/ ){ $value = trimall( substr( $value, 1 ) ); } elsif ( $value =~ /^\@/ ){ $value = 0; } else { $value = 1; } return $value; } # sub Read_conf( $conf_file, \%conf_values ) # Read a configuration file # $conf_file = configuration file # $conf_values = hash to store values in # sub Dump_conf( $ \% ) { my($title, $hash) = @_; my($key); print "$title config\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } sub Read_conf( $ \% ) { my($conf_file,$conf_values) = @_; my($file,$key,$value,$line); # open the conf file $file = new FileHandle; if( not defined( $file->open("<$conf_file")) ){ return "cannot open $conf_file - $!"; } while( defined( $line = <$file>) ){ chomp $line; next if not $line or $line =~ /^\s*#/; ($key,$value) = ($line =~ /^\s*([\w-]*)(.*)/); $value = trimall($value); ($key = trimall($key)) =~ s/-/_/g; print "key '$key'='$value'\n" if $Debug > 2; $conf_values->{$key} = Fix_value( $value ); print "set key '$key'='" . $conf_values->{$key} . "'\n" if $Debug > 2; } $file->close; Dump_conf( "Read_conf", %$conf_values ) if $Debug > 1; return ""; } # Dump_pc( $title, %Pc_hash ) # dump the printcap hash # sub Dump_pc( $ \% ) { my($title, $hash) = @_; my($key, $name); $name = (); $name = \@{$hash->{'NAME'}}; print "Dump_pc: $title pc '". join( "','",@$name) . "'\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } sub Dump_index( $ \% ) { my($title, $hash) = @_; my($key); print "Dump_index: $title index\n"; foreach $key (sort keys %$hash ){ print " '$key'='". $hash->{$key} . "'\n"; } } # sub Read_pc_entry( $file ) # $file = filehandle # find and read a printcap entry # my($lastline); sub Read_pc_entry( $ ) { my($file) = @_; my($hash,$state,$escape,$line,@lines,$len,$i,@names); my($key,$value,$add_next); $state = ""; $hash = (); $add_next = 0; print "Read_pc_entry: starting\n" if $Debug > 1; while( $lastline or defined( $lastline = <$file> ) ){ $line = trimall( $lastline ); print "line '$line'\n" if $Debug > 3; if( not $line or $line =~ /^\s*#/ ){ $lastline = ""; next; } # beginning of next entry? last if not $add_next and $line =~ /^\s*\w/ and $state ne ""; # we get rid of escapes at the end of the line $lastline = ""; $add_next = 0; ($line, $escape) = ($line =~ /^(.*?)(\\*)$/); if( defined( $escape ) ){ print "escape '$escape'\n" if $Debug > 3; $len = length($escape); if( $len % 2 ){ $escape = substr($escape,0,$len-1); $add_next = 1; } $line .= $escape; } last if( not $state and $line =~ /^\s*include\s/ ); $state .= $line; print "state '$state'\n" if $Debug > 3; } print "Read_pc_entry: final state '$state'\n" if $Debug > 2; if( $state eq "" ){ return undef; } @lines = split( /\s*:+/,$state); if( $Debug > 3 ){ print "Read_pc_entry: split values=\n"; for( $i = 0 ; $i < @lines; ++$i ){ print "[$i] '$lines[$i]'\n"; } } @names = split( /\s*\|+/, shift(@lines)); @names = map { trimall($_) } @names; @{$hash->{'NAME'}} = @names; foreach $line (@lines){ ($key,$value) = ($line =~ /^\s*([\w-]*)(.*)/); $value = trimall($value); ($key = trimall($key)) =~ s/-/_/g; print " key '$key'='$value'\n" if $Debug > 3; $hash->{$key} = Fix_value( $value ); print " set key '$key'='" . $hash->{$key} . "'\n" if $Debug > 3; } Dump_pc( "Read_pc_entry: final value", %$hash ) if $Debug > 1; return $hash; } sub CheckRecurse( $ \% \% $ $ \@ ) { if( defined $lastline ){ my($v,$file) = split( ' ', $lastline ); if( $v eq 'include' ){ $lastline = ""; print "CheckRecurse: file '$file'\n" if $Debug>0; my( $pc_file, $Pc_hash, $Pc_index, $server, $depth, $hostname ) = @_; Read_printcap_file($file, %$Pc_hash, %$Pc_index, $server, $depth, @$hostname ); } } } # sub Read_printcap_file( # $pc_file - file name # %Pc_hash - hash to store printcap values in # %Pc_index - index of all printcap names # $server - if $server != 0 then a server, and use server printcap entries # $depth - recursion depth # @Hostname - hostname information # # read the printcap file and produce a # hash with pointers to hashes of printcap vars # # Algorithm: # open file # while (read a printcap entry){ # decode the printcap entry # if printcap values exist then # merge values # else # create printcap entry # endif # endwhile sub Read_printcap_file( $ \% \% $ $ \@ ) { my( $pc_file, $Pc_hash, $Pc_index, $server, $depth, $hostname ) = @_; my($file,$file_name,$hash,$key,$value,$names,$first,$name); my($i,@n,@Hostentry); # open the conf file $file = new FileHandle; ++$depth; print "Read_printcap_file: file '$pc_file', depth $depth\n" if $Debug>0; if( $depth > $Max_depth ){ return "nesting too deep for '$pc_file'"; } # get either file or filter $file_name = trimall($pc_file); if( ($file_name =~ s/^\|//) ){ $file_name = $file_name . '|'; } else { $file_name = '<' . $file_name; } $file_name = FixStrVals( $file_name, %Keyvals ); print "Read_printcap_file: opening '$file_name'\n" if $Debug>0; if( not defined( $file->open($file_name)) ){ return "cannot open '" . $file_name . "' - $!"; } for(; defined( $hash = Read_pc_entry($file) ); CheckRecurse($pc_file, %$Pc_hash, %$Pc_index, $server, $depth, @$hostname ) ){ Dump_pc( "Read_printcap_file: checking", %$hash ) if $Debug > 1; if( $hash->{'server'} and not $server ){ print "Read_printcap_file: " . "server=(pc '$hash->{server}', need '$server')\n" if $Debug>1; next; } if( $hash->{'oh'} and not MatchHost( @$hostname, $hash->{'oh'} ) ){ print "Read_printcap_file: " . "oh '$hash->{oh}' not matched\n" if $Debug>1; next; } $names = $hash->{'NAME'}; $first = $names->[0]; # find out if we need to add or merge printcap # entries my(%k) = (); for( $i = 1; $i < @$names; ++$i ){ $name = $names->[$i]; $k{$name} = $name; } $value = $Pc_hash->{$first}->{'NAME'}; if( defined @$value ){ for( $i = 1; $i < @$value; ++$i ){ $name = $value->[$i]; $k{$name} = $name; } } @n = ( $first, sort keys %k ); @{$Pc_hash->{$first}->{'NAME'}} = @n; foreach $key (keys %$hash){ $value = $hash->{$key}; if( $key ne 'NAME' ){ $Pc_hash->{$first}->{$key} = $value; } } foreach $name (@$names){ $Pc_index->{$name} = $first; } if( not $Pc_index->{'FIRST'} ){ $Pc_index->{'FIRST'} = $first; } if( $Debug > 1 ){ Dump_index( "Read_printcap_file: after adding '$first'", %$Pc_index ); foreach $name (sort keys %$Pc_hash){ Dump_pc( "Read_printcap_file: after adding '$first'", %{$Pc_hash->{$name}} ); } } } if( $Debug > 0 ){ Dump_index( "Read_printcap_file: after '$pc_file'", %$Pc_index ); foreach $name (sort keys %$Pc_hash){ Dump_pc( "Read_printcap_file: after '$pc_file'", %{$Pc_hash->{$name}} ); } } } sub MakeMask( $ ) { my($mask) = @_; my($mnum,$v,@v,$x,$i,$j,@d); if( defined $mask ){ if( $mask =~ /\./ ){ $mnum = inet_aton( $mask ); } else { if( $mask < 32 and $mask >= 0 ){ $v = pack( "N", (1 << $mask ) - 1); @v = reverse split( '', unpack( "B32", $v )); for( $i = 0; $i < 4; ++$i ){ $x = 0; for( $j = 0; $j < 8; ++$j ){ $x *= 2; $x += $v[$i*8+$j]; } $d[$i] = $x; } $i = join(".", @d ); #print "MakeMask: generated $mask = '$i'\n" if $Debug > 5; $mnum = inet_aton( $i ); } else { $mnum = inet_aton( "255.255.255.255" ); } } } else { $mnum = inet_aton( "255.255.255.255" ); } print "MakeMask: $mask = '" . inet_ntoa( $mnum ) . "'\n" if $Debug > 5; return $mnum; } # sub MatchHost( @Hostinfo, $matches ) # @Hostinfo is value returned by gethostbyname() # ($name, $alises, $addrtype, $length, @addrs ) # 0 1 2 3 4 # matches has format: ((glob|ip/mask),)* sub MatchHost( \@ $ ) { my($hostinfo,$matches) = @_; my(@list,$value,$addr,$mask,$anum,$mnum,$null,@v,$i,$ipaddr); @list = split( '[,\s]', $matches ); foreach $value ( @list ){ print "Matchhost: '$value' to $hostinfo->[0]\n" if $Debug>2; if( $value =~ /^\d/ ){ # we have addr/mask $null = inet_aton("0.0.0.0"); ($addr,$mask) = split( '/',$value ); $anum = inet_aton( $addr ); $mnum = MakeMask( $mask ); print "Matchhost: addr '" . inet_ntoa($anum) . "', mask '" . inet_ntoa($mnum) . "'\n" if $Debug>3; for($i = 4; $i < @$hostinfo; ++$i ){ $ipaddr = $hostinfo->[$i]; print "Matchhost: ipaddr '" . inet_ntoa($ipaddr) . "'\n" if $Debug>3; $ipaddr = ($ipaddr ^ $anum) & $mnum; print "Matchhost: result '" . inet_ntoa($ipaddr) . "'\n" if $Debug>3; if( $ipaddr eq $null ){ print "Matchhost: found '".inet_ntoa( $hostinfo->[$i])."'\n" if $Debug>3; return 1; } } } else { # we have glob str $value =~ s/\./\\./g; $value =~ s/\*/.*/g; print "Matchhost: new value '$value'\n" if $Debug>3; if( $hostinfo->[0] =~ /$value/ ){ print "Matchhost: found\n" if $Debug>3; return 1; } } } return 0; } # sub Setup_pc_entry( $name ) # 1. look up the pc entry # 2. set the initial values to configuration defaults # 3. combine the pc values # returns: hash of combined values sub Real_printer( $ ) { my($name) = @_; $name = $Pc_index{$name}; return $name; } sub Setup_pc_entry( $ ) { my($name ) = @_; my($real, %hash, $value, $key, $tc_val, @tc_list, %tc_hash ); $real = Real_printer( $name ); if( not $real ){ return undef; } print "Setup_pc_entry: pr '$name', using real '$real'\n" if $Debug > 2; %hash = %Init_hash; Dump_pc( "Setup_pc_entry: after init", %hash ) if $Debug > 3; $value = $Pc_hash{$real}; Dump_pc( "Setup_pc_entry: pc value for '$real'", %$value ) if $Debug > 3; foreach $key (keys %$value){ print "Setup_pc_entry: setting '$key'='$value->{$key}'\n" if $Debug > 5; $hash{$key} = $value->{$key}; } Dump_pc( "Setup_pc_entry: pr '$name', real '$real'; result", %hash ) if $Debug > 1; # now we have to resolve the TC values # $tc_val = $hash{'tc'}; $hash{'tc'} = ""; if( $tc_val ){ push @tc_list, split( /[\s,;:]/, $tc_val ); } while( @tc_list ){ $tc_val = shift @tc_list; print "Setup_pc_entry: tc '$tc_val'" if $Debug > 5; $real = Real_printer( $tc_val ); if( $tc_hash{$tc_val} ){ print STDERR "Setup_pc_entry: Printer '$name' has tc with multiple uses of '$tc_val', really '$real'"; return undef; } $tc_hash{$tc_val} = 1; if( not defined $real ){ print STDERR "Setup_pc_entry: Printer '$name' missing tc entry for '$tc_val', really '$real'"; return undef; } $value = $Pc_hash{$real}; foreach $key (keys %$value){ print "Setup_pc_entry: setting '$key'='$value->{$key}'\n" if $Debug > 5; if( $key ne 'NAME' ){ $hash{$key} = $value->{$key}; } } Dump_pc( "Setup_pc_entry: pr '$name', after tc '$real'", %hash ) if $Debug > 1; $tc_val = $hash{'tc'}; $hash{'tc'} = ""; if( $tc_val ){ push @tc_list, split( '\s,;:', $tc_val ); } } return \%hash; } sub FixStrVals( $ \% ) { my($str, $hash ) = @_; my( $key, $val ); while( $str =~ /%(.)/ ){ $key = $1; print "FixStrVals: fixing '$key' in '$str'\n" if $Debug > 5; $val = $hash->{$key}; $val = "" if( not defined $val ); $str =~ s/%$key/$val/g; } print "FixStrVals: final '$str'\n" if $Debug > 5; return $str; } sub Get_printer_name( \% ) { my($Args) = shift; my($printer); $printer ||= $Args->{'P'}; $printer ||= $Pc_index{'FIRST'}; $printer ||= $Init_hash{'default_printer'}; print "Get_printer_name: '$printer'\n" if $Debug>0; return( $printer ); } sub Setup_LPRng( \% ) { my($Args) = @_; my($pc_path,$file,$key); # get the command line options # get the hostname information $key = hostname(); @Hostname = gethostbyname( $key ); # set up the key values $Keyvals{'H'} = $Hostname[0]; #Read_conf("/var/tmp/LPD/lpd.conf", %Init_hash); Read_conf("/etc/lpd.conf", %Init_hash); $pc_path = "/etc/printcap"; if( $Init_hash{'printcap_path'} ){ $pc_path = $Init_hash{'printcap_path'}; } foreach $file ( split( '[:,]', $pc_path ) ){ $file = FixStrVals( $file, %Keyvals ); Read_printcap_file($file, %Pc_hash, %Pc_index, 1, 0, @Hostname); } } sub Set_Debug( $ ) { my($v) = $Debug; $Debug = $_[0]; } # sub Get_remote_pr_host( $Printer, $Pc_value ); # returns: ($pr, $remote, $port) # $pr = remote printer, $remote = remote host, $port = port to use # # if Pc_value # we use the lp value # if no lp value, we use rp, rm value # else # we use the lp value # if the lp value then we split it up # sub Get_remote_pr_host( $ $) { my( $prname, $pc ) = @_; my( $lp, $pr, $remote, $port ); if( defined $pc ){ $lp = $pc->{'lp'}; } else { $lp = $prname; } # we now check to see if we have pr@host if( defined $lp ){ if( $lp =~ /\@/ ){ ($pr, $remote ) = split( '@', $lp ); } else { $pr = $prname } } elsif( defined $pc ){ $pr = $pc->{'rp'}; $remote = $pc->{'rm'}; } if( not $pr ){ $pr = $prname; } $pr = $prname if( $pr =~ /%P/ ); if( not $remote ){ if( defined $pc ){ $remote = "localhost" if $pc->{'force_localhost'}; } else { $remote = "localhost" if $Init_hash{'force_localhost'}; } } if( not $remote ){ if( defined $pc ){ $remote = $pc->{'default_remote_host'}; } else { $remote = $Init_hash{'default_remote_host'}; } } if( not $remote ){ $remote = "localhost"; } ($remote, $port ) = split( '%', $remote ); if( not $port ){ if( defined $pc ){ $port = $pc->{'lpd_port'}; } else { $port = $Init_hash{'lpd_port'}; } } if( not $port ){ $port = "printer"; } if( $port + 0 == 0 ){ $port = getservbyname( $port, "tcp" ); } return( $pr, $remote, $port ); } sub getconnection ($ $) { my ($remote,$port) = @_; my ($iaddr,$paddr,$proto); my ($low_port, $high_port, $ports, $t, $euid ) if $Debug>0; $ports = $Init_hash{'originate_port'}; if( $ports ){ ($low_port, $high_port) = split( /[\s,;]+/, $ports ); print "low_port '$low_port', high_port '$high_port'\n" if $Debug>0; } $low_port += 0; $high_port += 0; print "num low_port '$low_port', high_port '$high_port'\n" if $Debug>0; $iaddr = inet_aton($remote) or die "no host: $remote"; $paddr = sockaddr_in($port,$iaddr); $proto = getprotobyname('tcp'); print "remote='$remote', port ='$port', iaddr='" . inet_ntoa($iaddr). "'\n" if $Debug; $t = 0; if( $low_port < $high_port and ($EUID == 0 or $UID == 0 ) ){ $euid = $EUID; $EUID = 0; while( $t == 0 and $low_port < $high_port ){ close(SOCK); socket(SOCK,PF_INET,SOCK_STREAM,$proto) or die "socket: $!"; setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or warn "setsockopt failed - $!\n"; if( bind( SOCK, sockaddr_in( $low_port, INADDR_ANY ) ) ){ $t = 1; } else { print "bind to $low_port failed - $!\n"; ++$low_port; } } $EUID = $euid; } if( $t == 0 ){ close(SOCK); socket(SOCK,PF_INET,SOCK_STREAM,$proto) or die "socket: $!"; setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) or warn "setsockopt failed - $!\n"; } connect(SOCK,$paddr) or die "connect: $!"; print "connection made\n" if $Debug; # unbufferred IO select(SOCK); $| = 1; select(STDOUT); return \*SOCK; } sub sendit( $ $ ) { my( $SOCK, $line ) = @_; my( $count ); print "sendit sending '$line'\n" if $Debug; print $SOCK $line or die "print to socket failed - $!\n"; $line = ""; $count = read $SOCK, $line, 1; print "sendit read $count\n" if $Debug; if( !defined($count) ){ die "read error on socket - $!\n"; } if( !$count ){ die "EOF on socket\n"; } $count = unpack( "C", $line ); if( $count ){ print "error: "; while( defined ( $line = <$SOCK> ) ){ print $line; } print "\n"; exit 1; } print "sendit no error\n" if $Debug; } sub sendbuffer( $ $ $ ) { my($SOCK, $line, $buffer ) = @_; my( $count ); print "sendbuffer line '$line'\n" if $Debug; sendit( $SOCK, $line ); print "sendbuffer buffer '$buffer'\n" if $Debug; print $SOCK $buffer; print $SOCK "\000"; $line = ""; $count = read $SOCK, $line, 1; print "sendbuffer read $count\n" if $Debug; if( !defined($count) ){ die "read error on socket - $!\n"; } if( !$count ){ die "EOF on socket\n"; } $count = unpack( "C", $line ); if( $count ){ print "error code: $count\n"; while( defined($line = <$SOCK>) ){ print $line; } print "\n"; exit 1; } print "sendbuffer no error\n" if $Debug; } sub sendfile ( $ $ $ ) { my( $SOCK, $name, $filename ) = @_; my( $size, $line, $count ); open( FILE, "<$filename") or die "cannot open file '$filename'\n"; $size = -s FILE; print "sendfile: '$name' size $size\n" if $Debug; sendit( $SOCK, "\003$size $name\n" ); print "sendfile: sending file\n" if $Debug; while( $size = read FILE, $line, 1024 ){ print "read $size bytes\n" if $Debug; print $SOCK $line; } print "sendfile: finished\n" if $Debug; if( !defined( $size ) ){ die "bad read from '$name' - $!\n"; } print $SOCK "\000"; $line = ""; $count = read $SOCK, $line, 1; print "sendfile: read $count\n" if $Debug; if( !defined($count) ){ die "read error on socket - $!\n"; } if( !$count ){ die "EOF on socket\n"; } $count = unpack( "C", $line ); if( $count ){ print "error code: $count\n"; while( defined($line = <$SOCK>) ){ print $line; } print "\n"; exit 1; } print "sendfile: no error\n" if $Debug; } $Debug = 0; 1; lprng-3.8.B/UTILS/smbprint0000755000131400013140000000707411531672127012300 00000000000000#!/bin/sh # $Id: smbprint,v 1.67 2004/09/24 20:19:56 papowell Exp $ # # Blatently lifted from some folks who blatently lifted it from # other folks, who seem to have taken it from one of the very # first Samba distributions. # Patrick ("Worse than a chain letter") Powell # # This script supports sending a print job to an SMB (Samba/Microsoft) # printer using the 'smbclient' from the Samba distribution. # # Variation 1: LPRng + smbclient -A auth # smb:lp=|/.../smbprint # :sd=/var/spool/lpd/%P # :xfer_options=share=//host/share authfile=auth # - user name and password in /var/spool/lpd/smb/auth file # - requires version of smbclient that uses -A authfile # Variation 2: LPRng + smbclient -U username password # smb:lp=|/.../smbprint # :sd=/var/spool/lpd/%P # :xfer_options=share=//host/share authfile=auth # - user name and password in /var/spool/lpd/smb/auth file # - requires version of smbclient that uses -A authfile # Variation 3: LPRng + used as filter # smb:lp=/dev/null # :if=/.../smbprint # :sd=/var/spool/lpd/%P # :xfer_options=share=//host/share authfile=auth # - user name and password in /var/spool/lpd/smb/auth file # Variation 4: pass options in $spooldir/general.cfg file # smb:lp=/dev/null OR lp=|/.../smbprint OR :if=/.../smbprint # - options in /var/spool/lpd/smb/general.cfg file # # The general.cfg file is used to set shell variables # # share=//host/share - share (required) # hostip= - host ip address (optional) # workgroup= - workgroup (required) # authfile=auth - authorization file (optional) # translate= - do translation (optional and DANGEROUS) # # The authentication file (authfile) holds the username and # password value. You can put these in the general.cfg file # as well. WARNING: smbclient requires the authentication file # to have the format: # username=name # password=xxxx # There are NO quotes allowed around the name and/or password # files so the password value xxxx must not contain shell # quote or metacharacters. # PATH=/bin:/usr/bin:/usr/local/bin export PATH # get options from general.cfg file if [ -f ./general.cfg ] ; then source ./general.cfg fi # get options from $PRINTCAP_ENTRY environment variable options=`echo "${PRINTCAP_ENTRY}" | sed -n 's/:xfer_options=//p' ` echo OPTIONS $options >&2 if [ -n "$options" ] ; then eval export $options fi # a brutal way to determine if smbclient takes the -A authfile option smbclientold=`smbclient -A /dev/null 2>&1 /tmp/smbprint.log # use the -A or if [ "$smbclientold" = "" ] ; then # echo smbclient "$share" ${password:+password} -E \ # ${username:+-U} ${username:+username} ${hostip:+-I} $hostip -N ${workgroup:+-W} $workgroup \ # ${authfile:+-A} $authfile -c "$command" >&2 smbclient "$share" ${password} -E \ ${username:+-U} ${username} ${hostip:+-I} $hostip -N ${workgroup:+-W} $workgroup \ ${authfile:+-A} $authfile -c "$command" >&2 else # echo echo \"$command\" "|" smbclient "$share" ${password:+password} -E \ # ${username:+-U} ${username:+username} ${hostip:+-I} $hostip -N ${workgroup:+-W} $workgroup \ # >&2 echo $command | smbclient "$share" ${password} -E \ ${username:+-U} ${username} ${hostip:+-I} $hostip -N ${workgroup:+-W} $workgroup \ >&2 fi lprng-3.8.B/UTILS/freefs.c0000644000131400013140000000413611531672127012126 00000000000000#include "portable.h" /**** ENDINCLUDE ****/ #ifdef HAVE_SYS_MOUNT_H # include #endif #ifdef HAVE_SYS_STATVFS_H # include #endif #ifdef HAVE_SYS_STATFS_H # include #endif #if defined(HAVE_SYS_VFS_H) && !defined(SOLARIS) # include #endif # if USE_STATFS_TYPE == STATVFS # define plp_statfs(path,buf) statvfs(path,buf) # define plp_struct_statfs struct statvfs # define statfs(path, buf) statvfs(path, buf) # define USING "STATVFS" # define BLOCKSIZE(f) (unsigned long)(f.f_frsize?f.frsize:f.f_bsize) # define BLOCKS(f) (unsigned long)f.f_bavail # endif # if USE_STATFS_TYPE == ULTRIX_STATFS # define plp_statfs(path,buf) statfs(path,buf) # define plp_struct_statfs struct fs_data # define USING "ULTRIX_STATFS" # define BLOCKSIZE(f) (unsigned long)f.fd_bsize # define BLOCKS(f) (unsigned long)f.fd_bfree # endif # if USE_STATFS_TYPE == SVR3_STATFS # define plp_struct_statfs struct statfs # define plp_statfs(path,buf) statfs(path,buf,sizeof(struct statfs),0) # define USING "SV3_STATFS" # define BLOCKSIZE(f) (unsigned long)f.f_bsize # define BLOCKS(f) (unsigned long)f.f_bfree # endif # if USE_STATFS_TYPE == STATFS # define plp_struct_statfs struct statfs # define plp_statfs(path,buf) statfs(path,buf) # define USING "STATFS" # define BLOCKSIZE(f) (unsigned long)f.f_bsize # define BLOCKS(f) (unsigned long)f.f_bavail # endif /*************************************************************************** * Space_avail() - get the amount of free space avail in the spool directory ***************************************************************************/ int main( int argc, char *argv[], char *envp[] ) { char *pathname = argv[1]; plp_struct_statfs fsb; unsigned long space = 0; if( !pathname ){ pathname = "."; } if( plp_statfs( pathname, &fsb ) == -1 ){ fprintf(stderr, "Space_avail: cannot stat '%s'", pathname ); exit(1); } space = (1.0 * BLOCKS(fsb) * BLOCKSIZE(fsb))/1024; printf("path '%s', Using '%s', %lu blocks, %lu blocksize, space %lu\n", pathname, USING, BLOCKS(fsb), BLOCKSIZE(fsb), space ); return(0); } lprng-3.8.B/UTILS/set_file_time.c0000644000131400013140000000323611531672127013464 00000000000000/* The evil 'set file time' function for testing file removal Use: setfiletime Age file* */ #include #include #include #include #include extern char *optarg; extern int optind; extern int optopt; extern int opterr; extern int optreset; char *Name = "???"; char *msg[] = { "%s: setfiletime AGE file*\n", " AGE is fK, where f amount (fraction)", " K is amount - S/s sec, M/m min, H/h hour, D/d day", 0 }; void usage(void) { int i; for( i = 0; msg[i]; ++i ){ if( i == 0 ) fprintf( stderr, msg[i], Name ); else fprintf( stderr, "%s\n", msg[i] ); } exit(1); } int main( int argc, char **argv ) { int c; int age; float fage; char *s, *t; struct timeval tval[2]; setlinebuf(stdout); if( argv[0] ) Name = argv[0]; while( (c = getopt( argc, argv, "=" ) ) != EOF ){ switch( c ){ case '=': usage(); break; default: usage(); break; } } if( argc - optind == 0 ) usage(); s = argv[optind++]; t = 0; fage = strtod(s,&t); printf("age '%f' (%s)\n", fage, s ); if( !t ) usage(); if( !fage ) usage(); switch( t[0] ){ case 's': case 'S': break; case 'm': case 'M': fage *= 60; break; case 'h': case 'H': fage *= 60*60; break; case 'd': case 'D': fage *= 24*60*60; break; } printf( "back '%f' sec\n", fage ); if( gettimeofday( &tval[0], 0 ) ){ perror( "gettimeofday" ); exit(1); } printf( "now '%d'\n", (int)tval[0].tv_sec ); tval[0].tv_sec -= (int)fage; tval[1] = tval[0]; while( optind < argc ){ s = argv[optind++]; printf( "setting '%s' back %d\n", s, (int)fage ); if( utimes( s, tval ) ){ perror( "utimes" ); exit(1); } } return(0); } lprng-3.8.B/UTILS/accounting.pl.in0000644000131400013140000001533711531672127013611 00000000000000#!@PERL@ eval 'exec @PERL@ -S $0 ${1+"$@"}' if $running_under_some_shell; # this emulates #! processing on NIH machines. # (remove #! line above if indigestible) # accounting.pl.in,v 5.5 2000/06/09 21:55:12 papowell Exp # LPRng based accounting script. # Version Thu Apr 13 21:00:20 PDT 2000 # LPRng 3.6.14 # # stdin = /dev/null # stdout = accounting file # stderr = log file # # command line format: # accounting [start|end] [-options] [accounting file] # -Tdebug will turn on debugging # start - at start of job; scan accounting file, fix up, # put in START entry # end - at end of job; scan accounting file, fix up, # put in END entry # # Accounting File has format: # start '-ppagecounter' '-Athis' -P'that' <- startpage # ... # end '-ppagecounter' <- lastpage # END 't=$elapsed' 'p=$pages' 'q=$lastpage' 's=$startpage' 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time' 'S=$starttime' # --- end of a job # START 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time' # start '-ppagecounter' '-Athis' -P'that' <- startpage # ... # end '-ppagecounter' <- lastpage # END 't=$elapsed' 'p=$pages' 'q=$lastpage' 's=$startpage' 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time' 'S=$starttime' # # We implement a stack based FSM to do the following: # Stack = NULL, state = FIND_START # # FIND_START - find the first START # START -> push START line # -> FIND_start # # FIND_start - find the first 'start' entry with page # start -> push start # -> FIND_end # # FIND_end - find the first 'end' entry for this job # end -> push end line # -> FOUND_end # START -> push START line # -> FIND_start # # FOUND_end - keep looking for 'end' entries # end -> pop stack # -> push end line # START -> push START line # -> FIND_start # # All states: # # END -> clear stack # -> FIND_START # START -> push START line # -> FIND_start # # # At end, if you do not have state FOUND_end you do not have a # valid accounting file so you have to wait. # Stack will have contents: # ((START* start )* end) * # ^ start page count # ^ end page count # we start from the bottom of the stack; # - end entry sets end page count for job # - start entry sets start page count for job # - START assigns pagecount as difference between start and end # end page count = start page count # # seq START START START start end # pages 0 0 end - start # # seq START START start1 START START start2 end2 # pages 0 start2-start1 0 start2-end2 # use strict; use Getopt::Std; use FileHandle; my($JFAIL, $JABORT, $JREMOVE, $JHOLD) = ( 32, 33, 34, 37); my(%opt, $action, $acct_h, $debug,$state,@stack); my($FIND_START,$FIND_start,$FIND_end,$FOUND_end)=(0,1,2,3,4,5); $debug = 0; # print STDERR "$0: '" . join("' '",@ARGV) . "'\n" if $debug; $action = ""; if( @ARGV ){ if( $ARGV[0] !~ /^-/ ){ $action = shift @ARGV; } print STDERR "action $action\n" if $debug; } if( $action ne "start" and $action ne "end" ){ print STDERR "$0: invalid action '$action'\n"; exit $JABORT; } # pull out the options getopts( 'A:B:C:D:E:F:G:H:I:J:K:L:M:N:O:P:Q:R:T:S:U:V:W:X:Y:Z:' . 'a:b:cd:e:f:g:h:i:j:k:l:m:n:o:p:q:r:t:s:u:v:w:x:y:z:', \%opt ); my($acct_file) = ""; if( @ARGV ){ $acct_file = shift @ARGV; } else { $acct_file = $opt{'a'}; } if( exists( $opt{T} ) && $opt{T} =~ m/debug/ ){ $debug = 1; } if( !$acct_file ){ print STDERR "$0: no accounting file\n"; exit( $JABORT ); } my($time) = time; print STDERR "$0: $action 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time'\n" if $debug; print STDERR "accounting file '$acct_file'\n" if $debug; if( $action eq "start" ){ $acct_h = new FileHandle ">>$acct_file" ; print $acct_h "START 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time'\n"; print STDERR "START 'A=$opt{A}' 'P=$opt{P}' 'n=$opt{n}' 'H=$opt{H}' 'D=$time'\n" if $debug; $acct_h->close(); exit 0; } $acct_h = new FileHandle "+<$acct_file" ; if( ! defined($acct_h) ){ print STDERR "$0: cannot open $acct_file r/w - $!\n"; exit( $JABORT ); } # now we read the last line from the accounting file my($size) = -s $acct_file; my($max_seek) = 2048; my($read_all) = 0; if( $size > $max_seek && not $acct_h->seek( -$max_seek, 2 ) ){ print STDERR "$0: lseek $acct_file failed - $!\n"; exit( $JABORT ); } again: @stack = (); $state = $FIND_START; while( <$acct_h> ){ chomp; print STDERR "STATE '$state' LINE '$_'\n" if $debug; print STDERR "STACK\n " . join("\n ",@stack) . "\n" if $debug; if( /^END / ){ $state = $FIND_START; @stack = (); next; } if( /^START / ){ push @stack, $_; $state = $FIND_start; next; } if( $state == $FIND_start ){ if( /^(file)?start .*-p\d+/ ){ push @stack, $_; $state = $FIND_end; } } elsif( $state == $FIND_end ){ if( /^(file)?end .*-p\d+/ ){ push @stack, $_; $state = $FOUND_end; } } elsif( $state == $FOUND_end ){ if( /^(file)?end .*-p\d+/ ){ pop @stack; push @stack, $_; $state = $FOUND_end; } } } if( $state != $FOUND_end ){ if( $read_all ){ print STDERR "$0: did not find end record in file"; exit 0; } $acct_h->close(); $acct_h = new FileHandle "+<$acct_file" ; if( ! defined($acct_h) ){ print STDERR "$0: cannot open $acct_file r/w - $!\n"; exit( $JABORT ); } $read_all = 1; } print STDERR "FINAL STATE '$state'\n" if $debug; print STDERR "FINAL STACK\n " . join("\n ",@stack) . "\n" if $debug; my($end_counter,$start_counter,$start_time,$count,$out,$elapsed); $end_counter = $start_counter = 0; $out = ""; for( my $i = @stack -1; $i >= 0 ; --$i ){ $_ = $stack[$i]; print STDERR "stack [$i] '$_'\n" if $debug; if( /^[a-z]*end .*-p(\d+)/ ){ $end_counter = $1; } elsif( /^[a-z]*start .*-p(\d+)/ ){ $start_counter = $1; } elsif( /^START/ ){ # we now update the accounting information ($start_time) = /D=(\d+)/; s/D=(\d+)/S=$1/; $count = $end_counter - $start_counter; $elapsed = $time - $start_time; # you should put your make update record stuff here s/^START/END 't=$elapsed' 'p=$count' 's=$start_counter' 'q=$end_counter' 'D=$time'/; $out = $_ . "\n" . $out; $end_counter = $start_counter; $time = $start_time; } } # update the file and the database at this point print STDERR "APPEND $out" if $debug; print $acct_h $out; lprng-3.8.B/UTILS/make_printcap_use.in0000644000131400013140000000115511531672127014527 00000000000000#!/bin/sh @PERL@ -e ' while ( ($m = <>) && !( $m =~ m/START/) ){ ; } print "

\n"; print "\n"; print "\n"; while ( ($m = <>) && !( $m =~ m/END/) ){ chomp($m); if ( $m =~ /{/ ){ $m =~ s/},$//; $m =~ s/",//; $m =~ s/{//; $m =~ s/_K,.*,/_K /; $m =~ s/"//; $m =~ s/\s+/ /g; $m =~ s/^\s+//; $m =~ s/\s.*//; print "\n"; } else { $m =~ s:^\s*/\*\s*::; $m =~ s:\*/::; $title = $m; } } print "
OptionMeaning
$m$title
\n"; ' $1 lprng-3.8.B/UTILS/atalkprint0000755000131400013140000000313011531672127012600 00000000000000#!/bin/sh # $Id: atalkprint,v 1.74 2004/09/24 20:19:55 papowell Exp $ # This is a template file for hooking up printing to a remote # printer that needs a communication program # # Modified by Patrick Powell for the LPRngTool # Note 1: the general.config file is assumed to be in the current directory # Note 2: entries can be in any order in the file # # This script is an input filter for printcap printing on a unix machine. It # uses the smbclient program to print the file to the specified smb-based # server and service. # For example you could have a printcap entry like this # # atalk:lp=/dev/null:sd=/usr/spool/lpd/atalk:if=/usr/local/filters/atalkprint # # which would create a unix printer called "atalk" that will print via this # script. # # The script gets its information from the general.config file # file in the printer spool directory or the atalk_options line # or from the printcap 'atalk_options' line # The options used are: # host=host host for printing # printer=printer printer # username=printer printer # example: general.config file - # host="host" # printer="lp" # # :atalk_options= host="host" printer="lp" # # Should read the following variables set in the auth file: # username=username for authentication # password=password for authentication if [ -f ./general.cfg ] ; then . ./general.cfg fi options=`echo "${PRINTCAP_ENTRY}" | sed -n 's/:atalk_options=//p' ` if [ -n "$options" ] ; then eval export $options fi # now you simply use the paramters you have extracted # /usr/bin/pap -p "$username:$printer@$host" lprng-3.8.B/UTILS/makeinc.in0000644000131400013140000000247011531672127012446 00000000000000#!@SHELL@ ########################################################################### # LPRng - An Extended Print Spooler System # # Copyright 1988-1995 Patrick Powell, San Diego State University # papowell@sdsu.edu # See LICENSE for conditions of use. # ########################################################################### # MODULE: UTILS/makeinc # PURPOSE: find dependencies for files # NOTE: uses GCC to expand the files # Usage: cd source_directory; makeinc *.o # Note: you have to modify the -I. -I./include line # if you change structure # makeinc,v 3.1 1996/12/28 21:40:52 papowell Exp ########################################################################## for i in $* ; do lo=`echo $i | sed -e 's/\.o/.lo/g'` o=`echo $i | sed -e 's/\.lo/.o/g'` I=`echo $i | sed -e 's/\.lo/.c/' -e 's/\.o/.c/' ` #echo "# doing '$i' LO '$lo' O '$o' C '$I'" II=`ls ./*/$I 2>/dev/null` if [ ! -n "$II" ]; then II=`ls ./$I 2>/dev/null`; fi; #echo "# II $II" gcc ${CFLAGS} -E \ -I. -I./include -I.. \ $II >/tmp/s awk ' /^# [0-9]/ { if( $3 ~ /usr/ ) next; l = substr( $3, 2); l = substr( l, 1, length(l)-1); if( l ~ /\.c$/ ) next; print l; } { next; }' /tmp/t sort /tmp/t |uniq | sed -e 's,.*/,,' >/tmp/w echo -n $o $lo ":" awk 'BEGIN { printf "\t" } {printf "%s ", $0} END { print }' < /tmp/w done lprng-3.8.B/UTILS/fixid.in0000644000131400013140000000007311531672127012137 00000000000000#!@PERL@ -spi.bak if( /include.*inet_ntop.h/ ){ $_ = ""; } lprng-3.8.B/UTILS/ps.draft0000644000131400013140000000547011531672127012156 00000000000000From thomas%spline.UUCP@utah-gr.UUCP Mon Apr 20 20:42:02 1987 Path: seismo!ut-sally!utah-cs!utah-gr!spline!thomas From: thomas%spline.uucp@utah-gr.UUCP (Spencer W. Thomas) Newsgroups: comp.laser-printers,comp.text Subject: Re: Troff/PostScript Question Message-ID: <1993@utah-gr.UUCP> Date: 21 Apr 87 00:42:02 GMT References: <148@dana.UUCP> Sender: news@utah-gr.UUCP Reply-To: thomas%spline.UUCP@utah-gr.UUCP (Spencer W. Thomas) Organization: Univ of Utah CS Dept Lines: 94 In article <148@dana.UUCP> paul@dana.UUCP (Paul Ausick) writes: >I want to print the word "DRAFT" on every page of a document >in outline letters right across the middle of the page, slanting >upwards. I've got just the thing for you. This shell script is run as a filter and redefines the "showpage" and "copypage" operators to print the word "DRAFT" (by default) or whatever word you want as outlined characters diagonally across the page. Thus, you might say psdraft file.ps | lpr To get it to read stdin, use - as the file name: dvi2ps file.dvi | psdraft - | lpr I have tested it with output from Scribe, TeX and ditroff. =Spencer ({ihnp4,decvax}!utah-cs!thomas, thomas@cs.utah.edu) -------------------------------- Cut Here -------------------------------- #! /bin/sh sed 's/^X//' <<'EOF' X#! /bin/sh X# X# Put the word "DRAFT" (or a specified word) on each page of a postscript X# document. X# X# Usage: X# psdraft -s draftstring file ... X# X# X# Author: Spencer W. Thomas X# Computer Science Dept. X# University of Utah X# thomas@cs.utah.edu X X# X# Insert header after first line that does not begin %% or %! X# X Xtrap "rm -f /tmp/psd$$.*" 0 1 2 15 X Xif [ "x$1" = "x-s" ] ; then X draftstring=$2 X shift X shift Xelse X draftstring=DRAFT Xfi X Xif [ "x$*" = "x" ] ; then X echo "Usage: psdraft [-s draftstring] files ..." Xfi X X# Create sed script file X Xsed "s/(DRAFT)/($draftstring)/" <<'EOF' >/tmp/psd$$.sed X1,/^[^%]/{ Xs/^%/%/ Xs/^$// Xt skip Xi\ X% Prelude to show a draft string on every page.\ X(DRAFT)\ X/DRAFTDICT 10 dict def\ XDRAFTDICT begin\ X/DRAFTSTRING exch def\ X/bd /Helvetica-Bold findfont def\ X/od bd maxlength 1 add dict def\ Xbd {exch dup /FID ne {exch od 3 1 roll put} {pop pop} ifelse} forall\ Xod /FontName /Outline0 put od /PaintType 2 put od /StrokeWidth 0 put\ X/Outline0 od definefont pop\ X/DRAFT { gsave\ X initmatrix\ X /Outline0 findfont setfont\ X DRAFTSTRING dup stringwidth pop 8.875 exch div dup 72 mul dup scale\ X 52.3 rotate 2.5 exch div -.35 translate\ X 0 0 moveto show\ X grestore } def\ X/oldshow /showpage load def\ X/oldcopy /copypage load def\ Xend\ X/showpage { DRAFTDICT begin DRAFT oldshow end } def\ X/copypage { DRAFTDICT begin DRAFT oldcopy end } def\ X% End of draft prelude X: skip X} XEOF X Xcat $* | sed -f /tmp/psd$$.sed EOF exit 0 =Spencer ({ihnp4,decvax}!utah-cs!thomas, thomas@cs.utah.edu) lprng-3.8.B/UTILS/one.pjl0000755000131400013140000000104011531672127011772 00000000000000%-12345X@PJL @PJL RDYMSG DISPLAY = ":" @PJL USTATUSOFF @PJL USTATUS JOB = ON @PJL USTATUS DEVICE = ON @PJL USTATUS PAGE = ON @PJL USTATUS TIMED = 10 @PJL ENTER LANGUAGE = POSTSCRIPT %! %!PS-Adobe-3.0 %% one page (i.e. - a page with a 1 on it) %%/Times-Roman /Courier findfont 200 scalefont setfont 72 300 moveto (1) show showpage %-12345X@PJL @PJL RDYMSG DISPLAY = ":" @PJL EOJ NAME = ":" @PJL USTATUSOFF @PJL USTATUS JOB = ON @PJL USTATUS DEVICE = ON @PJL USTATUS PAGE = ON @PJL USTATUS TIMED = 10 @PJL RDYMSG DISPLAY = "Done: :" %-12345Xlprng-3.8.B/UTILS/make_lpd_conf.in0000755000131400013140000000426611531672127013630 00000000000000#!/bin/sh date=`LC_ALL=C date`; AWK=@AWK@ cat < 6 ){ # F = "FIELDS=" # } # print "name \"" name "\", type \"" type "\", value \"" F value "\""; if( type == 0 ){ value = value + 0; # print "FLAG \"" value "\"" ; if( value == 0 ){ name= name "@ (FLAG off)"; } else { name= name " (FLAG on)"; } } else if( type == 1 ){ if( value == "" ){ value = 0; } name = name "=" value " (INTEGER)"; } else { v = ""; if( value == "0"){ value = ""; v = "EMPTY " ; } name = name "=" value " (" v "STRING)"; } print "# default " name ; } else { print "# Purpose: " $0; } } ' lprng-3.8.B/INSTALL0000644000131400013140000004144611531672125010644 00000000000000 LPRng Installation Patrick Powell with many modifications by Bernhard R. Link Last Updated 2007-02-08 18:08 SUPER EXPRESS INSTALLATION FOR TERMINALLY IMPATIENT SYSADMINS READ THE NEXT COUPLE OF PARAGRAPHS: To put files and executables in the most common 'STANDARD locations' sh STANDARD_configuration make clean; make all; make install; checkpc -f The "STANDARD_configuration" script will run configure and set the most common configuration for UNIX/LINUX systems: - /etc/printcap, /etc/lpd/lpd.conf, /etc/lpd/lpd.perms configuration files. - executables in /usr/bin, /usr/sbin, /usr/libexec/filters - you do not need any include files from /usr/local/include or libraries from /usr/local/lib - no Kerberos support Here is the contents of the STANDARD_configuration file: #!/bin/sh set -x if [ -d /usr/share/man ] ; then mandir="--mandir=/usr/share/man" fi sh ./configure --prefix=/usr --sysconfdir=/etc $mandir \ --disable-kerberos --enable-ssl --enable-force_localhost \ You can simply do: sh STANDARD_configuration make clean all (as root): make install checkpc -f USING CONFIGURE DEFAULTS DIRECTORIES By default, configure will put files in /usr/local/... directories. If you want to install LPRng in parallel with your existing printing system, you can have configure put the executables in the /usr/local/... locations: configure; make clean all (as root): make install checkpc -f The currently running LPD server must be shut down and the LPRng lpd server started. CAVEATS and WARNINGS: The LPRng software requires an ANSI C compiler and a make utility that is compatible with Gnu Make (verson 3.73 or later) or FreeBSD 4.2 or later. LPRng is compiled and tested using GCC and Gnu Make. INCLUDE FILES AND LIBRARIES If you are using GETOPT or Kerberos you may need to extend the search paths for include files and libraries. See the STANDARD_configuration and KERBEROS_configuration files for examples. Solaris Users: You can get precompiled versions of the GCC compiler and GNU Make from: www.sunfreeware.com The LPRng code has NOT been tested with the Sun Microsystems compilers, and NOT been tested with 64 bit support enabled. During compilation and installation, the PATH environment variable MUST have /usr/local/bin FIRST followed by /usr/ccs/bin: PATH=/usr/local/bin:/usr/ccs/bin:$PATH If you have ANY problems with compilation, and you are NOT using a 'clean' GCC installation, please install GCC from a package (see http://www.sunfreeware.com) or remove gcc and reinstall it. Make sure that the include files are correct for your version of Solaris. In fact, I recommend that you do the compilation on a 'clean' machine that has nothing but a 'virgin' Solaris Install + utilities BEFORE reporting problems. You have been warned. HPUX Users: See the following site for precompiled GCC and other tools: http://hpux.cae.wisc.edu/ I STRONGLY recommend installing GCC and using GCC. Make sure that your include files are the correct ones for your particular OS. If you use the native or HP provided C compiler, you will need to add some additional flags to allow ANSI C compatibility. The -Aa and -Ae are candidates, but you will have to check your particular compiler for details. Ryan Novosielski suggests that for HP-UX 11.0 and 11.11 you may need to use --with-linker=/usr/bin/ld You have been warned. EXTREMELY IMPORTANT WARNING FOR THE SANITY OF SYSADMINS It is extremely dangerous to use NFS mounted file systems for spool directories. The LPRng system depends on file locking for process coordination and synchronization. Given the historical evidence of problems with file locks and NFS, not to mention the terrible performance impact, it is strongly recommended that you use a local file system for your spool directories. You have been warned. SYSTEM STARTUP SCRIPTS There is a couple of system startup scripts in the conf/ directory of the LPRng source. (most with some instructions how to set them up, though those might be a bit out of date). CONFIGURATION The configure (autoconf) utility is used to specify the location of files and run time options for the LPRng software. configure (autoconf) defaults for files and directories: ${prefix} - default is /usr/local ${exec_prefix} - default is ${prefix} ${bindir} is usually ${exec_refix}/bin, (/usr/local/bin) ${sbindir} is usually ${exec_prefix}/sbin (/usr/local/sbin) ${libdir} is usually ${exec_prefix}/lib (/usr/local/lib) ${libexecdir} is usually ${exec_prefix}/libexec (/usr/local/libexec) ${sysconfdir} is usually ${prefix}/etc (/usr/local/etc) ${mandir} is usually ${prefix}/man (/usr/local/man) CONFIGURATION FILES: THIS PARAGAPH DOES NOT DESCRIBE THE CURRENT BEHAVIOUR All of the LPRng configuration files but printcap files go in ${sysconfdir}/lpd/, usually /etc/lpd/. The printcap file, for historical and backwards compatibility reasons, is is in ${sysconfdir}/printcap, i.e. - /etc/printcap. We install a sample lpd.conf, lpd.perms, and printcap files, sufficed with SAMPLESUFFIX, which is .sample by default: Default 'configure' locations (and installed example files): lpd.conf: /usr/local/etc/lpd/lpd.conf (/usr/local/etc/lpd/lpd.conf.sample) lpd.perms: /usr/local/etc/lpd/lpd.perms (/usr/local/etc/lpd/lpd.perms.sample) printcap: /usr/local/etc/printcap (/usr/local/etc/printcap.sample) Standard UNIX Configuration (and installed example files): lpd.conf: /etc/lpd/lpd.conf (/etc/lpd/lpd.conf.sample) lpd.perms: /etc/lpd/lpd.perms (/etc/lpd/lpd.perms.sample) printcap: /etc/printcap (/etc/printcap.sample) EXECUTABLES AND MAN PAGES: (* indicates SETUID root permissions, not set by current makefiles) ${bindir}/ lpr*, lprm*, lpq*, lpstat* ${sbindir}/lpc*, checkpc, lpd ${libexecdir}/filters/ lpf, banner, etc ${mandir}/ man pages CONFIGURATION OPTIONS In addition to the --prefix, etc., mentioned above, there are several more you can use: COMPILATION: Environment variables (also can be on command line): CC= C compiler command CFLAGS= C compiler flags LDFLAGS= linker flags, e.g. -L if you have libraries in a nonstandard directory CPPFLAGS= C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP= C preprocessor Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data [PREFIX/share] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --infodir=DIR info documentation [PREFIX/info] --mandir=DIR man documentation [PREFIX/man] --with-config_subdir=CONFIG_SUBDIR configuration subdirectory (default 'lpd') --with-lpddir=DIR lpd executable directory (default \${sbindir}) --with-lpd_conf_path=PATH path of lpd.conf (default: \${sysconfdir}/${CONFIG_SUBDIR}/lpd.conf) --with-lpd_perms_path=PATH path of lpd.perms (default: \${sysconfdir}/${CONFIG_SUBDIR}/lpd/lpd.perms) --with-printcap_path=PATH path of printcap (default \${sysconfdir}/printcap) --with-lpd_printcap_path=PATH path of lpd_printcap (default \${sysconfdir}/${CONFIG_SUBDIR}/lpd_printcap) --with-initpath=PATH path of lpd startup file (default /usr/local/etc/rc.d/lprng.sh) use 'no' to disable installation and lpd startup --with-lockfile=PATH lockfile PATH, default /var/run/lpd --with-filter-ld-libary-path=PATH filter LD_LIBRARY_PATH value, default empty (was /lib:/usr/lib:/usr/local/lib in earlier versions) --with-filter_path=PATH filter PATH value, default /bin:/usr/bin:/usr/local/bin --with-localedir=PATH specify locale information directory OPERATIONAL --disable-setuid do not install client executables setuid root --enable-priv_ports require connections from privileged ports --disable-force_localhost disable force_localhost default --disable-require_configfiles client programs require lpd.conf, printcap --enable-kerberos enable kerberos support --disable-kerberos_checks disable kerberos library location and checking for support --enable-nls use Native Language Support --enable-tcpwrappers use tcp wrappers (-lwrap) --disable-ssl disable ssl support --with-unix_socket_path=DIR unix socket path (default /var/run/lprng) --with-userid=NAME run LPRng software as this userid, default daemon --with-groupid=NAME run LPRng software as this groupid, default daemon --with-done_jobs=N retain last N job status, default 1 --with-done_jobs_max_age=N retain job status N seconds, default 0 - no expiry --with-filterdir=DIR filter directory (default \${libexecdir}/filters) --with-gnu-ld assume the C compiler uses GNU ld default=no --with-openssl=DIR root location for OpenSSL --with-openssl-inc OpenSSL include files --with-openssl-lib OpenSSL library files --with-ssl_ca_file=FILE ssl Certificate Authority CERT file (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.ca/ca.crt) --with-ssl_ca_key=KEY ssl Certificate Authority private key file (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.ca/ca.key) --with-ssl_certs_dir=DIR ssl Certificate Authority certs working directory (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.certs/) --with-ssl_crl_file=PATH ssl Certificate Revocation List File (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.crl/ssl.crl) --with-ssl_server_cert=FILE ssl server certificate file (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.server/server.crt) --with-ssl_server_password_file=FILE ssl server private key in password file (default \${sysconfdir}/${CONFIG_SUBDIR}/ssl.server/server.pwd) STARTING LPD SERVER AND CHECKING CONFIGURATION Use the following command to check to see that the LPD server is running on the localhost: #> lpc -s localhost lpd If it has not been started, then you can start it by hand: #> /usr/sbin/lpd INSTALLATION PROBLEMS If the installation step did not install the executables in the correct location or there are other problems, use the following procedures to fix up the install: # kill off the old server On BSD: kill `ps -aux |grep lpd | awk '{print $2}'` On System V: kill `ps -e |grep lpd | awk '{print $1}'` You should remove or rename the original lpd binaries if they have are still present: mv /usr/lib/lpd /usr/lib/lpd.old ln -s /usr/local/bin/lpd /usr/lib/lpd # you might want to track down the old lpr, lpq, lprm binaries find /usr -type file -name lp\* -print >/tmp/candidates find /sbin -type file -name lp\* -print >>/tmp/candidates # Examine the /tmp/candidates file, and remove or rename the # non-LPRng versions of the programs # remove or rename the candidate files /usr/local/sbin/lpd; # start up LPD OR /usr/sbin/lpd; # start up LPD OR /????/lpd # start up LPD lpq; # test it with LPQ If you are running on Solaris, see the Solaris section in the LPRng Reference Manual for further instructions on integration with the LP subsystem. PRINTCAP FILES: Read the comments in the /etc/printcap.sample for details on how to set up a simple set of printcap entries. You may also want to read the Printing Cookbook and the LPRng Reference Manual documentation. SECURITY WARNINGS: The default configuration for LPRng allows connections from any port while a strict RFC1179 implementation would require connections only from a port in the range 721-731. Relaxing this restriction allows non-setuid root clients (lpr, lpq, etc) to connect to the LPRng server. The following is the default LPRng system installation: 1. All client programs are installed Setuid Root. (NOT in the current version, yet undecided if that will come back) 2. No checking is done for strict RFC1179 conformance by the lpd server 3. By default, all client programs will connect to the server on the local host (force_localhost configuration option). This configuration allows you to connect directly to non-LPRng systems using the LPRng clients, and to have the maximum flexibility with the least amount of system configuration problems. You can modify the /etc/printcap file, and set 'force_localhost@' to send jobs to a remote print server which requires connections to originate from a privileged port. The described configuration has the drawback of having SETUID clients, which is regarded as dangerous . A more cautious approch is to use the following: 1. No LPRng programs are installed Setuid Root (configure --disable-setuid) 2. All clients communicate directly to the server on the localhost. (i.e. - force_localhost is used) 3. The server is started at system initialization time by root and it is the only program that opens a connection to a remote print spooler. This now reduces the problem to a much more manageable level. If you are truly paranoid then you should read the LPRng Refernece Manual and the Printing Cookbook sections on Authentication, and add either SSL or Kerberos authentication to your system. KERBEROS: LPRng uses the MIT Kerberos 5 distribution and provides backwards compatibility with the MIT Kerberos 4 print support system. If you want to use Kerberos authentication then configure with the following options: - for Kerberos 5 only: ./configure --enable-kerberos You may need to add the following if your libraries and include files are not in the 'usual' places. Replace /usr/local/lib with the directory where the Kerberos libraries are and /usr/local/include where the include files are. LDFLAGS="-L/usr/local/lib" \ CPPFLAGS="-I/usr/local/include" ******************** OVERRIDING CONFIGURES' GUESSES ****************** If you get errors similar to the ones below, it may be because "configure" guessed wrong. You can override the guesses here, by editing the file config.h configure generates or by adding the given options to your CFLAGS, e.g ./configure CFLAGS="-Wall -O2 -g -W -DMAKE_USE_STATFS=STATVFS -DMAKE_USE_STTY=TERMIOS" "recvfiles.c: unknown struct fsb has no size": define STATFS: to use statfs(2) (BSD) STATVFS: to use statvfs(2) (SVR4) others for system specific cases either modify USE_STATFS_TYPE in config.h or add one of: -DMAKE_USE_STATFS=ULTRIX_STATFS -DMAKE_USE_STATFS=SVR3_STATFS -DMAKE_USE_STATFS=STATVFS -DMAKE_USE_STATFS=STATFS define MAKE_USE_STTY = SGTTYB to use struct sgttyb and (BSD) TERMIO to use struct termio and (old sysV) TERMIOS to use struct termios and (SVR4) either modify USE_STTY in config.h or add one of: -DMAKE_USE_STTY=SGTTYB -DMAKE_USE_STTY=TERMIO -DMAKE_USE_STTY=TERMIOS a better way to do this is to edit the "ARGH" section of portable.h, and add the appropriate lines to the section for your OS, or add a new section if one doesn't exist; then you can send me the patches and I'll incorporate them into the distribution. SETPROCTITLE - overwrites the program argument information when ps is used, displays status. Used only by LPD if this does not work, add the following: -DNO_SETPROCTITLE ## ****** TESTING AND SECURITY LOOPHOLE ****************************** Define GETENV to allow the LPD_CONF environment variable to be used as the name of a configuration file. In non-testing systems, this is a security loophole. add -DGETENV=\"1\" lprng-3.8.B/aclocal.m40000644000131400013140000010737111531672265011460 00000000000000# generated automatically by aclocal 1.10.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(AC_AUTOCONF_VERSION, [2.61],, [m4_warning([this file was generated for autoconf 2.61. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # progtest.m4 serial 4 (gettext-0.14.2) dnl Copyright (C) 1996-2003, 2005 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl dnl This file can can be used in projects which are not available under dnl the GNU General Public License or the GNU Library General Public dnl License but which still want to provide support for the GNU gettext dnl functionality. dnl Please note that the actual code of the GNU gettext library is covered dnl by the GNU Library General Public License, and the rest of the GNU dnl gettext package package is covered by the GNU General Public License. dnl They are *not* in the public domain. dnl Authors: dnl Ulrich Drepper , 1996. AC_PREREQ(2.50) # Search path for a program which passes the given test. dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) AC_DEFUN([AM_PATH_PROG_WITH_TEST], [ # Prepare PATH_SEPARATOR. # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Find out how to test for executable files. Don't use a zero-byte file, # as systems may use methods other than mode bits to determine executability. cat >conf$$.file <<_ASEOF #! /bin/sh exit 0 _ASEOF chmod +x conf$$.file if test -x conf$$.file >/dev/null 2>&1; then ac_executable_p="test -x" else ac_executable_p="test -f" fi rm -f conf$$.file # Extract the first word of "$2", so it can be a program name with args. set dummy $2; ac_word=[$]2 AC_MSG_CHECKING([for $ac_word]) AC_CACHE_VAL(ac_cv_path_$1, [case "[$]$1" in [[\\/]]* | ?:[[\\/]]*) ac_cv_path_$1="[$]$1" # Let the user override the test with a path. ;; *) ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in ifelse([$5], , $PATH, [$5]); do IFS="$ac_save_IFS" test -z "$ac_dir" && ac_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD if [$3]; then ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" break 2 fi fi done done IFS="$ac_save_IFS" dnl If no 4th arg is given, leave the cache variable unset, dnl so AC_PATH_PROGS will keep looking. ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" ])dnl ;; esac])dnl $1="$ac_cv_path_$1" if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then AC_MSG_RESULT([$]$1) else AC_MSG_RESULT(no) fi AC_SUBST($1)dnl ]) # Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.10' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.10.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.10.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(AC_AUTOCONF_VERSION)]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf case $depmode in nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; none) break ;; esac # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. if depmode=$depmode \ source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 3 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [for mf in $CONFIG_FILES; do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 13 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.60])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) ]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"\$(SHELL) $am_aux_dir/install-sh"} AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering # Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 AC_DEFUN([AM_MAINTAINER_MODE], [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) dnl maintainer-mode is disabled by default AC_ARG_ENABLE(maintainer-mode, [ --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer], USE_MAINTAINER_MODE=$enableval, USE_MAINTAINER_MODE=no) AC_MSG_RESULT([$USE_MAINTAINER_MODE]) AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) MAINT=$MAINTAINER_MODE_TRUE AC_SUBST(MAINT)dnl ] ) AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo done .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # We grep out `Entering directory' and `Leaving directory' # messages which can occur if `w' ends up in MAKEFLAGS. # In particular we don't look at `^make:' because GNU make might # be invoked under some other name (usually "gmake"), in which # case it prints its new name instead of `make'. if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then am__include=include am__quote= _am_result=GNU fi # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then am__include=.include am__quote="\"" _am_result=BSD fi fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 3 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t $srcdir/configure conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([acinclude.m4]) lprng-3.8.B/man/0000777000131400013140000000000011531672402010437 500000000000000lprng-3.8.B/man/lpq.n0000644000131400013140000001534411531672130011333 00000000000000.TH LPQ 1 2007-02-24 "LPRng" "lpq command" .SH NAME lpq \- spool queue examination program .SH SYNOPSIS .B lpq .RB [ \-a ] .RB [ \-A ] .RB [ \-l ] .RB [ \-L ] .RB [ \-V ] .RB [ \-c ] .RB [ \-v ] .RB [ \-P .IR " printer" ] .RB [ \-s ] .RB [ -t .IR " sleeptime" ] .RB [ \-D .IR " debugopt" ] .RI [ jobid \|.\|.\|.] .SH DESCRIPTION .I lpq requests a status report from .IR lpd (8) on the specified printers or jobs. .I lpq invoked without any arguments reports on the printer given by the default printer (see .B \-P option). The short (default) format simply lists the printer, host, and numbers of jobs in the spool queue. When using the long format (-l option), for each job in a spool queue .I lpq reports the job identifier which is generated from the user's name and originating host, current rank in the queue, the job number (which may be supplied to .IR lprm (1) for removing a specific job), the job description information, and the total size in bytes. If there is an error or other problem with the job, this information may be modified to reflect the problems. In a spool queue, Job ordering is a modified FIFO (First in First Out), modified by the job class and priority information. .PP The following options are available. .TP .B \-A Use authentication specified by the value of the AUTH environment variable. .TP .BI "\-D " debugoptions Debugging is controlled using the .B \-D option. This accepts a comma-separated list of debugging settings. These settings take one of two forms: .B facility=value , or .B value to set an overall default value. .TP .BI "\-P " printer By default, the destination printer is taken from the command line .I printer value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .TP .B "\-V" Print version information. .TP .B "\-v" Dump lpd related information. .TP .B "\-c" Clear Screen before output, very usefull with \-t .TP .B "\-a" List status for all printers (see PRINTER LISTS below) which have entries for the LPRng client programs in the .IR printcap (5) database. .TP .B "\-l" Increase verbosity of the \fBl\fRong display format. A single -l options selects a short verbose display, multiple -l options increase the verbosity. .TP .B "\-L" Use maximum verbosity for the \fBl\fRong display format. .TP .B "\-s" Display a short, single line status summary for each queue and subqueue. .TP .BI "\-t " sleeptime Forces .I lpq to periodically display the spool queues and then sleep .I sleeptime seconds between scans of the queue. .IP "jobid ... all" The options are followed by a list of jobids which are used to select jobs of interest. A jobid can be a user name, a job identifier, a job number, or a glob based pattern which will be applied to the job identifiers. The all keyword will display all jobs and is the default option. .PP The .I lpq will report the status of the spool queue (enabled for spooling, disabled for unspooling), and the absence of a server if unspooling is enabled. The .IR lpc (1) command .I "lpc start " may be used to start the server if this is the case. .SH ENVIRONMENT By default, the destination printer is taken from the command line .I dest value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .SH "PRINTER LISTS" The .B -a option is used to by .IR lpq (1) to get status for a list of printers. This list is formed as follows. .IP 1) The printcap file is scanned for printer entries. Only entries with names starting with a letter or digit are recognized as valid queue or printer names. .IP 2) If the special entry .I all is present, and it has a field .I ":all=pr1@host1,pr2@host2,..." then the printers .IR pr1 , .IR pr2 , \&... are used as the printer or queue list. .IP 3) If there is no all entry, then the original list of printers found in step 1) is used as the list of printers. .PP The special case of .B "lpq -Pall" disables the searching of the printcap database, and simply sends a query to the lpd server for status of printer .BR all . The .IR lpd (8) server enumerates the printers in its printcap file, ignoring any .I all entry, and returns status only for printers which have entries in the .IR lpd (8) server printcap file. .PP Finally, the special case .B "lpq -Ppr@host" causes .IR lpq (1) to send a status request for printer .B pr to host .BR host . .PP Here is a simple set of rules to use: .nf .ft CW Client: pr1:lp=%P@server pr2:lp=%P@server - printer pr1 followed by pr2 pr1:lp=%P@server pr2:lp=%P@server all:all=pr2,pr1 - printer pr2 followed by pr1 (all overrides) Client: pr1:lp=%P@server pr2:lp=%P@server Server: lp:lp=... lpq -Pall - status returned only for printer 'lp' .fi .SH "EXIT STATUS" The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "PRINTCAP INFORMATION" The printer names and other information is obtained by using a printcap file or some other database. The ${HOME}/.printcap file can be used to specify user level options and configuration information. See .IR printcap (5) for more information. .SH FILES The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" .BR lpd.conf (5), .BR lpc (8), .BR lpd (8), .BR checkpc (8), .BR lpr (1), .BR lprm (1), .BR printcap (5), .BR lpd.perms (5), .BR pr (1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/psbanner.n0000644000131400013140000000002411531672130012334 00000000000000.so man1/lpbanner.1 lprng-3.8.B/man/cancel.n0000644000131400013140000000002011531672130011745 00000000000000.so man1/lprm.1 lprng-3.8.B/man/checkpc.n0000644000131400013140000000673611531672130012144 00000000000000.TH CHECKPC 8 2007-02-22 "LPRng" "checkpc command" .SH NAME checkpc \- check out the printcap database .SH SYNOPSIS .B checkpc .RB [ " \-aflprsV " ] .RB [ " \-A" \fIage\fP[ DHMS "] ]" .RB [ " \-D\fIdebugflags\fP " ] .RB [ " \-P\fIprinter\fP " ] .RB [ " \-t " \fIsize\fP[ kM "] ]" .SH DESCRIPTION .B Checkpc is used to check for the existence and correct permissions of entries in the .I printcap database. It is useful when installing a new printcap database and cleaning up existing printer spoolers. .TP .B \-a Do not create accounting files (:af). .TP .B \-f The fix flag will cause the checkpc program create and fix various files and permissions. It does this in a simple minded manner, and the program may have to be run several times until all permissions are correct. It also reports in extremely verbose details its actions. .TP .B \-l Do not create log files (:lf). .TP .B \-p Print verbose printcap information. Useful if interested in the printcap values. .TP .B \-r remove junk or job files older than the age set by -A. You must set the age to a non-zero value otherwise no files are removed. .TP .B \-s Do not create filter status files (:ps). .TP .B "\-A \fIAge\fR[\fBDHMS\fR]" Report junk or job files older than age. The age time can have a suffix days (D) hours (H), minutes (M), or seconds (S); default is days. .TP .BI "\-D " debugflags Run the program with debugging flags. See the LPRng HOWTO for details of the flags actions. .TP .B \-V Verbose mode. .TP .BI "\-P " printer Process only the specified print queue. .TP .B "\-t \fIsize\fR[\fBkM\fR]" Truncate log files (:lf) to the specified size in Kbytes or Mbytes (default is Mbytes). .TP .BI "\-T " serial-line set process name and start feature test .SH "ANNOYING FEATURES" If the .BR \-f (fix) option is specified and you do not run this as root, it will complain, but attempt to carry out the operations. This will lead to a large number of failures reports if the ownership and/or permissions are incorrect. .SH FILES The files used by LPRng are set by values in the printer configuration file and by configuration options. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" .BR lpd.conf (5), .BR lpc (8), .BR lpd (8), .BR lpr (1), .BR lpq (1), .BR lprm (1), .BR printcap (5), .BR lpd.perms (5), .BR pr (1), .BR lprng_certs (1), .BR lprng_index_certs (1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lpc.n0000644000131400013140000002640611531672130011316 00000000000000.ds VE LPRng-3.9.0 .TH LPC 8 \*(VE "LPRng" .ig lpc.1,v 3.36 1998/03/29 18:37:49 papowell Exp Mon Jul 17 20:14:17 PDT 1995 Patrick Powell .. .SH NAME lpc \- line printer control program .SH SYNOPSIS .B lpc [ .BI \-A ] [ .BI \-a ] [ .BI \-D debugopts ] [ .BI \-P printer ] [ .BI \-S server ] [ .BI \-U username ] [ .B \-V ] [ command [ argument ... ] ] .SH DESCRIPTION .I Lpc is used by the system administrator to control the operation of the line printer system. For each line printer configured in .I _PRINTCAP_PATH_ or the printcaps specified in the configuration file .I _LPD_CONF_PATH_ (see lpd.conf(5)), .I lpc may be used to: .IP \(bu 3 disable or enable a single or all printer, .IP \(bu 3 disable or enable a single printer's or all printer's spooling queue, .IP \(bu 3 move jobs to the top a queue .IP \(bu 3 find the status of printers, and their associated spooling queues and printer daemons, .IP \(bu 3 start and stop printer servers for a queue with multiple print servers, .IP \(bu 3 hold and release a specific job in a printer queue, .IP \(bu 3 redirect printing to another printer, .IP \(bu 3 restart a printer job after having solved printer problems and let it print from the beginning, .IP \(bu 3 reprint a job .PP Without any arguments, .I lpc will prompt for commands from the standard input. If arguments are supplied, .IR lpc interprets the first argument as a command and the remaining arguments as parameters to the command. Permission to use spool queue control commands is determined by the printer permissions file (See FILES). .SH OPERATION .PP The operation of each spool queue is controlled by a .I "spoolcontrol" file which has a set of keyword options and values. (Other print spoolers have used permissions bits of directories and files for similar purposes). In addition, each job in the spool queue can have a .I "holdfile" which contains detailed information on how the spooler is to treat the particular job. The server will update these files with status and other information as the job is processed. The .I lpc command operates by sending requests to the .I lpd server process to update the information in these files and to signal server processes that the information has been updated. .SH OPTIONS .IP "\fB\-A\fR" 5 Use authentication specified by the value of the AUTH environment variable. .IP "\fB\-a\fR" 5 Alias for -Pall. .IP "\fB\-P\fIprinter\fR" 5 Printer spool queue to operate on. if no name is given, the -P option, the printer selected by the value of the PRINTER environment variable, or the first entry in the printcap file will be used. When all printers are selected, the LPC command will first attempt to find the printcap entry for printer ``all''; the .I all printcap field value will be a list of printers to control. If there is no printcap entry, then the request is directly forwarded to the default LPD host, which will do a lookup for all of the available printers. By specifying ``all@host'', the user can control all printers on a given host. .IP "\fB\-S\fIserver\fR" 5 Send commands to this server, rather than the one specified by the \fB\-P\fIprinter\fR" or printcap entry. This allows you to use a default printcap entry for authentication information or other setup information, but direct queries to a specific server. .IP "\fB\-V\fR" 5 Print program version information .IP "\fB\-U\fIusername\fP\fR" 5 Set the user name for the request. This option is available only to user root or to the userids listed in the .I allow_user_setting configuration option. .IP "\fB\-D\fIdebugopts\fP" 5 Debugging is controlled using the .B \-D option. This accepts a comma-separated list of debugging settings. These settings take one of two forms: .B facility=value , or .B value to set an overall default value. The form -D= will display a list of debugging options. .SH COMMANDS .PP The following is the alphabetical list of recognized commands. The jobcontrol or holdfile fields effective are listed as part of the command. .TP ? .br Help. Also, any unrecognized input produces a help listing. .TP active [pr@[host]] .br makes a connection to the LPD server for the specified printer. Closes the connection after making it. This is useful for checking to see if a non-LPRng server is active. .TP abort { all | printer* } .br Kill the active job and disables unspooling. The active job will not be deleted from the queue. .br Action: kills server process, updates spool control file .I printing_disabled field. .TP class {all | printer } (off | classlist | X=globmatch) .br Controls the class of jobs currently being printed. The .I off option removes any class restrictions. The classlist option is a list of classes; for example A,B,C would release classes A, B, and C for printing. The X=globmatch form performs a match against a control file entry starting with the indicated capital letter. For example, J=*form1* would allow jobs which had the string form1 in their job title to be printed. .TP defaultq .br Lists the default queue for the LPC program. .TP defaults .br Lists default values for the configuration information. .TP debug j all | printer } [string | off ] .br Set the debugging string for the specified printer. This is a diagnostic aid and should be used with caution; refer to the reference manual for details of the debugging string format. In general, you can use: .br .I INTEGER \- the integer number sets the general debugging level .br keyword=value .br \- sets a debugging variable to a specified value .br keyword \- sets a debugging flag .br Action: updates spool control file .I debug field. .TP disable { all | printer } .br Disable spooling to the specified spool queues. See .I enable. .br Action: updates spool control file .I printing_disabled field. .TP down {all | printer } .br Disable both queuing and printing for all printers or the selected printer. See .I up. .br Action: updates spool control file .I printing_disabled and .I spooling_disabled fields. .TP enable { all | printer } .br Enable spooling for all printers or the selected printer. .br Action: updates spool control file .I spooling_disabled field. .TP exit or quit .br terminate LPC program .TP help .br Print a short help message. .TP hold printer { jobid } .br Holds the specified printer job (or jobs) in the queue. The job will not be printed even if spooling and printing is enabled. It must be released with the release command. The holdall command or :ah: printcap flag can enable automatic holding of spooled jobs. .br Action: updates job holdfile .I hold field with time that job was held. A 0 value release job for printing. .TP holdall { all | printer ... } .br Turn on automatic job holding of new jobs. New jobs will be marked as held, and held until released with the release command. This will be done until holdall is turned off with the noholdall command. The :ah: printcap flag can enable automatic holding as well. .br Action: updates spool control file .I holdall field. .TP kill { all | printer ... } .br Do an abort command followed by a start command. This is a quick way to kill off a server that has problems. Note that due to race conditions and delays, that the start command may not be effective this action should be monitored to ensure that the job restarts. .TP client { all | printer ... } .br Show the LPRng client configuration and printcap information on the local host. This is an extremely useful diagnostic tool. .TP lpd [printer@[host]] .br determines if LPD daemon process on the print server is running, and gets the PID. This is handy to determine if the LPD daemon was killed or aborted due to abnormal conditions. .TP lpq printer [options] .br Run .I lpq from inside the .I lpc program. .TP lprm printer jobid [jobid]* .br Run .I lprm from inside the .I lpc program. Not all options are supported - this form requires the printer name and jobid to be specified explicitly. .TP move printer jobid destinationPrinter .br Send the specified jobs to the destination printer and remove them from the printer queue. .br Action: updates the job holdfile .I move field with the destination and starts a server process to do the job transfer. .TP msg printer message text .br Update the status message for the printer. An empty message will remove the status message. .TP noholdall { all | printer* } .br Turn off automatic job holding. See holdall command. .TP quit or exit .br terminate LPC program .TP redirect [printer [destinationPrinter | off ]] .br redirect the jobs in the printer queue to another printer or turn redirection off. .br Action: updates spool control file .I redirect field. .TP redo [printer [jobid]] .br Reprint the selected job. .TP release [printer [jobid]] .br Releases the selected job for printing. .TP reread [ printer [@host] ] .br Sends a request to the LPD server for the printer to reread the configuration and printcap information. This is equivalent to using kill -HUP serverpid, but can be done for servers on remote hosts. .TP server { all | printer } .br Shows the printcap entries for the printer or all printers as the LPD server would use them. .TP start { all | printer } .br Start the printer. This is useful when some abnormal condition causes the server to terminate unexpectedly leaving jobs in the queue. .I Lpq will report that there is no daemon present when this condition occurs. .TP status { all | printer } Display the status of daemons and queues on the local machine. .TP stop { all | printer } .br Disable any further unspooling after the current job completes. .TP topq printer [ jobid ] .br Place the selected jobs at the top of the printer queue. .TP up {all | printer ...} Enables queuing and printing for the specified or all printers. Privileged. .SH JOBIDS .PP The LPQ command displays a job identifier for each job, which can be used in LPC commands to identify a specific job. In the commands descriptions above, the jobid can be a user name, a job number, a job identifier, or a glob pattern. The glob pattern is matched against the job identifier. In command which have an optional jobid, if none is specified then the first printable job in the queue is acted on. .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpd.conf(5), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.perms(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH DIAGNOSTICS .nf Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .fi .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng mailing list is lprng@lprng.com; subscribe by sending mail to lprng-request@lprng.com with the word subscribe in the body. The software is available from ftp://ftp.lprng.com/pub/LPRng. .SH "AUTHOR" Patrick Powell . lprng-3.8.B/man/pclbanner.n0000644000131400013140000000002411531672130012470 00000000000000.so man1/lpbanner.1 lprng-3.8.B/man/lpr.n0000644000131400013140000002722211531672130011332 00000000000000.TH LPR 1 2006-12-09 "LPRng" "lpr command" .SH NAME lpr \- off line print .SH SYNOPSIS .B lpr [ .B \-A ] [ .B \-B ] [ .B \-b,l ] [ .BI \-C " class" ] [ .BI \-D " debugopt" ] .ti +5n [ .BI \-F " filterformat" ] [ .B \-G ] [ .B \-h ] [ .BI \-i " indentcols" ] .ti +5n [ .B \-k ] [ .BI \-J " job" ] [ .BI \-K,# " copies" ] .ti +5n [ .BI \-m " mailTo" ] [ .BI \-P " printer" ] [ .B \-r ] .ti +5n [ .BI \-R " remoteAccount" ] [ .B \-s ] [ .BI \-T " title" ] [ .BI \-U " user" ] .ti +5n [ .B \-V ] [ .BI \-w " width" ] [ .BI \-X " userfile" ] [ .B \-Y ] [ .BI \-Z " options" ] [ .BI \-1,2,3,4 " font" ] [ .B \-\- ] .ti +5n [ .IR filename " \|.\|.\|." ] .SH DESCRIPTION .B Lpr uses a spooling daemon to print the named files when facilities become available. If no names appear, the standard input is assumed. .SH OPTIONS .TP 5 .B \-A The authentication type is set by the value of the AUTH environment variable. .TP 5 .B \-B Do filtering of job files by the filters specified by the printcap. Combine the output of the filtering operation into a single job file and then send the single file to the lpd print spooler. .TP 5 .B "\-b, \-l" either of these flags specifies a binary or literal file, and no (or minimal) processing is to be done by the print spooling system. Printed using the .I f format filter (:if=... or :filter=...). .TP 5 .BI \-C " class" Specify the job classification for use on the burst page and to set the priority. Priorities range from A (lowest) to Z (highest); the default priority is A. For example, .br .ti +0.5i lpr \-C B foo.c .br sets the priority/class to B and the file foo.c is printed. .TP 5 \fB\-D\fP\ \fIdebugoptions\fP Debugging is controlled using the .B \-D option. This accepts a comma-separated list of debugging settings. These settings take one of two forms: .BI facility =value, or .B value to set an overall default value. .TP 5 \fB\-F\fI filterformat\fR Filter or format specification. By default, input is assumed to a standard text file and the .I f format is used; the output device is assumed to be a simple line printer. Other formats available are listed below. Not all formats may be available on all printers; see .BR printcap (5) for details. Formats are single lower case letters; the following are the valid arguments for .B \-F together with the assumed type of data. For compatibility with previous versions of .BR lpr , the format types can be used as options themselves (i.e. by omitting the .BR F ) except where noted below, a warning may be issued in such cases. .\".RS 5 .TP 5 \fB\-G\fP Similar to the \fB\-B\fP option, but only processes individual files. .TP 5 \fB\-h\fP No banner or header for this job. .TP 5 .BI \-i " indentcols" Indent input by indentcols. Note that this option is not supported on all printers. .TP 5 .BI -J " jobname" Specify the job name to print on the burst page; defaults to the name of files in the job or .I "(STDIN)" if input is from a pipe. .TP 5 \fB\-K\fP\fIcopies\fP,\0\fB\-#\fP\fIcopies\fP Specify the number of copies of each file to be printed. You may or may not get the requested number of copies depending on the intelligence of the remote printing system. .TP 5 .B \-k .B lpr normally creates a temporary file for the input read from stdin before sending it to the remote printer. The .B \-k (kut-through) option will simply copy from STDIN to the destination print spooling system. If you kill the job in the middle of creation then the partly transferred file will get printed. This option may not work with very large jobs, non-LPRng spoolers, or when you have encryption or authentication enabled. .TP 5 .BI \-m " mailTo" Send mail upon unsuccessful completion to user .IR mailTo . The mailTo value has been used to do such things as specify email (user@host), paging (page:user@host), both (user@host,page:user@host) and all sorts of other notifier information. See the LPRng HOWTO for details on how this is implemented. .TP 5 .BI \-P " printer" By default, the destination printer is taken from the command line .I "-P printer" value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .TP 5 .BI \-R " remoteAccount" Specify accounting information to be used by a remote system that prints your output. .sp This parameter can be used to specify a billing code to be charged for the printing. .TP 5 .B \-r The DREADED .B "REMOVE AFTER PRINTING" option. Beware, for .I lpr will delete the files after spooling them. Present by demand from users for compatibility with other Berkeley lpr implementation, but really should NOT be present. .TP 5 .BI \-T " title" Specify the title used by .BR pr (1); defaults to the file name. .TP 5 \fB\-U\fP\ \fIusername\fP The .B \-U option is used to specify a user name for the job. This is available only to ROOT or users listed in the .I allow_user_setting configuration option. This is obviously a security loophole, but it is present to allow systems such as SAMBA to submit jobs on behalf of users. See .B "Authenticated Transfers" below. .TP 5 .B \-V Verbose mode. Additional -V flags increase verbosity. Use debug flags for extreme verbosity. .TP 5 .BI \-w " width" Specify the page width for printing the job. .TP 5 .BI \-X " path" User specified filter for job files. Processing is done on the client host. .TP 5 .B \-Y Make a direct connection to the printer device and do not spool. .TP 5 .BI -Z " options" Pass the specified options to the print spooler. Used when additional or specialized information must be provided to the spooler. .TP 5 .B "OBSOLETE OPTIONS Lower case \-c, \-d, \-g, \-n, \-t, \-v" Used to indicate: .B \-c is data produced by .BR cifplot (l), .B \-d is .BR tex (l) (DVI format from Stanford), .B \-g is standard plot data as produced by the .BR plot (3X) routines, .B \-n and .B \-t is output from (device independent) .BR troff , .B \-v a raster image for devices like the Benson Varian. .B "These are obsolete." These are retained for historical compatibility, but most of their functionality has been replaced by the abilities of the printer support system to determine the file type and do the appropriate conversions. .\".RE .TP 5 .B "OBSOLETE OPTION \-p" .B "This is obsolete." This option is retained for historical compatibility, but this functionality should be implemented on the client system before sending the job to the printer. Use .BR pr (1) to format the files, then print using .I f format. This may not be supported on the print system. .TP 5 .B "OBSOLETE \-s" This flag is included for compatibility with other versions of .BR lpr . In these versions it will create a symbolic link to the files to be printed. .B Lpr now sends files directly to the server and it is irrelevant. .TP 5 .BI "OBSOLETE OPTIONS \-1,2,3,4" "fontname" Specify a font to be mounted on font position \fIi\fR for TROFF printing (Obsolete). .SH FILENAMES .PP By default, if no filenames are specified .B lpr will read stdin and print it. .SH "AUTHENTICATED TRANSFERS" .PP The original LPR network protocol defined in RFC1179 did not provide for user to server authentication. This is now supported by LPRng. See the LPRng support documentation for details on its operation and support. .SH COMPATIBILITY .PP The LPRng version of .B lpr attempts to be functionally compatible with common implementations of .BR lpr . However, there are some commands and functionality that are deliberately missing. .IP "\fB\-s\fP\ Symbolic Links" 5 (Berkeley LPR) This option specified that a symbolic link to the original data file rather than a copy of the data file was to be used when spooling jobs. This opens up a variety of security problems, as well as being ineffective when printing to a remote host. .SH "THE -B, -Y, -X filter ULTRA-LIGHTWEIGHT PRINTING OPTIONS" .PP LPRng supports ultra-lightweight printing by eliminating the need for a print spooler. This is quite dangerous, but makes the lpr client very lightweight. The .B \-Y command line option and the .B :direct printcap option enables lpr to connect directly to a specified port or use a program to send a job. This filter also enables client side filtering, so if there are any filters specified in the printcap entry they will be used. For example: .nf lpr -Y -Phost%port file1 file2 ... approximately equivalent to: for i in file1 file2 ...; do ${filter} <$i; # ${filter} is filter from printcap done >host%port (TCP/IP connection) lpr -Y -Phost%port -X userfilter file1 file2 ... approximately equivalent to: for i in file1 file2 ...; do userfilter <$i; done >host%port (TCP/IP connection) Summary: -P host%port > TCP/IP connection to host%port -P /dev/lp > /dev/lp -P '|/program' | /program SPECIAL CASE lpr -Y -Ppr@host -X userfilter file1 file2 ... approximately equivalent to: for i in file1 file2 ...; do userfilter <$i >temp.$i; done lpr -Ppr@host temp.file1 temp.file2 .fi .PP The .B \-B option or the :lpr_bounce is used to filter and make a single file out of a set of print files and then forward them. .RS .nf lpr -B -Ppr@host approximately equivalent to: lpr -Y -P/tmp/tempfile file1 file2 ... lpr -Ppr@host /tmp/tempfile .fi .RE .PP You can also use a printcap entry and the .B :direct options. .RS .nf Printcap: lp:direct:lp=h14%9100:remote_support=R lpr -Plp file1 file2 Same as: lpr -Plp -Y -Ph14%9100 file1 file2 .fi .RE .PP The .B :remote_support option is used to prevent the .B lpq and .B lpc program from attempting to send jobs to the device. .SH ENVIRONMENT .PP By default, the destination printer is taken from the command line .I "-P printer" value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "PRINTCAP INFORMATION" .LP The printer names and other information is obtained by using a printcap file or some other database. The ${HOME}/.printcap file can be used to specify user level options and configuration information. See printcap(5) for more information. .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" .BR lpd.conf (5), .BR lpc (8), .BR lpd (8), .BR checkpc (8), .BR lpq (1), .BR lprm (1), .BR checkpc (8), .BR printcap (5), .BR lpd.perms (5), .BR pr (1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lp.n0000644000131400013140000000275011531672130011147 00000000000000.TH LP 1 2006-12-09 "LPRng" "lp command" .SH NAME lp \- compatibility way to feed print jobs to the print daemon. .SH SYNOPSIS .BR lp " [" \-ckmprswBGY "] [" .BI "\-d " printer ] [ .BI "\-D " dbglvl ] [ .BI "\-f " class ] [ .BI "\-n " num ] [ .BI "\-q " prio ] [ .BI "\-t " title ] .I files .SH DESCRIPTION .B lp is a (partial) simulation for the Solaris SystemV R4 print facilities and implemented as link to .B lpr which behaves differently when invoked with this name. Please use .B lpr directly instead of this program. .SH OPTIONS A description of the options is still missing. .SH "SEE ALSO" .BR lpr (1). .SH "AUTHOR" LPRng was written by Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net .\" This manpage-stub is written by Bernhard R. Link .\" and available under GNU GPL v2 and any license LPRng is available under. lprng-3.8.B/man/lpd.n0000644000131400013140000015470211531672130011320 00000000000000.TH LPD 8 2008-03-14 "LPRng" "lpd daemon" .hy 0 .de NP .IP \\n(nP .nr nP \\n(nP+1 .. .de np .nr nP 1 .. .de L .ie !"\\$1"" \{\ .ft CW \&\\s-2\\$1\\s+2\\fP\\$2 .ft R .\} .el \{\ .ft CW .ps -2 .\} .. .SH NAME lpd \- line printer daemon .SH SYNOPSIS .B lpd .RB [ \-L .IR logfile ] .RB [ \-F ] .RB [ \-V ] .RB [ \-D .IR debugopt ] .RB [ -p .IR port ] .SH DESCRIPTION The lpd program is the printer server program of the LPRng software suite. This software is an enhanced and modified version of the Berkeley LPD software. .SH OPTIONS .TP .BI \-L " logfile" specifies an alternate file to be used for logging error and debugging messages. The .IR syslog (8) facility is used to log critical messages as well. Please note that you need to create the file by yourself, a 'touch' is sufficient. This is needed for security reasons. .TP .B \-F Under normal operation, the LPD server will run in background mode. The -F flag forces it to run in foreground mode, where it is more easily debugged. .TP .B \-V Print program version information. .TP .BI \-D " debugopt" Debugging is controlled using the .B \-D option. This accepts a comma-separated list of debugging settings. These settings take one of two forms: .B facility=value , or .B value to set an overall default value. The available facilities can be determined by invoking LPD with the \-D= parameter. .TP .BI \-p " port" Bind to the specified port rather than port 515 specified by RFC1179. .SH OPERATION .PP .I Lpd is the line printer daemon (spool queue handler) and is normally invoked at boot time from the .IR rc (8) file; it can also be started by a user. Note that the lpd server needs only run on systems where actual printing or spooling is taking place. .IR lpr (1) and other related programs transfer files using network facilities to the .IR lpd . .PP When started, .I lpd reads a configuration file to obtain basic operational parameters and then reads the .IR printcap (5) database information to determine the which printers have spool queues and to start spool queue server processes. If running as a background server, it will disconnect from its control terminal and run in the background. It uses the system calls .IR listen (2) and .IR accept (2) to receive requests to print files in the queue, transfer files to the spooling area, display the queue, remove jobs from the queue, or perform a spool queue control function. In each case it creates one or more server processes to handle the request and the lpd process will listen for more requests. .PP Sending the server a SIGHUP signal causes the server to reread the various configuration and inititialization files. This action is similar to that of the .I INETD and other servers. The same action is taken when sent a .I reread command by the .IR lpc (1) program. At an interval specified by the .I poll_time configuration variable, .I lpd will check for spool queues with jobs and no printing activity, and start printing. .PP LPD access control is done using a rule set and match algorithm similar to a packet filter. Each request for printing, status, or control operations is matched against the rule set, and the first ACCEPT or REJECT value determines if the operation can be performed. The following is a typical permissions file: .RS .nf .L # Set default permissions DEFAULT ACCEPT # Reject any connections from outside our subnet REJECT SERVICE=X NOT IP=130.191.0.0/255.255.0.0 # Only accept Printing (P) and spooling (LPR) from # the private network, the 10.0.0.0/8 network and fw REJECT SERVICE=P,R NOT REMOTEHOST=*.private,10.0.0.0/8,fw.astart.com # Do not accept forwarded jobs for printing REJECT SERVICE=P FORWARD # Allow only the administrators control access ACCEPT SERVICE=C,M REMOTEHOST=spooler.astart.com USER=root,papowell ACCEPT SERVICE=C,M SERVER REMOTEUSER=root,papowell # Allow only the user on the same host who spooled job to remove it ACCEPT SERVICE=M SAMEUSER SAMEHOST REJECT SERVICE=M,C .RE .fi .sp .LP Permission checking is done by using a set of keys (or fields) with associated values to check for permission. The SERVICE key has value P for printing (i.e.- unspooling), R for spooling (i.e.- LPR request), C and S for printer control and status respectively (i.e.- LPC request), M for removal (i.e.- LPRM request), Q for queue information (i.e.- LPRM request), and so forth. The .B X key indicates the initial connection to the LPD spooler, and can be used to control connections from remote systems. The values of the USER, HOST, and IP keys taken from the control file which is being received or checked for permissions. The REMOTEUSER, REMOTEHOST and REMOTEIP keys are those either sent as part of a command, or derived from information about the current network connection. Each line of the permissions file is scanned for key names and values, and these are matched against the request keys information. When all matches on a line are made, then search terminates with the specified action (ACCEPT/REJECT). If no match is found the default permission value is used. The DEFAULT key is used to specify the current default permission to be used for successful matches or if there is no match after scanning the entire permissions database. .LP The GROUP entry is used to check that the USER name appears in a group entry in the system user group database. For example, GROUP=student*,staff* would check to see if any of the group name matching student* or staff* have the specified user name in them. If a system has the .I netgroups capability, a group name starting with a \f(CW@\fR will be treated as a netgroup name, and current user name from the job file will be checked to see if it is in the group. Similarly, the REMOTEGROUP entry will check a remote user name. The PORT entry can be used to ensure that a connection to the server originates from a specified range of ports. For more details, see the .BR lpd.perm (5) man page. .LP The permissions database is scanned in order of the fixed file entries and then by invoking the specified filters for each of the permissions lists. It is recommended that the filters be placed at the end of the permissions lists. The user name is one of the parameters passed to the filter, and can be used to determine if a user has permissions to print a file. .sp .nf .ne 20v .ta \w'Key__________'u +\w'Match_'u +\w'Connect_'u +\w'Job___'u +\w'Job____'u +\w'LPQ__'u +\w'LPRM__'u +\w'LPC'u Key Match Connect Job Job LPQ LPRM LPC \0 \0 \0 Spool Print SERVICE S 'X' 'R' 'P' 'Q' 'M' 'C,S' USER S - JUSR JUSR JUSR JUSR JUSR HOST S RH JH JH JH JH JH GROUP S - JUSR JUSR JUSR JUSR JUSR IP IP RIP JIP JIP RIP JIP JIP PORT N PORT PORT - PORT PORT PORT REMOTEUSER S - JUSR JUSR JUSR CUSR CUSR REMOTEHOST S RH RH JH RH RH RH REMOTEGROUP S - JUSR JUSR JUSR CUSR CUSR REMOTEIP IP RIP RIP JIP RIP RIP RIP CONTROLLINE S - CL CL CL CL CL PRINTER S - PR PR PR PR PR FORWARD V - SA - - SA SA SA SAMEHOST V - SA - SA SA SA SAMEUSER V - - - SU SU SU SERVER V - SV - SV SV SV AUTH V - AU - AU AU AU AUTHTYPE S - AU - AU AU AU AUTHUSER S - AU - AU AU AU FWDUSER S - AU - AU AU AU .ta 3m +\w'RH = REMOTEHOST 'u KEY: JH = HOST host in control file RH = REMOTEHOST connecting host name JUSR = USER user in control file CUSR = REMOTEUSER user from control request JIP= IP IP address of host in control file RIP= REMOTEIP IP address of requesting host PORT= connecting host origination port CONTROLLINE= pattern match of control line in control file FW= IP of source of request = IP of host in control file SA= IP of source of request = IP of host in control file SU= user from request = user in control file SA= IP of source of request = IP of server host SV= matches if remote host is the server AU= authentication information IFIP= IP address of remote end of connection Match: S = string with wild card, IP = IP address[/netmask], N = low[-high] number range, V = exact value match SERVICE: 'X' - Connection request; 'R' - lpr request from remote host; 'P' - print job in queue; 'Q' - lpq request, 'M' - lprm request; 'C' - lpc spool control request; 'S' - lpc spool status request NOTE: when printing (P action), the remote and job check values (i.e. - RUSR, JUSR) are identical. .fi .sp .PP The special key .I letter=patterns searches the control file line starting with the (upper case) letter, and is usually used with printing and spooling checks. For example, C=A*,B* would check that the class information (i.e.- line in the control file starting with C) had a value starting with A or B. .SH "PERMISSIONS, MULTIHOMED HOSTS, IPV6" .PP There is a subtle problem with names and IP addresses which are obtained for 'multi-homed hosts', i.e. - those with multiple Ethernet interfaces, and for IPV6 (IP Version 6), in which a host can have multiple addresses, and for the normal host which can have both a short name and a fully qualified domain name. In addition, a host can have multiple IP addresses, depending on the complexity of its configuration. .PP The IFIP (interface IP) field can be used to check the IP address of the origination of the request, as reported by the information returned by the accept() system call. Note that this information may be IPV4 or IPV6 information, depending on the origination of the system. This information is used by gethostbyaddr() to obtain the originating host fully qualified domain name (FQDN) and set of IP addresses. Note that this FQDN will be for the originating interface, and may not be the canonical host name. Some systems which use the Domain Name Server (DNS) system may add the canonical system name as an alias. .PP When performing an IP address match, the entire list of IP addresses for a system will now be checked. If one of these matches, then success is reported. Similarly, the entire list of host names and aliases will be checked. If one of these matches, then success will be reported. .PP In addition, when checking for printing, if the name lookup for the host reported in the control file fails, then we assume that the host is unknown and all match checks for names or IP addresses will fail. You can determine if a host has an entry by using the following check, which will reject all requests from a remotehost which does not have a DNS entry. .br REJECT NOT REMOTEHOST=* .br .SH "PRINTCAP DATABASE" Individual printer operations are controlled by values in the printcap database. See .IR printcap (5) for details of the format and content of the various entries. The following are typical printer entries for a local and remote printer. .RS .sp .nf .ft CW # main or shared printcap file - usually /etc/printcap # remote postscript printer fullpage |postscript :lp=postscript@farside.astart.com # give access to (remote) hosts t1|postscript2 :cm=Test Printer 1 :lp=postscript2@nearside.astart.com # local printcap file # specification for local printer on nearside t1|postscript2 :oh=nearside.astart.com :cd=/usr/spool/LPD/safe :sd=/usr/spool/LPD/t1 # # /usr/spool/LPD/t1/printcap file - t1: :lp=/dev/pr :if=/usr/lib/pr/if :of=/usr/lib/pr/if .RE .sp .fi .PP Printcap information can be distributed by individual files or shared using NSF, YP, or other methods; see .IR lpd.conf (5) for the exact details of the location of printcap files and programs, given by the .I printcap_path and .I lpd_printcap_path configuration information. The usual printcap configuration is to have a main (shared) printcap database which is used by all hosts. The printcap information is usually extremely simple, consisting only of the printer name and host (i.e. - fullpage printer entry). .PP On hosts which have printers attached or which are to provide spooling queue directories, more extensive printcap information is needed. In the shared database, .I oh (options for specified host only) field restricts use of this entry to the specified host. This entry can contain host specific information, such as the location of the spool queue and/or actual device to be used for output. .PP In the above example, the main printcap file, _PRINTCAP_PATH_ has entries for all printers. Note that these entries do not specify the spool directories (sd and cd fields), but this could be provided. On a host with a printer specific information can be provided in several ways. The simplest is to simply put an additional entry in the shared printcap file, with the .I oh field set to the support host name. An alternative would be to specify the spool directories (sd and cd fields) in the shared information, and to put the printer specific information in a printcap file. .PP In addition to the .I oh flag, the .I server flag indicates that this entry is for a the LPD server only. This can be used to simplify the management of client and server entries. .PP The printcap information is obtained in the following order. If the lpd_printcap_path configuration value is nonblank then the lpd server will process only this information otherwise it uses the printcap_path information. All client programs use the contents of the configuration printcap_path variable to get a list of locations of printcap files. Each of these entries in the path lists are processed, and the printcap information is extracted. Entries which have .I oh fields are only used by the specified host. The files and information is processed in linear order, later entries overriding preceeding ones. .PP When processing jobs or performing spool queue specific requests, the LPD server will check to see if there is a printcap file in the control directory for the spool queue and the contents will be processed. Since only the LPD server has access to the spool and control queues, this information is processed only by the server. .PP In addition to files, printcap information can be obtained from programs or filters. For example, the printcap_path of the form .L /etc/printcap:|/usr/lib/getpr will use the contents of the .L /etc/printcap file, and then use the .L /usr/lib/getpr program to get information about a specific printer. When information about a particular spool queue is needed and one or more filters are specified as the source of printcap information, then the filter will be started and the printer name written on its standard input. The filter must provide a printcap entry for the requested printer on its standard output. .PP The filter can be used to interface to databases or nonstandard information sources which do not produce printcap information in an acceptable form. .SH "SPOOL DIRECTORY CONTENTS" .PP Each spool queue has a spool directory (sd) and optional control directory (cd) where job and control information is kept. Under normal operation the spool and control directories are identical, but if the spool directory is NFS exported for use by other printer spoolers which write files directly into the spool queue, then it is recommended that the control directory be a separate directory and not NFS mounted. The following files are used for printer operations. Per job entries are marked with an asterisk (*). .sp .nf .ta 20n +8n +4n File Name Dir Purpose printer CD lock file and server process PID unspooler.printer CD subserver process PID control.printer CD queue control information *hfAnnn SD job hold file *cfAnnnHOST SD job control file *dfAnnnHOST SD job data file *bfAnnn.* SD temporary files .sp .fi .PP The nnn in the file names stands for the job number. RFC1179 requires this to be a 3 digit number, but the longnumber printcap flag or a nonzero longnumber configuration variable will enable 6 digit numbers. .PP The lock file is used to prevent multiple job queue servers from becoming active simultaneously, and to store the server process id. The lock file name is the name as the printer name; all other control files have the printer name appended as indicated above. .PP The printer spool control file contains information controlling the queue operations. It consists of a series of lines with keywords and values to control printing, spooling, and automatic job holding operations. The following is an example of a typical spool control file. .sp .nf .RS spooling_disabled 0 printing_disabled 1 holdall 0 redirect p1@host2 debug 10,log=/tmp/log class A .RE .sp .fi .PP The .I spooling_disabled and .I printing_disabled entries control spooling and printing; the lpc .I enable, .I disable, .I start, and .I stop command alter these values. The .I holdall entry will prevent jobs from being processed until released with the lpc .I hold or .I release comands; the lpc .I holdall and .I noholdall commands alter these values. .PP The .I redirect entry causes the lpd server to forward jobs to the specified remote printer; the lpc .I redirect command alters this field. The .I class field controls the class of jobs being printed. By default, the class value is a pattern that matches the class entry in a job file; however a entry of the form .I letter=patterns will print jobs whose control file line starting with .I letter matches one of the patterns. The .I debug line provides a set of debugging parameters for diagnostic information for the particular spool queue. .PP Each print job consists of a control file and one or more data files. Lines in the control file file specify the job data files or parameters for the job and the general format of the file is specified by RFC1179. Each line consists of a flag character and a parameter; upper case and digit characters specify options and lower case letters specify the printing format and names of data files. The following is a list of the control file flag characters. .sp .IP A Identifier A job identifier to be used when displaying job information and/or status. The insertion of this line is controlled by the .I use_identifier printcap/configuration variable. .sp .IP C Class String to be used for the class line on the burst page. .IP H Host Name. Name of the machine where .I lpr was invoked. .IP I Indent. The number of characters to indent the output by (in ascii). .IP J Job Name. String to be used for the job name on the burst page. .IP L Banner user name. Information for banner page. .IP P Person. Login name of the person who invoked .IR lpr . This is used to verify ownership by .IR lprm . .IP M Send mail to the specified user when the current print job completes. .IP N File name. The original name of a data file which is in the job. .IP T Title. String to be used as the title for .IR pr (1) when the LPR -p option was specified. .IP U Unlink. Job file to remove when printing completed. .IP W Width. The page width (in characters) to used for printing. .IP Z zoptions. Options passed by .IR lpr .IR -Zzoptions. These are passed to output filters to aid in printing. .IP f Formatted File. Name of a file to print which is already formatted. .IP l Like ``f'' but passes control characters and does not make page breaks. .IP p Name of a file to print using .IR pr (1) as a filter. .IP t Troff File. The file contains .IR troff (1) output (cat phototypesetter commands). .IP d DVI File. The file contains .IR Tex (l) output (DVI format from Stanford). .IP g Graph File. The file contains data produced by .IR plot (3X). .IP c Cifplot File. The file contains data produced by .IR cifplot . .IP v The file contains a raster image. .IP r The file contains text data with FORTRAN carriage control characters. .IP 1 Troff Font R. Name of the font file to use instead of the default. (Obsolete) .IP 2 Troff Font I. Name of the font file to use instead of the default. (Obsolete) .IP 3 Troff Font B. Name of the font file to use instead of the default. (Obsolete) .IP 4 Troff Font S. Name of the font file to use instead of the default. (Obsolete) .in -5 .sp .PP Each job in the spool queue can have an associated job hold file which is used by the server process to control the printing of the job. The status file contains information controlling the job hold status and error status. The spool server will attempt to print a job a limited number of times before abandoning it or setting an error status in the job status file. The following is a typical job hold file. .RS .ft CW hold 0 priority 0 active 2135 redirect remove 0 error .RE .PP A nonzero .I hold entry will prevent the job from being processed; the lpc .I hold and release commands update this field. The .I priority field overrides the normal first-in first-out printing priority; jobs with non-zero priority fields are printed first. The lpc .I topq command updates this field. If the .I active field is non-zero, the job is being printed by the server with the specified process id. The .I redirect field allows individual jobs to be forwarded to a different printer; the lpc .I move command updates this field. Finally, the remove and error fields are used to control printing of problem jobs. The .I remove field is set when a job should be removed; the .I error field records information that would prevent a job from being printed. .SH "JOB SUBMISSION" The LPR program is used to submit a job to the LPRng system. The LPR program opens a connection to the LPD server and then transfer the job control file and data files. The LPD server checks to see if the remote host and user has permissions to spool to the requested printer, and then checks to see if the printer is accepting jobs. If both conditions are met, the job is accepted and the control and data files are placed in the spool directory. The LPRng software sends the control file first, followed by the data files. .PP If the LPR program is acting as a filter, it is not necessary to temporarily store the print job on the local machine. The input data can be sent directly to the LPD server for spooling using an implicit job size of 0 and sending data until the connection is terminated to the server. However, some LPD servers do not accept 0 size jobs, even though it is specified by the RFC1179, so by default LPR will create a temporary file. The LPR -k (seKure) option specifies this direct transmission mode be used. .SH "JOB TRANSMISSION" When LPR is to send a job to the server, it must determine the location of the server. It does this by examining the values of the specified printer and host. .PP If the printer and host are explicitly specified in the form .L "pr@host" then the LPR program will send the job to the specified spool queue .L pr and to the server running on .L host . This can be explicitly specified by the PRINTER environment variable or by the LPR -P option. .PP If the printer is specified only by a name, then the information in the printcap database is used. The printcap entry for the printer is searched for and the remote host and printer information extracted. The job is sent to the server running on the specified host. .PP This action can be modified by the following printcap or configuration tags. .IP "1. default_host=host" 5 (Configuration) If there is no printcap entry for the printer, the job is sent to the LPD server running on .L host . .IP "2. force_localhost" 5 (Configuration or printcap) If this flag is specified, then LPR and other client programs will send the job to the server running on the localhost. This overrides the default_host information. .SH "FORWARDING OPERATIONS" The LPD system can forward jobs from one spool directory to another. This is controlled by the following options. .IP 1. 5 The forward field in the spool control file has a value rp@rm. This can be set using the LPC forward command. .IP 2. 5 The lp (line printer) printcap entry has the form rp@rm. There is a rm (remote machine) and optional rp (remote printer) printcap entry. .LP The first of the above conditions to be met will determine the destination. If printing is enabled, then jobs will be forwarded to the remote destination. Example: .DS .ft CW .nf # using lp=rp@host test:sd=/usr/spool/test :lp=test@host test:sd=/usr/spool/test :lp=test@host%port # using :rp:rm: test:sd=/usr/spool/test :rp=test:rm=host .ft R .fi .DE .IP 3. 5 The LPD server uses the same algorithm for sending jobs as the LPR program. A connection is made to the remote server and the files are copied to the server. A set of timeouts is used to control error recover and retry operations. The printcap and configuration variables .I connect_timeout, .I connect_interval, .I connect_grace, and .I send_try control connecting to the remote host. A connection is attempted to the remote server from a random port in the range of ports specified by the .I originate_port variable. If a connection is not completed within .I connect_timeout seconds, the connection is aborted, and then after the .I connect_interval seconds it is retried. The procedure repeated indefinitely for printing, but only once for status or control operations. A connect_timeout value of 0 indicates no timeout; a value of 0 specifies infinite timeout After a job has been successfully printed, the connection is closed and the server waits for .I connect_grace seconds before trying to reconnect. .SH "BOUNCE QUEUES" .PP Normally job files are forwarded to a printer without modification. The .B lpd_bounce flag makes the queue a .I "bounce queue" and allows banners to be generated and data files to passed through the appropriate format filter. The entire output of this process is then passed to the destination with the format specified by the .B bq_format option (default .B l or binary). See PRINTING OPERATIONS for details about filters. For example, the following printcap entry will filter format f files. .ne 1i .DS .ft CW .nf testbq:sd=/usr/spool/testbq: :lpd_bounce :bq_format=l :lp=final@host :if=/usr/lib/filter_for_f :mf=/usr/lib/filter_for_m :pf=/usr/lib/filter_for_pr .fi .ft R .DE .SH "CHANGING FORMAT OF DATAFILES" .PP Sometimes only the indicated format of the data files needs to be changed. This can be done using the .B translate_format option. This entry consists of pairs of lower case characters of the form SdSd...; S is the original and d is the translated format. .ne 1i .DS .ft CW .nf changeformat: :sd=/usr/spool/changeformat: :translate_format=mfpf :lp=final@host .fi .ft R .DE .PP In the example above, the m format is processed by a filter, and then its format type is changed to f; the p format is processed similarly. Note that the lpr -p option specifies that the job will be processed by the .L /bin/pr command - the filter must do both the pr processing and any necessary format conversions. .SH "LPR FILTER PROCESSING" .PP The .L :lpr_bounce: printcap flag will cause LPR to do bounce queue filtering before sending the job to the remote queue. This can have unexpected effects if the filters are not available on the local host. .PP A typical entry which will cause LPR to do filtering is shown below. .ne 1i .DS .ft CW .nf testbq:lpr_bounce :lp=printer@host :if=/usr/lib/filter_for_f :vf=/usr/lib/filter_for_v :mf=/usr/lib/filter_for_m :translate_format=mfvf .ft R .DE .PP This entry will force LPR to run jobs with formats f, m, and v through the appropriate filter. It will also rename the formats to the f format. .SH "ROUTING JOBS TO PRINTERS" .PP When a job is submitted for printing, sometimes it is desirable to have it dynamically rerouted to another spool queue, or multiple copies send to various destination. This can be done by using a .L routing_filter . .PP When a job is accepted by the LPD server, part of the processing includes passing it to a program specified by the printcap .L router entry. This filter is invoked with the original control file as STDIN, and the default set of filter options. The output of the routing filter will be a set of directives used by LPD when forwarding the job to another printer or in processing the job. The environment and options flags are set as for a standard filter. (See "FILTERS" for details.) Here is a sample printcap entry: .DS .ft CW .nf t2|Test Printer 2 :sd=/var/spool/LPD/t2 :lf=log :lp=t2@printserver :bq=t1@localhost :destinations=t1@localhost,t2@localhost :router=/usr/local/libexec/filters/router .ft R .DE .PP The routing filter exit status is used as follows: .nf 0 (JSUCC) - normal processing 37 (JHOLD) - job is held any other value - job is deleted from queue .fi .PP The router filter returns one or more routing entries with the following format. Note that entry order is not important, but each entry will end with the 'end' tag. .DS dest copies X end .DE .PP Example of router output: .DS .ft CW .nf dest t1@localhost copies 2 CA end dest t2@localhost CZ end .ft R .DE .PP The above routing information will have copies of the job sent to the t1 and t2 spool queue servers. If no valid routing information is returned by the router filter the job will be sent to the default bounce queue destination. .PP .SH "REFORMATING CONTROL FILES" .PP Sometimes it is desirable to reformat a control file before sending to a remote destination. If the .L control_filter printcap entry is present, then the control file is passed through the filter. If the filter exits with status JSUCC, then the job is process normally; status JABORT causes the job processing to be aborted, status JREMOVE causes the job processing to be removed, and any other status is treated as JFAIL. .PP After passing the control file through the control_filter, the LPD server will reread it, and transfer only the data files specified in the new control file to the destination. .SH "SPOOL QUEUE NAME OPTION" .PP The .L qq printcap entry and the .L use_queuename configuration entry causes the name of the spool queue to be placed in the job control file. This value can be used by the filter to determine how to process a job. When combined with the use of the Bounce Queue, this can be used to reformat jobs before sending to another printer spooler system. .SH "PRINTING OPERATIONS" .PP When printing is enabled, the LPD server will create a spool server process to carry out printing operations. For each job in the queue, the spool server process will create a subserver process to carry out the actual printing operations. If the subserver process fails, the server process will initiate recovery operations. Job will be attempted to be printed until all are done or a subserver returns an ABORT indication; the server will then terminate operations. .PP The server process normally scans the queue once, at initiation; if the spool control file is modified, usually by using the lpc command, the spool queue is rescanned. The overall algorithm for job printing is: .nf open the print device; send some initialization strings; send a banner to the device; send the job data files to the device; send some termination strings; close the print device; .fi .PP In order to handle the various device requirements, the subserver process in turn uses 'filter' programs specified in the printcap entry to carry out the individual steps. .IP "OF Filter" 5 The 'of' filter is used for initialization, banner printing and the termination strings. It has the peculiar property of suspending itself when sent a special escape string, allowing other filters to be used to print the individual job files. .IP "Data Filters" 5 Each data file in a job has format specified by a lower case character and an associated filter specified in the printcap file. For example, the 'g' format is printed by the 'gf' filter, and so forth. By convention, the 'if' filter is used to print 'f' (ordinary text) and 'l' (binary) format jobs. .IP "lp-pipe Filters" If the printcap device specification has the form .I "|program" then the output device is accessed by the specified program. This allows the program to take care of any required initialization or communication requirements. .LP The following is a concise summary of the actual algorithm used to print files. Note that LP stands for the printer device or filter specified by the 'lp' printcap entry; OF stands for the 'of' printcap filter; IF is the default 'if' filter; BP is the banner printing filter; and ?F stands for the filter for data file. The '??' values stand for entries from the printcap file. .sp .nf .ft CW .ta 4n +4n +4n +4n +4n +4n +4n +4n +4n .ps -2 .vs -2 LP = open( 'lp' ); // open device, filter, or network connection OF = IF = LP; // set defaults set up accounting according to 'af' entry; if( 'of' ) OF = filter( 'of' ) -> LP; // make OF filter if 'as' then record start of job accounting information. if 'achk' then check for accounting limits. if( leader on open 'ld' ) `ld` -> OF // send leader if( FF on open 'fo' ) `fo` -> OF // send leader // print a banner // first check to see if required // and then to see if not suppressed by printcap // or by user do_banner = (always banner 'ab' || (!suppress banner 'sb' && job has banner )); if( ! header last 'hl' && do_banner ){ if( banner program 'bp' ){ fork and exec bp to generate banner, but into temp file. cat temp file -> OF; } else { short banner info -> OF; } } // now we suspend the OF filter, use other filters if( OF != LP ) suspend OF filter; for each data file df in job do // send FF between files of job if( !first job && ! no FF separator 'sf' ){ if( OF != LP ) wake up OF filter; 'ff' -> OF; if( OF != LP ) suspend OF filter; } // get filter for job format = jobformat; if( jobformat == 'f' or jobformat = 'l' ){ format = 'f'; } filter = check pc for filter for format; ?F = LP; // default - no filter if( filter ){ ?F = filter( filter ) -> LP; } data file -> ?F; // note: if :direct_read: flag set, filter input // is directly from the file, otherwise the // file contents are written to the filter input. if( ?F != LP ) close( ?F ) endfor // finish printing if( OF != LP ) wake up OF filter; if( header last 'hl' && do_banner ){ if( ! no FF separator 'sf' ){ 'ff' -> OF; } if( banner program 'bp' ){ fork and exec bp to generate banner, but into temp file. cat temp file -> OF; } else { short banner info -> OF; } } if( ff on close 'fq' ){ 'ff' -> OF; } if( trailer on close 'tr' ){ tr -> OF; } if 'ae' then record end of job accounting information. if( OF != LP ) close( OF ); close( LP ); .ps +2 .vs +2 .sp .fi .PP When printing or transferring a job to a spool queue fails, it is retried the number of times specified by the .I rt (or .I send_try ) printcap variable. A 0 value specifies an infinite number or retries. When the retry count is exceeded, then the .I send_failure_action printcap variable determines the action to be taken. The variable can be the values .I succ , .I fail , .I abort , .I remove , .I ignore , or .I hold , which will cause the job to be treated as normally completed, retried, aborted, removed, or ignored and retried at a later time respectively. These names correspond to the .I JSUCC , .I JFAIL , etc. error codes returned by filters. If the variable has the form .I |/filter , then the filter is run and passed the number of attempts on the standard input. The filter must exits with a .I JSUCC, .I JFAIL, etc., error code and the server will take the appropriate action as listed above. .PP The print filters normally have their input provided by a process via a pipe. However, if the .I direct_read printcap flag is set, then the filter input is taken directly from the job file. This is compatible with the vintage BSD method, but loses the ability to track the job progress. .PP After the job print or transfer attempt, if the job is to be removed and the printcap variable .I "save_on_error" is true, the job will not be removed from the spool queue but only flagged with an error. The job can then be retried at a later time. If the job is successfully printed it is usually removed from the spool queue. However, if the printcap variable .I "save_when_done" is true the job will merely be marked as completed and not removed from the queue. .SH "FILTERS" .PP As described in the previous section, filters are created to handle output to devices or other filters. The command line to invoke a filter is generated in the following manner. .IP 1. 5 The printcap entry or configuration value defining the filter command is obtained. .IP 2. 5 The file to be printed or the banner line/file generated by the banner printer will be written to STDIN (file descriptor 0) of the filter. The output device (or /dev/null if this is not a printing filter) will be be STDOUT (file descriptor 1) and STDERR (file descriptor 2) will be connected to the error logging file. If this is a printing filter, the error log will be determined by the :af: printcap field and FD 3 will be opened and set to the either the file, remote host, or input of the filter program. .IP 3. 5 Filter specifications starting with ROOT will be run as root (EUID = 0). This can be a serious security loophole and should only be used as a last resort for specific problems. .IP 4. 5 The options for the filter command line will be replaced by appropriate values. Option specifications have the form $[0| ][-]X. .\" Option specifications have the form $[0| ][-][']X. The default option expansion has the form $X -> -X'value'; the form $0X or $(space)X adds a space after the -X, i.e.- $0X -> -X 'value'; the form $-X suppresses the -X, i.e. - $-X -> value. .\" the form $-X suppresses the -X, i.e. - $-X -> 'value'; .\" and the form $'X suppresses the quotes around the value. .\" Note that the 0,-, and ' can be combined. For example, $-'X -> value. The options will be expanded as follows: .RS .sp .nf .ta \w'Key 'u +4n +4n Key Value a Accounting file (printcap 'af' entry) b Job size, i.e.- total data file size, in bytes c if binary (format 'l') expands to -c d Control directory e job data file f original print file name (control file N field) h Control file hostname i Control file indent (I) field j job number from control file name k Control file name l printcap Page length (pl) value m printcap Cost factor (co) value n Control file user logname (P) field p Remote Printer name for forwarded jobs r Remote Host name for forwarded jobs s printer Status file (ps) value t current time in simple format w printcap Page width (pw) value x printcap x dimension (px) value y printcap y dimension (py) value F data file format character P Printer name S printcap Comment tag (cm) value Upper Case control file line starting with letter Digit control file line starting with digit .sp .RE .fi .IP 5. 5 The options specified by the filter_options (for none OF filters) or of_filter_options (for the OF filter) will be appended to the command line and expanded. To suppress adding options, you can use the form '-$ filter', i.e. - of=-$/bin/cat. If the 'bkf' (backwards compatible filter options) printcap flag is set, the of filter is given the options specified by bk_of_filter_options and other filters those by bk_filter_options. The following shows the various combinations possible, and typical values for the options. .RS .sp .nf .ta \w'default_options 'u +4n +4n +4n Options filter_options $C $F $H $J $L $P $Q $R $Z $a $c $d $e $f $h $i \e $j $k $l $n $s $w $x $y $-a bk_filter_options $P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a bk_of_filter_options $w $l $x $y .RE .IP 6. 5 A printing filter which executes correctly and completely should exit with a 0 error status. A nonzero error status will be interpreted as follows: .RS .nf .ta 9n +4n +4n JFAIL 32 failed - retry later JABORT 33 aborted - do not try again, but keep job JREMOVE 34 failed - remove job .RE .fi .PP The JFAIL will cause the job to be retried at a later time. A limit can be placed on the number of retries using the :rt: or :send_try: printcap entry. A retry value of 0 will cause infinite retries. The JABORT indicates serious problems and will cause printing operations on the job to stop until restarted by operator intervention. The JREMOVE status indicates problems, and the job should be removed from the spool queue. .PP The environment variables for filters are highly restricted, due to the possibility for abuse by users. The following variables are set: .IP "USER and LOGNAME" 5 user name or daemon name. .IP "LOGDIR" 5 home directory of user or daemon. .IP PATH 5 from the .I filter_path configuration variable. .IP LD_LIBRARY_PATH 5 from the .I filter_ld_path configuration variable. .IP SHELL 5 set to .I /bin/sh .IP IFS 5 set to blank and tab. .IP TZ 5 the TZ environment variable. .IP SPOOL_DIR 5 the spool directory for the printer .IP CONTROL_DIR 5 the control directory for the printer .IP PRINTCAP_ENTRY 5 the printcap entry for the printer .IP CONTROL 5 the control file for the print job .IP "pass_env environment variables" 5 Values of environment variables listed in the pass_env configuration variable. .SH ACCOUNTING .PP The LPRng software provides several methods of performing accounting. The printcap af (accounting field), as and ae (accounting start and end), and achk (accounting check) provide a basic set of facilities. The af field specifies a file, filter, or TCP network connection to an accounting server. If af has the form .ft CW |filter .ft R or .ft CW |-$ filter .ft R then a filter will be started and all accounting information will be sent to the filter. The first form passes the filter the command line options specified by the filter_options configuration variable and the second suppresses option passing. If af has the form .ft CW host%port .ft R then a TCP connection will be opened to the port on the specified host and accounting information sent there. All other forms will be treated as a pathname relative to the queue spool directory. .PP If af specifies a file, then the accounting information is appended to an existing file; the accounting file will not be created. .PP When af specifies a filter or network connection and the achk flag is set, then after writing the initial accounting information (see as printcap field below) the server will wait for a reply of the form ACCEPT from the filter or server. If not received, the job will not be printed. .PP The as (accounting start) and ae (accounting end) fields can specify a string to be printed or a filter. Options in the string will be expanded as for filters, and the strings printed to either the accounting information destination. If the as field specifies a filter, then the print server will wait for the filter to exit before printing the job. If the exit status is 0 (successful), the job will be printed. A non-zero JREMOVE status will remove the job, while any other status will terminate queue printing operations. After printing the job, the ae filter will be started and the server will wait for it to complete before printing the next job. .PP The as and ae filters will have STDOUT set to the printing device and or filter, and the STDERR set to the error log file for the print queue, and file descriptor 3 set to the destination specified by the af field. .PP As a convenience, all format filters for printing will be started with file descriptor 3 set to the destination (file or filter) specified by the printcap af field. This allows special filters which can query devices for page counts to pass their information directly to an accounting program. The descriptor will READ/WRITE, allowing filters to query the accounting program and/or update the information directly. .SH "LOGGING INFORMATION" .PP In order to provide a centralized method to track job status and information, the printcap/configuration variable logger_destination enable the send of status and other information to a remote destination. The logger_destination value has the form .RS .nf .L host[%port][,protocol] .ti -4n Examples: .L taco%451,UDP .L dickory%2001,TCP .RE .fi .br where host is the host name or IP address, port is an optional port number, and protocol is an optional protocol type such as UDP or TCP. The configuration variables default_logger_port and default_logger_protocol can be used to override the default port number (2001) and protocol (UDP) to be used if none is specified. Logging information has the format below. .RS .nf IDENTIFIER jobid [PRINTER name] at \fItimestamp\fP \e STATUS | TRACE | FILTER_STATUS PID nnn [ status information] .RE .fi .PP The status information format consists of an identifier line, followed by a specifier of the status type. The logging information entry is terminated by a line with a single period on it. Lines with a starting period have the period duplicated. .SH AUTHENTICATION .PP Rather than building authentication facilties into LPRng, an interface to authentication programs is defined, and will be used as follows. The printcap and configuration entries .I auth, .I auth_client_filter, .I auth_forward, .I auth_forward_id, .I auth_forward_filter, .I auth_receive_filter, and .I auth_server_id entries control authentication. The .I auth value specifies the type of authentication to be used for client to server authentication. Typical values would be kerberos, md5, etc. If the authentication type is not built-in, the client programs use the .I auth_client_filter program to perform authentication. When a server gets and an authentication request, it will use the .I auth_receive_filter program to perform authentication. The .I auth_server_id is the remote server id used when a client is sending jobs to the server or when the server is originating a request. When a server forwards a request, it uses .I auth_forward value to determine if authentication is to be done, and the .I auth_forward_id as the destination server id. .de NP .fi .in 0 .PP .br .in +4n .ti -4n \\n(nP.\ \ \c .nr nP \\n(nP+1 .. .de sP .fi .PP .br .in +4n .. .de np .nr nP 1 .. .SH "Client To Server Authentication" .np .NP The client will open a connection to the server and sends a command with the following format. The REQ_SECURE field in the command corresponds to the one-byte command type used by the LPR protocol. .RS .nf Commands: .ta 4n +4n \eREQ_SECUREprinter C user\en Print job transfers: \eREQ_SECUREprinter C user controfilename\en .RE .fi .NP On reception of this command, the server will send a one byte success code as below. An error code may be followed by additional error information. The values used by LPRng include: .RS .nf .ta 16n +4n +4n ACK_SUCCESS 0 success, no error ACK_STOP_Q 1 failed; no spooling to the remote queue ACK_RETRY 2 failed; retry later ACK_FAIL 3 failed; job rejected, no retry .RE .fi .NP If there is an error the connection will be terminated. The server will then start an authentication process, and provide the following open file descriptors for it. The authenticator process will run as the UID of the server (i.e.- usually daemon). .RS .nf .ta 6n +8n +4n FD Options Purpose 0 R/W socket connection to remote host (R/W) 1 W pipe or file descriptor for information for server 2 W error log 3 R pipe or file descriptor for responses to client .RE .sP The command line arguments will have the form: .RS .nf program -S -Pprinter -nuser -Rserver_user -Ttempfile .RE .sP The printer and user information will be obtained from the command line sent to the server. The authenticator can create additional temporary or working files with the pathnames tempfile.ext; these should be deleted after the authentication process has been completed. .NP After receiving \eACK_SUCCESS, the client starts an authenticator process, and provides the following open file descriptors for it. The authenticator process will run UID user. .RS .nf .ta 6n +8n +4n FD Options Purpose 0 R/W socket connection to remote host (R/W) 1 W pipe or file descriptor for responses to client 2 W error log .RE .sP The command line arguments will have the form: .RS .nf program -C -Pprinter -nuser -Rserver_user -Ttempfile .RE .fi .NP The authenticator can create additional temporary or working files with the pathnames tempfile.ext; these will be deleted after the authentication process has been completed. The client authenticator will be running as the client user. .NP After exchanging authentication information, the client authenticator will transfer the contents of the temporary file to the server authenticator, using FD 0. It will then wait for reply status on FD 0. If the transfer step fails, or there is no reply status of the correct format, the client authenticator will print any received information on FD 1, error information on FD 2, and then exit with error code JFAIL. .NP After receiving the files on FD 0, the server authenticator will perform the required authentication procedures and leave the results in tempfile. The server authenticator will write the following to FD 1, for use by the server: .RS .nf authentication_info\en .RE .sP If the transfer step or authentication fails, then the server will write an error message to FD 2 and exit with error code JFAIL. The server will use this authentication information to determine if the remote user has permission to access the system. .NP The server authentication process will read input from FD 3 until and end of file, and then proceed to transfer the input to the client authenticator. If the data transfer fails, then the process will exit with error code JFAIL, otherwise it will exit with error code JSUCC. .NP The client authenticator will read the status information from FD 0, and after performing authentication will write it to FD 1. If data transfer or authentication fails, the authenticator will write an error message to FD 2 and exit with error code JFAIL, otherwise it will exit with error code JSUCC. .SH "Server to Server Authentication" .np .PP The Server to Server authentication procedure is used by one server to forward jobs or commands to another server. It should be noted that this forwarding operation puts an implicit trust in the security of the client to server to server chain. In the description below, src and dst are the userid of the source and destination servers respectively. .NP The originating host takes the part of the client, and will transfer a job acting like the client. The initial information transfer from the originating (src) server will have the format: .RS .nf .ta 4n +4n Commands: \eREQ_SECUREprinter F user\en Print job transfers: \eREQ_SECUREprinter F user controfilename\en .RE .sP After receiving a 0 acknowledgment byte, the src server will invoke its authenticator with the arguments below. The forward_user value will default to the server_user value if not explicitly provided. .RS .nf .ta 4n +4n .L program -C -Pprinter -nserver_user \e -Rforward_user -Ttempfile .RE .NP On the destination server the authenticator is invoked with the arguments: .RS .nf .ta 4n +4n .L program -S -Pprinter -nserver_user \e -Rforward_user -Ttempfile .RE .sP The authentication is performed to determine that the transfer was between the two servers, rather than the user to server. .SH "KERBEROS AUTHENTICATION" .PP As a convenience, Kerberos 5 authentication has been built into the LPD clients and servers. If you are not familiar with Kerberos, then you should obtain other documentation and/or assistance before attempting to use this. The following facilities/configuration values are used to support Kerberos. .PP A Kerberos principal is the name used for authentication purposes by Kerberos. For example, user principals have the form user@REALM; for example, papowell@ASTART.COM. Services and/or servers have the form service/host@REALM; for example, the lpd server on dickory would have the form: .ti +5n lpr/astart2.astart.com@ASTART.COM .PP User to server authentication process will use the user's principal name, and generate a service name for the server. The name generation is controlled by the following configuration and/or printcap values. .IP service The name of the service to be used to identify the service. This is usually "lpr". .IP kerberos_keytab The location of the server keytab file. The keytab file corresponds to the user password, and must be considered a security risk. It should be owned by the LPD server user, and readable/writable only by the server. .IP kerberos_life The lifetime of the authentication ticket used by the server. This usually defaults to 10 hours. .IP kerberos_renew The renewal time of the ticket. .PP In addition to the default values, an explicit server principal can be specified in the printcap file using the kerberos_server_principal This allows cross domain authentication to be done. .PP When setting up Kerberos authentication, you will need to establish principals for each server, and to distribute and install the keytab files on each server. .SH "AUTHENTICATION PERMISSIONS" .PP The following permissions tags are available to check on authentication procedures. .RS .nf .ta 4n +12n +4n +4n +4n +4n AUTH=[NONE,USER,FWD] - authentication AUTH=NONE - no authentication AUTH=USER - authentication from a client AUTH=FWD - forwarded authentication from a lpd server AUTHTYPE=globmatch AUTHUSER=globmatch FWDUSER=globmatch .RE .fi .np .NP The AUTH tag can be used to determine the type of authentication being done. The AUTHTYPE tag can be used to match the authentication type being used or requested by the client or remote server. The authentication process returns an authentication identifier for the user; this information can be matched by the AUTHUSER tag. .NP For a command sent from a client or forwarded from a server, AUTHUSER matches the auth_user_id provided for the user when sent to a server. (This information will be forwarded by a remote server). For a forwarded command, FWDUSER refers to the authentication information for the server doing the forwarding. .NP For example, to reject non-authenticated operations, the following line could be put in the permissions file. .RS .nf REJECT AUTH=NONE .RE .NP To reject server forwarded authentication as well, we use REJECT AUTH=NONE,FWD. If a remote server with name .I serverhost has id information FFEDBEEFDEAF, then the following will accept only forwarded jobs from this server. .RS .nf ACCEPT FWDUSER=FFEDBEEFDEAF REMOTEHOST=serverhost REJECT AUTH=FWD .RE .fi .SH ENVIRONMENT The lpd action can also be manipulated by using environment variables. .TP .B LPR_TMP .SS Authentication .TP .B MD5KEYFILE Used for md5 signated file transmission .SH FILES The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" .BR lpd.conf (5), .BR lpc (8), .BR checkpc (8), .BR lpr (1), .BR lpq (1), .BR lprm (1), .BR printcap (5), .BR lpd.perms (5), .BR pr (1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lprng_certs.n0000644000131400013140000001426311531672130013060 00000000000000.TH lprng_certs 1 2006-12-09 "LPRng" "lprng_certs command" .SH NAME lprng_certs \- lprng SSL certificate management .SH SYNOPSIS .B .nf lprng_certs option Options: init - make directory structure newca - make new root CA defaults - set new default values for certs gen - generate user, server, or signing cert index [dir] - index cert files verify [cert] - verify cert file encrypt keyfile - set or change keyfile password .nf .SH DESCRIPTION .PP The .B lprng_certs program is used to manage SSL certificates for the LPRng software. There SSL certificate structure consists of a hierarchy of certificates. The LPRng software assumes that the following types of certificates will be used: .IP "CA or root" A top level or self-signed certificate. .IP "signing" A certificate that can be used to sign other certificates. This is signed by the root CA or another signing certificate. .IP "user" A certificate used by a user to identify themselves to the lpd server. .IP "server" A certificate used by the .I lpd server to identify themselves to the user or other .I lpd servers. .SH "Signing Certificates" .PP All of the signing certificates, including the root certificate (root CA), _SSL_CA_FILE_, are in the same directory as the root CA file. Alternately, all of the signing certs can be concatenated and put into a single file, which by convention is assumed to have the same name as the root CA file, _SSL_CA_FILE_. The .BR ssl_ca_file , .BR ssl_ca_path , and .BR ssl_ca_key printcap and configuration options can be used to specify the locations of the root CA files, a directory containing the signing certificate files, and the private key file for the root CA file respectively. .PP The root certificate (root CA file) _SSL_CA_FILE_ has a private key file _SSL_CA_KEY_ as well. By convention, the private keys for the other signing certificate files are stored in the certificate file. .PP The OpenSSL software requires that this directory also contain a set of hash files which are, in effect, links to these files. .PP By default, all signing certificates are assumed to be in the same directory as the root certificate. .SH "Server Certificates" .PP The certificate used by the .I lpd server are kept in another directory. These files do not need to have hash links to them. By convention, the private keys for these certificate files are stored in the certificate file. The server certificate file is specified by the .B ssl_server_cert and has the default value _SSL_SERVER_CERT_. This file contains the cert and private key. The server certificate password file is specified by the .B ssl_server_password option with the default value _SSL_SERVER_PASSWORD_ and contains the password used to decrypt the servers private key and use it for authentication. This key file should be read only by the .I lpd server. .SH "User Certificates" .PP The certificates used by users are kept in a separate directory in the users home directory. By convention, the private keys for these certificate files are stored in the certificate file. .PP The user certificate file is specified by the .B LPR_SSL_FILE environment variable, otherwise the .B "${HOME}/.lpr/client.crt" is used. The password is taken from the file specified by the .B LPR_SSL_PASSWORD environment variable, otherwise the .B "${HOME}/.lpr/client.pwd" file is read. .PP .SH "USING LPRNG_CERTS" .PP The organization of the SSL certificates used by LPRng is similar to that used by other programs such as the .B Apache .B mod_ssl support. The .B lprng_certs program is used to create the directory structure, create certificates for the root CA, signing, user and servers. In order to make management simple, the following support is provided. .SH "lprng_certs init" .PP This command creates the directories used by the lpd server. It is useful when setting up a new .B lpd server. .SH "lprng_certs newca" .PP This command creates a self-signed certificate, suitable for use as a root CA certificate. It also sets up a set of default values for other certificate creation. .SH "lprng_certs defaults" .PP This command is used to modify the set of default values. .PP The default values are listed and should be self-explanatory, except for the value of the .B signer certificate. By default, the root CA can be used to sign certificates. However, a signing certificate can be used as well. This allows delegation of signing authority without compromising the security of the root CA. .SH "lprng_certs gen" .PP This is used to generate a user, server, or signing certificate. .SH "lprng_certs index" .PP This is used to create the indexes for the signing certificates. .SH "lprng_certs verify [cert]" .PP This checks the certificate file using the Openssl .B "openssl verify" command. .SH "lprng_certs encrypt keyfile" .PP This removes all key information from the key file, reencrypts the key information, and the puts the encrypted key information in the file. .SH "LPRng OPTIONS" .nf .ta \w'${HOME}/.lpr/client.crt 'u Option Purpose ssl_ca_path directory holding the SSL signing certs ssl_ca_file file holding the root CA or all SSL signing certs ssl_server_cert cert file for the server ssl_server_password file containing password for server server ${HOME}/.lpr/client.crt client certificate file ${HOME}/.lpr/client.pwd client certificate private key password .SH "ENVIRONMENT VARIABLES" .nf .ta \w'${HOME}/.lpr/client.crt 'u LPR_SSL_FILE client certificate file LPR_SSL_PASSWORD client certificate private key password .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "SEE ALSO" .LP lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.conf(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/Makefile.am0000644000131400013140000000207211531672130012406 00000000000000MAINTAINERCLEANFILES = Makefile.in man_MANS = cancel.1 checkpc.8 lp.1 lpbanner.1 lpc.8 lpd.8 lpd.conf.5 \ lpd.perms.5 lpf.1 lpq.1 lpr.1 lprm.1 lpstat.1 monitor.1 pclbanner.1 \ printcap.5 psbanner.1 lprng_certs.1 lprng_index_certs.1 CLEANFILES = $(man_MANS) EXTRA_DIST = cancel.n checkpc.n lp.n lpbanner.n lpc.n lpd.n lpd.conf.n \ lpd.perms.n lpf.n lpq.n lpr.n lprm.n lpstat.n monitor.n pclbanner.n \ printcap.n psbanner.n lprng_certs.n lprng_index_certs.n %.1 %.5 %.8: $(srcdir)/%.n Makefile rm -f $@ sed \ -e "s!_PRINTCAP_PATH_!${PRINTCAP_PATH}!" \ -e "s!_FILTER_LD_PATH_!${FILTER_LD_PATH}!" \ -e "s!_FILTER_PATH_!${FILTER_PATH}!" \ -e "s!_LPD_PERMS_PATH_!${LPD_PERMS_PATH}!" \ -e "s!_LPD_CONF_PATH_!${LPD_CONF_PATH}!" \ -e "s!_LOCKFILE_!${LOCKFILE}!" \ -e "s!_SSL_CA_FILE_!${SSL_CA_FILE}!" \ -e "s!_SSL_CA_KEY_!${SSL_CA_KEY}!" \ -e "s!_SSL_CERTS_DIR_!${SSL_CERTS_DIR}!" \ -e "s!_SSL_SERVER_CERT_!${SSL_SERVER_CERT}!" \ -e "s!_SSL_SERVER_PASSWORD_!${SSL_SERVER_PASSWORD}!" \ -e "s!_LPD_LISTEN_PORT_!${LPD_LISTEN_PORT}!" \ $< > $@ lprng-3.8.B/man/README0000644000131400013140000000147611531672130011241 00000000000000########################################################################### # LPRng - An Extended Print Spooler System # # Copyright 1988-1995 Patrick Powell, San Diego State University # papowell@sdsu.edu # See LICENSE for conditions of use. # ########################################################################### # MODULE: TESTSUPPORT/Makefile # PURPOSE: ./man/README # $Id$ ########################################################################## These are the man pages for the LPRng software. Commentary Thu Jul 20 08:14:12 PDT 1995 Patrick Powell The man pages for the lpr, lpc, lpd, etc. have been modified to reflect the programs as of the above date. This does not mean that they will not change again. Much thanks to Justin Mason (jmason@iona.ie) for adding the various clarifications to these pages. lprng-3.8.B/man/lpf.n0000644000131400013140000000771011531672130011316 00000000000000.TH LPF 1 2006-12-09 "LPRng" "lpf filter" .SH NAME lpf \- general printer filter .SH SYNOPSIS .B lpf .BI \-P printer .BI \-w width .BI \-l length .BI \-x width .BI \-y length [ .BI \-c ] .BI \-K controlfilename .BI \-L bnrname [ .BI \-i indent ] [ .BI \-Z options ] [ .BI \-C class ] [ .BI \-J job ] [ .BI \-R accntname ] .BI \-n login .BI \-h Host .BI \-F format [ .BI \-T [crlf,debug] .BI \-D level ] [ affile ] .SH DESCRIPTION .B Lpf is a general printer filter. Usually it is used as filter in the printcap file and is called by lpd. The -Tcrlf option will suppress translation of LF to CR/LF pairs. The -Tdebug option will increment the debug level. The following options passes lpd by default: .IP "\fB\-P\fIprinter\fR" 5 The name of the printer. .IP "\fB\-w\fIwidth\fR" 5 The page width in chars, as given in the :pw field in the printcap file .IP "\fB\-l\fIlength\fR" 5 The page length in lines, as given in the :pl field in the printcap file .IP "\fB\-x\fIwidth\fR" 5 The page width in pixels, as given in the :px field in the printcap file .IP "\fB\-y\fIlength\fR" 5 The page length in pixels, as given in the :py field in the printcap file .IP "\fB\-K\fIcontrolfilename\fR" 5 The name of the control file. .IP "\fB\-L\fIbnrname\fR" 5 The banner name. This is set by the lpr -T option. .IP "\fB\-n\fIlogin\fR" 5 The user login name. .IP "\fB\-h\fIHost\fR" 5 The host where the job was submitted. .IP "\fB\-F\fIformat\fR" 5 The job format from the lpr -F option or other option. .PP These options are optionally set by lpd: .IP "\fB\-Z\fIoptions\fR" 5 Extra options. They are passed from the \fB\-Z\fR parameter given on the lpr command command line and can be interpreted by the filter. .PP These remaining options can be added to the filter entry in the printcap file: .IP "\fB\-c\fR" 5 ignore control characters, set by lpr -b (binary) or -l (literal) options. .IP "\fB\-i\fIindent\fR" 5 The indentation amount, set by lpr -i indent option. .IP "\fB\-C\fIclass\fR" 5 The class name, set by lpr -C class option. .IP "\fB\-J\fIjob\fR" 5 The job name, set by lpr -J job option. .IP "\fB\-R\fIaccntname\fR" 5 The name of the accounting file, from printcap information. .IP "\fB\-D\fIlevel\fR" 5 Sets debug level. The level must be an integer, a nonzero value switches debugging on. .IP "\fB\-T\fIcrlf\fR" 5 Turn LF to CR/LF translation off. .IP "\fB\-T\fIdebug\fR" 5 Increment the debug level. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpd.conf(5), lpc(8), lpd(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.perms(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/monitor.n0000644000131400013140000000255211531672130012223 00000000000000.TH monitor 1 2006-12-09 "LPRng" "monitor command" .SH NAME monitor \- receive logging information from LPD .SH SYNOPSIS .B monitor [ .I \-u ] [ .I \-t ] [ port ] .SH DESCRIPTION .PP The .B monitor program is a template for a printer status monitoring program. It will open the specified TCP and/or UDP port, and then wait for accounting or other information to be sent. It prints this information on it standard output. .SH OPTIONS .IP "\fB\-u\fR" 5 wait for connections on the UDP port. .IP "\fB\-t\fR" 5 wait for connections on the TCP port. .IP "\fBport\fR" 5 Use the specified port number. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "SEE ALSO" .LP lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.conf(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lpd.conf.n0000644000131400013140000005772311531672130012251 00000000000000.ds VE LPRng-3.9.0 .TH LPD.CONF 5 \*(VE "LPRng" .SH NAME .nf lpd.conf \- configuration file for the LPRng line printer spooler system .fi .SH DESCRIPTION The file \fBlpd.conf\fR is used to provide configuration information for the LPRng Printer spooler system and defaults for printcap information. Leading spaces on lines are ignored, and blank lines and lines whose first nonblank character is a sharp (``#'') are ignored. Trailing blanks and tabs (whitespace) for an option value are deleted unless the last one is escaped with a backslash (``\\''). All other lines specify parameters and should be of the following form: .RS .nf keyword keyword@ keyword#value keyword=value .RE .fi Note that these values are the same format as .BR printcap (5) values. Values in the configuration can contain host or machine dependent information; to assist with this, the following .I "escape sequences" in the configuration information are replaced as follows: .TP \fB%h\fR the short form of the host name (i.e.- non fully qualified). .TP \fB%H\fR the fully qualified host name. .TP \fB%a\fR the abbreviated architecture name, \fIsun4\fR, \fIsol2\fR, \fIhpux\fR, \fIaix\fR, \fIirix5\fR, etc. This value can be set using the \fBarchitecture\fR keyword in the configuration file and is set to a default value at compile_time. .TP \fB%P\fR the printer name from the printcap entry (see below). .TP \fB%R\fR the remote printer name from the printcap entry. .TP \fB%M\fR the remote host name from the printcap entry. This is truncated to the short host name. .PP For example, on host .I dickory.sdsu.edu, the strings .I "short=\fB%h\fR" .I "long=\fB%H\fR" .I "arch=\fB%a\fR" would be expanded as .I "short=dickory" .I "long=dickory.sdsu.edu" .I "arch=sun4" . .PP The P, R, and M tags are provided for use with combined configuration and printcap information. These values are not expanded when the printcap information is initially processed, and can be used only in a limited number of printcap or other entries. Currently only the printcap :sd: (spool directory) and :forward_server: (forward server) entries use these. .PP .SH "GENERAL CONFIGURATION PARAMETERS" .PP Some of the following parameters take lists of files or directories. Unless otherwise explicitly stated, these lists can be separated by commas (,), semicolons (;), or colons, (punctuation) and possibly tabs or spaces (whitespace) as well. .PP Keyword names can use either underscores (_) or hyphens (-) in their names, but the underscore is preferred. .TP \fBinclude\fR pathname [pathname*] (no default) This can be used to include files into the \fBlpd.conf\fR file. The include file parameter a whitespace separated list of files; the files must have absolute pathnames and must be readable. .TP \fBae\fR (default: "jobend $H $n $P $k $b $t") This specifies either a script or a filter to be invoked at the send of a job for accounting purposes. See \fBas\fP for the matching accounting at start, and the .BR printcap (5) and .BR lpd (8) man pages for details. .TP \fBallow_getenv\fR (default: "LPD_CONF") This option specifies an environment variable whose value is a configuration file. Use of this is restricted to test purposes, and SUID ROOT client and server will not run when the variable is enabled. .TP \fBar\fR (default: yes) See .BR printcap (5) for details. .TP \fBarchitecture\fR The default value is set at compile time and can be overwritten with this parameter. The default value of this parameter is set at compile time and it is used when expanding the special sequence \fB%a\fR in pathname and filename strings in this config file. .TP \fBauth\fR (default: NULL) Authentication type to be used for client to server communication. .TP \fBauth_client_filter\fR (default: NULL) Program to be used for client to server communication. .TP \fBauth_forward\fR (default: NULL) Authentication type to be used for server to server communication. .TP \fBauth_forward_filter\fR (default: NULL) Program to be used for server to server communication. .TP \fBauth_forward_id\fR (default: NULL) Authentication id of remote server for server to server communication. .TP \fBauth_receive_filter\fR (default: NULL) Program to be used by server receive server or client communication. .TP \fBauth_server_id\fR (default: NULL) Authentication id of originating client or server. .TP \fBas\fR (default: "jobstart $H $n $P $k $b $t") See \fBas\fR. .TP \fBbk\fR (default: no) See \fBprintcap\fP(5) for details. .TP \fBbk_filter_options\fR (default: "$P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a") If the "bkf" (backwards compatible filter) flags is set in the printcap entry and the original filter specification does not have a `$` in it, this option string is appended to a filter specification, and the string expanded with values from the printcap information and job information. (see of_filter_options, filter_options, bk_filter_options, bk_of_filter_options) .TP \fBbk_of_filter_options\fR (default: "$w $l $x $y") If the "bkf" (backwards compatible filter) flags is set in the printcap entry and the original filter specification does not have a `$` in it, this option string is appended to the OF filter specification, and the string expanded with values from the printcap information and job information. (see of_filter_options, filter_options, bk_filter_options, bk_of_filter_options) .TP \fBcheck_for_nonprintable\fR (default: "") (Used by LPR) check f and p formats for non_printable characters unless \fB\-b\fR (binary) or \fB\-l\fR (literal) command_line option is supplied. Note that files containing HPGL or other printer control languages would often be classed as ``non_printable''. .TP \fBconnect_grace\fR (default: 0 seconds) The time to pause before opening a new connection to a printer. This allows the printer time to recover from the previous job. .TP \fBconnect_interval\fR (default: 10 (seconds)) The time to pause after a failed connection or open of the printing device before attempting a new connection or open. .TP \fBconnect_timeout\fR (default: 10 (seconds)) The time to wait for a device open or connection to complete. A zero value is infinite timeout. .TP \fBretry_nolink\fR (default: true) When TRUE and the LPD server is printing or transferring a job, then an indefinite number of attempts to connect to or open the IO device will be made. .TP \fBdefault_banner_printer\fR (default: "") The default banner printer program to be used for printing banners. This should be specified in the LPD configuration file. .TP \fBdefault_format\fR (default: "f") Default format for printing jobs. .TP \fBdefault_logger_port\fR (default: 2001) specifies a default port number for logger information. See logger_destination for details. .TP \fBdefault_logger_protocol\fR (default: UDP) specifies a default protocol for logger information. See logger_destination for details. .TP \fBdefault_permission\fR (default: ACCEPT) Default permission for operations. .TP \fBdefault_printer\fR (default: "") The default printer to use if there is no PRINTER environment variable, the user has not specified a printer, or there is no printcap information. .TP \fBdefault_priority\fR (default: "A") Default priority (class) for printing jobs. This is also used as the job class. .TP \fBdefault_remote_host\fR (default: "%H") The default remote host to use. .TP \fBdefault_tmp_dir\fR (default: /tmp) Directory for temporary files. .TP \fBdomain_name\fR (default: "") This parameter is optional, and is appended to the hostname to make it into a fully_qualified domain name, ie. \fIclass.iona.ie\fR. It will only be used if the software cannot determine the domain name using other means, such as \fBgethostbyname(3n)\fR. .TP \fBff\fR (default: \\f) Formfeed string. .TP \fBfilter_ld_path\fR (default: _FILTER_LD_PATH_) The value for the environment variable LD_LIBRARY_PATH, both used when executing, and passed on to filters. This variable is used to find shared libraries on SunOS, Solaris and Linux. .TP \fBfilter_options\fR (default: "$C $F $H $J $L $P $Q $R $Z $a $c $d $e $f $h $i $j $k $l $n $p $r $s $w $x $y $-a") If the "bkf" (backwards compatible filter) flags is not set in the printcap entry and the original filter specification does not have a `$` in it, this option string is appended to a filter specification, and the string expanded with values from the printcap information and job information. (see of_filter_options, filter_options, bk_filter_options, bk_of_filter_options) .TP \fBfilter_path\fR (default: _FILTER_PATH_) The value for the environment variable PATH, both used to find filters and passed on to filters run by \fBlpd\fR and \fBlpr\fR. .TP \fBforce_poll\fR (default: no) Some software packages put print jobs directly into the spool queues. The \fBforce_poll\fR flag forces lpd to periodically poll spool queues looking for jobs and no server. The \fBpoll_time\fR variable sets the interval between polls. .TP \fBfull_time\fR (default: no) Use full time and date format in logging and error messages. .TP \fBfx\fR (default: "") See \fBprintcap\fP(5) for details. This specifies the job formats allowed for this queue. .TP \fBgroup\fR (default "daemon") The group to use for file ownership and process permissions. Used only by lpd; this can be the name of a group or a number. All filters will run as the specified group. Note that if the group value is 0, then the real user group of the process at startup will be used. .TP \fBkerberos_keytab\fR (default "/etc/lpd.keytab") The keytab file to be used by the LPD server when using built-in kerberos authentication. The keytab file should be owned by the LPD server, and be readable/writable only by it (i.e. - 600 permissions). .TP \fBkerberos_life\fR (default NULL) The lifetime of a Kerberos ticket. NULL selects the default lifetime. Time should be specified using the standard Kerberos time representations. .TP \fBkerberos_forward_principal\fR (default NULL) remote principal used by server when forwarding .TP \fBkerberos_renew\fR (default NULL) The renewal of a Kerberos ticket. NULL selects a non-renewable ticket. Time should be specified using the standard Kerberos time representations. .TP \fBkerberos_server_principal\fR (default "lpr") Server principal used when client sending to server or when server is originating connection to another server for forwarding. .TP \fBkerberos_service\fR (default "lpr") The service name used to make requests to the LPD server when using kerberos authentication. For example, if kerberos_service has the value lpr, the server is on host alpha.com, and the kerberos domain is ALPHA.COM, then the kerberos principal name would be: .br lpr/alpha.com@ALPHA.COM. .br .TP \fBla\fR (default: yes) See \fBprintcap\fP(5) for details. .TP \fBlf\fR (default: log) Name of the log file. .TP \fBlo\fR (default: lock) Name of the lock file. .TP \fBlocalhost\fR (default "localhost") The name of the localhost entry to be used for the TCP/IP loopback interface. The TCP/IP connection may originate from the local host; use this name to check to see if the local host address is in the IP address database, and use it as the origination address for local connections. This is done to avoid problems with multi-homed hosts who originate connections from different interfaces. .TP \fBlockfile\fR (default: /var/spool/lpd/lpd) The file used to indicate the presence of an \fBlpd\fR server running on the host. The lpd_port value is appended to the lockfile value to provide a unique lockfile even when different versions of LPRng are running on the same system. .TP \fBlogger_destination\fR (default: "") This specifies a destination for logger information generated by the lpd server. The formation of the destination specification is host[%port][,(TCP|UDP)]. For example, localhost%2001,UDP would send logger information to the localhost IP address, on port 2001 using the UPD protocol. The default port and protocol are set by the default_logger_port and default_logger_protocol configuration variables respectively. .TP \fBlongnumber\fR (default: no) RFC1179 requires 3 digit job numbers; setting longnumber to yes allows 6 digit numbers. If the backwards_compatible flag is set, only 3 digit numbers will be used. .TP \fBlpd_listen_port\fR (default: _LPD_LISTEN_PORT_) [ipaddr%]port The port that \fBlpd\fR binds to. If the parameter is set to off then \fBlpd\fR does not listen to any TCP port. See \fBlpd_port\fR for details of the format of the argument. If this is not set at all, then \fBlpd\dP will listen on \fBlpd_port\fP. .TP \fBlpd_port\fR (default: \fIprinter\fR) [ipaddr%]port The port that \fBlpr\fR and the other client programs send their requests to. The specification has the format ipaddr%port. If the IP address is specified then a bind to only this address and port is done. If the port value is not a number a service lookup is performed and the corresponding service port is used; see services(5). This parameter is useful for debugging a new installation of LPRng, in that running LPRng on a different port from the default will not interfere with a previous installation of LPD or LPRng. .TP \fBlpd_printcap_path\fR (default: "") The location of .B lpd server only printcap database information. If this is nonblank the \fBprintcap_path\P will not be used by the .B lpd server. .TP \fBmail_operator_on_error\fR (default: "") Put this person on the CC-list of the mail, if it is not a success mail. (So in addition to the person who made the printer request, also this person gets error messages, but no success messages.) .TP \fBmax_status_line\fR (default: 79) An integer value specifying the numbers of characters to be used for displaying simple job status; this includes the queue position, job identifier, job contents, size, and time. A 0 (zero) value indicates no restrictions. .TP \fBmax_status_size\fR (default: 10 (Kbytes)) An integer value specifying (in K bytes) the maximum size of the status file to be generated during printing operations. A 0 value will create unlimited size status files. When the file size exceeds this value, it is truncated to .B min_status_size K bytes. .TP \fBmc\fR (default: 1) See \fBprintcap\fP(5) for details. .TP \fBmin_status_size\fR (default: 0 (Kbytes)) Minimum status size. If 0, defaults to 20 percent of max_status_size. .TP \fBminfree\fR (default: 0) The amount of free space (in Kbytes) needed in the spool directory in order for a job to be accepted. If 0, there is no limit; if the parameter is the name of a file rather than a number, the file must contain a numerical minimum free value (in Kbytes). This value is overridden by the printcap .I mi field value. .TP \fBms_time_resolution\fR (default: FALSE) This flag causes the time information to be printed to millisecond accuracy. This is overkill for most purposes. .TP \fBof_filter_options\fR (default: "") If this is not set, the value defaults to the same as the filter_options value. This string is appended to a OF filter specification, and the string expanded with values from the printcap information and job information. If the "bkf" (backwards compatible filter) flags is set in the printcap entry, of bk_of_filter_options value is appended instead (see of_filter_options, filter_options, bk_filter_options, bk_of_filter_options) .TP \fBoriginate_port\fR (default: "721 731") A range of port numbers to originate requests from. When sending service requests, the software will try to open and bind to these ports to originate a request to a server. If no port is given, or all of the requested ports are unavailable or cannot be bound to, then a normal use port is requested. Note that on UNIX systems, if a port in the range 0-1023 is requested the EUID of the process must be root for the request to be granted. Note that RFC1179 specifies that requests must originate from ports in the range 721-731. .TP \fBpass_env\fR (default: "LANG,LC_CTYPE,LC_NUMERIC,LC_TIME,LC_COLLATE,LC_MONETARY,LC_MESSAGES,LC_PAPER,LC_NAME,LC_ADDRESS,LC_TELEPHONE,LC_MEASUREMENT,LC_IDENTIFICATION,LC_ALL") Client programs such as LPR, LPC, etc., will pass these environment variables to any filter programs they start. .TP \fBpoll_time\fR (default: 6000) Interval in seconds at which LPD checks for queues with jobs and no server active. See \fBforce_poll\fR as well. .TP \fBpl\fR (default: 66) See \fBprintcap\fP(5) for details. .TP \fBpr\fR (default: /bin/pr) See \fBprintcap\fP(5) for details. .TP \fBprintcap_path\fR (default: "_PRINTCAP_PATH_") The location of the printcap database file. If a file or filter does not exist, it is considered a fatal error. All valid entries in these files will be used. See PRINTCAP LOOKUP for details. .TP \fBperms_path\fR (default: /etc/lpd.perms:/usr/etc/lpd.perms:/var/spool/lpd/lpd.perms.%h) The location of the printer permissions database. If a file or filter does not exist, it is skipped. The first file or filter that exists and is readable will be used. See PERMISSIONS LOOKUP for details. .TP \fBpw\fR (default: 80) See \fBprintcap\fP(5) for details. .TP \fBsave_on_error\fR (default: no) Save a job in the spool queue if it has an error rather than removing it. .TP \fBsave_when_done\fR (default: no) Save a job in the spool queue after completion rather than removing it. .TP \fBsend_data_first\fR (default: no) Send data files of a job first, followed by the control file. .TP \fBsend_failure_action\fR (default: "") The lpd server uses this to determine the action to take when unable to print or process a job. The keyword \fIabort\fR will cause it to terminate operations, leaving the job in the queue, \fIremove\fR will cause it to remove the job, \fIretry\fR will cause it to retry the job, and \fIhold\fR will cause it to hold the job with an error indication. If the value is a filter, then the filter will be invoked and the exit status of the filter used to determine the actions. .TP \fBsend_job_rw_timeout\fR (default: 6000) When printing or sending a job to a remote printer, use this as a write to the device or remote host timeout value. If a timeout occurs, then a FAIL status is returned and the send_failure_action value is used to determine what to do on failure. .TP \fBsend_try\fR (default: 3) Numbers of times to try to send a job to the printer or remote host. A 0 value means an infinite number of times. .TP \fBsendmail\fR (default: "/usr/lib/sendmail -oi -t") If the argument is empty then all mail_related functionality is disabled. The arguments are the command to run when mail is to be sent. The command used needs to be able to accept the message on stdin, with \fIno\fR arguments. The message will contain the \fBTo:\fR, \fBFrom:\fR, \fBCc:\fR and \fBSubject:\fR headers. .TP \fBserver_tmp_dir\fR (default: /tmp) Temporary dir for the server. .TP \fBspool_dir_perms\fR (default: 042700) Permissions of the spool directories. .TP \fBspool_file_perms\fR (default: 0600) Permissions of the spool files. .TP \fBsyslog_device\fR (default: /dev/console) Log to this device if all else fails. .TP .BR unix_socket_path " (default: /var/run/lprng/socket)" Location of the Unix socket that lpd listens on and LPRng clients attempt to communicate to when host is localhost. Set to \fIoff\fR to disable listening and connecting via a Unix socket. .TP \fBuse_date\fR (default: no) No information about this parameter available. .TP \fBuse_identifier\fR (default: no) Add a job identifier line to the control file, using the 'A' entry in the control file. .TP \fBuse_info_cache\fR (default: yes) If this is set to \fIyes\fR, lpd.perms and printcap information lookups will be cached for later use. Only lookups in the main databases will be cached, not lookups in the per_printer databases. You can force the \fBlpd\fR to flush its cache and reread the permissions file by sending it a SIGHUP. .TP \fBuse_queuename\fR (default: no) Put an entry into control files identifying the spool queue the job was originally sent to. The entry has the form 'Qspoolname', and its value can be passed to filters. This is useful for setting up a spool queue which formats jobs in different ways, depending on the name of the queue. .TP \fBuse_shorthost\fR (default: no) By default, names of lpr job files used the originating host fully qualified domain name. This can exceed 14 characters, the limit of file names on some UNIX systems. If this is set to \fIyes\fR, the non-qualified name will be used, and if the host name is at most 8 characters the file name will be at most 14 characters long. .TP \fBuser\fR (default: daemon) The user that \fBlpd\fR and its filters runs as, and the owner of the spool directories and other lpd_writable files. This can be the name of a user or a number. If the user value is 0, then the real UID of the program when started will be used. This allows a non_root user to test the functionality of the LRPng software. .SH "PRINTCAP LOOKUP, DATABASE FILES AND FILTERS" .PP The printcap_path and printer_perms_path variables specify a list of either data base files or filters to use to get printcap or permission entries for a printer. To get information, the filter is started and a single line with the printer name is sent to it. Note that the printer name .I all is used to request information either about all printers, or a specific printer entry that has a list of all printers. See .BR printcap (5) for more details. .PP To find the printcap information, LPRng programs will read the database files specified in the .I printcap_path entry. The .I lpd server will read any additional files specified in the .I lpd_printcap_path entry. If any of the files is missing or non-readable a fatal error will result. After having searched the various files, if a filter has been specified the filter will be started and the required printer name will be sent to the filter. The output from the filter will be used as the printcap information. .SH "SECURITY-RELATED PARAMETERS" .PP Environment variables are sanitized by \fBlpd\fR and the other executables, in that the variables \fIIFS\fR, \fILD_PRELOAD\fR and \fILD_PROFILE\fR are all deleted from the environment passed to filters and any other sub_processes. For more reliability, script filters should set their own PATH and LD_LIBRARY_PATH variables. .PP All filters will run as the user and group specified by the group and user variables. .SH EXAMPLE .nf # lpd.conf generated from on Wed Apr 7 07:59:48 PDT 1999 # The values in this file are the default values. # If you modify the file, set the value to something other than the default # For example, '# default force_localhost' means # the 'force_localhost' option value is on or 1. # Uncomment this and change it to read 'force_localhost@' # Purpose: always print banner, ignore lpr -h option # default ab@ # Purpose: query accounting server when connected # default achk@ # Purpose: accounting at end (see also af, la, ar, as) # default ae=jobend $H $n $P $k $b $t # Purpose: name of accounting file (see also la, ar) # default af= af=acct # Purpose: automatically hold all jobs # default ah@ ah # Purpose: Allow duplicate command line arguments (legacy requirement) # default allow_duplicate_args@ .fi .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.perms(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH DIAGNOSTICS .nf Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .fi .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng mailing list is lprng@lprng.com; subscribe by sending mail to lprng-request@lprng.com with the word subscribe in the body. The software is available from ftp://ftp.lprng.com/pub/LPRng. .SH "AUTHOR" Patrick Powell . lprng-3.8.B/man/lpstat.n0000644000131400013140000000465611531672130012052 00000000000000.TH LPSTAT 1 2006-12-30 "LPRng" "lpstat command" .SH NAME lpstat \- compatibility program to get information about printers .SH SYNOPSIS .B lpstat .RB [ \-A ] .RB [ \-d ] .RB [ \-l ] .RB [ \-r ] .RB [ \-R ] .RB [ \-s ] .RB [ \-t ] .RB [ \-a [\fIlist\fP]] .RB [ \-c [\fIlist\fP]] .RB [ \-f [\fIlist\fP]] .RB [ \-o [\fIlist\fP]] .RB [ \-p [\fIlist\fP]] .RB [ \-P ] .RB [ \-S [\fIlist\fP]] .RI [ list ] .RB [ \-u [\fIlogin-ID-list\fP]] .RB [ \-v [\fIlist\fP]] .RB [ \-V ] .RB [ \-n ] .RB [ \-T\fIdbgflags\fP] .SH DESCRIPTION .B lpstat is a (partial) simulation for the Solaris SystemV R4 print facilities. Please use .B lpq instead. .SH OPTIONS .I list is a list of print queue names .TP .B \-A use authentication specified by AUTH environment variable .TP .BR \-a [ \fIlist\fP ] destination status .TP .BR \-c [ \fIlist\fP ] class status .TP .B \-d print default destination .TP .BR \-f [ \fIlist\fP ] forms status .TP .BR \-o [ \fIlist\fP ] job or printer status .TP .B \-n each -n increases number of status lines (default 1) .TP .B \-N maximum number of status lines .TP .BR \-p [ \fIlist\fP ] printer status .TP .B \-P paper types - ignored .TP .B \-r scheduler status .TP .B \-s summary status information - short format .TP .BR \-S [ \fIlist\fP ] character set - ignored .TP .B \-t all status information - long format .TP .BR \-u [ \fIjoblist\fP ] job status information .TP .BR \-v [ \fIlist\fP ] printer mapping .TP .B \-V verbose mode .TP .BI \-T dbgflags debug flags .TP .BR -a ", " -c ", " -f ", " -o ", " -n ", " -N " and " -p " produce a long status format. .SH "SEE ALSO" .BR lpd.conf (5), .BR lpc (8), .BR lpd (8), .BR checkpc (8), .BR lpq (1), .BR lprm (1), .BR checkpc (8), .BR printcap (5), .BR lpd.perms (5), .BR pr (1). .SH "AUTHOR" LPRng was written by Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net .\" This manpage is written by Bernhard R. Link .\" and available under GNU GPL v2 and any license LPRng is available under. .\" The descriptions are extracted from lpstat.c from Patrick Powell lprng-3.8.B/man/Makefile.in0000644000131400013140000003605211531672272012433 00000000000000# Makefile.in generated by automake 1.10.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : subdir = man DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = SOURCES = DIST_SOURCES = man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ "$(DESTDIR)$(man8dir)" man5dir = $(mandir)/man5 man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CHGRP = @CHGRP@ CHOWN = @CHOWN@ CLEAR = @CLEAR@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DL_LIBS = @DL_LIBS@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FILTER_LD_PATH = @FILTER_LD_PATH@ FILTER_PATH = @FILTER_PATH@ GMSGFMT = @GMSGFMT@ GREP = @GREP@ INCLUDELPDCONFLOCAL = @INCLUDELPDCONFLOCAL@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_MAN = @INSTALL_MAN@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ KERBEROS = @KERBEROS@ KRB5CONFIG = @KRB5CONFIG@ KRB_LIBS = @KRB_LIBS@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LOCKFILE = @LOCKFILE@ LPD_CONF_PATH = @LPD_CONF_PATH@ LPD_LISTEN_PORT = @LPD_LISTEN_PORT@ LPD_PERMS_PATH = @LPD_PERMS_PATH@ LPD_PRINTCAP_PATH = @LPD_PRINTCAP_PATH@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGMERGE = @MSGMERGE@ NOREMOTE = @NOREMOTE@ OBJEXT = @OBJEXT@ OPENSSL = @OPENSSL@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ PLUGINUSER_LDFLAGS = @PLUGINUSER_LDFLAGS@ PLUGIN_CFLAGS = @PLUGIN_CFLAGS@ PLUGIN_LDFLAGS = @PLUGIN_LDFLAGS@ PRINTCAP_PATH = @PRINTCAP_PATH@ PRIV_PORTS = @PRIV_PORTS@ PRUTIL = @PRUTIL@ SD_DEFAULT = @SD_DEFAULT@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ SSL_CA_FILE = @SSL_CA_FILE@ SSL_CA_KEY = @SSL_CA_KEY@ SSL_CERTS_DIR = @SSL_CERTS_DIR@ SSL_CRL_FILE = @SSL_CRL_FILE@ SSL_LDADD = @SSL_LDADD@ SSL_SERVER_CERT = @SSL_SERVER_CERT@ SSL_SERVER_PASSWORD_FILE = @SSL_SERVER_PASSWORD_FILE@ STRIP = @STRIP@ UNIXSOCKETPATH = @UNIXSOCKETPATH@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ XGETTEXT = @XGETTEXT@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ builddir = @builddir@ configdir = @configdir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ filterdir = @filterdir@ host_alias = @host_alias@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lpdbindir = @lpdbindir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ plugindir = @plugindir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in man_MANS = cancel.1 checkpc.8 lp.1 lpbanner.1 lpc.8 lpd.8 lpd.conf.5 \ lpd.perms.5 lpf.1 lpq.1 lpr.1 lprm.1 lpstat.1 monitor.1 pclbanner.1 \ printcap.5 psbanner.1 lprng_certs.1 lprng_index_certs.1 CLEANFILES = $(man_MANS) EXTRA_DIST = cancel.n checkpc.n lp.n lpbanner.n lpc.n lpd.n lpd.conf.n \ lpd.perms.n lpf.n lpq.n lpr.n lprm.n lpstat.n monitor.n pclbanner.n \ printcap.n psbanner.n lprng_certs.n lprng_index_certs.n all: all-am .SUFFIXES: $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign man/Makefile'; \ cd $(top_srcdir) && \ $(AUTOMAKE) --foreign man/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-man1: $(man1_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \ done uninstall-man1: @$(NORMAL_UNINSTALL) @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.1*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 1*) ;; \ *) ext='1' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \ done install-man5: $(man5_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)" @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \ done uninstall-man5: @$(NORMAL_UNINSTALL) @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.5*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 5*) ;; \ *) ext='5' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \ rm -f "$(DESTDIR)$(man5dir)/$$inst"; \ done install-man8: $(man8_MANS) $(man_MANS) @$(NORMAL_INSTALL) test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ else file=$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \ done uninstall-man8: @$(NORMAL_UNINSTALL) @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \ for i in $$l2; do \ case "$$i" in \ *.8*) list="$$list $$i" ;; \ esac; \ done; \ for i in $$list; do \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ *) ext='8' ;; \ esac; \ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ inst=`echo $$inst | sed -e 's/^.*\///'`; \ inst=`echo $$inst | sed '$(transform)'`.$$ext; \ echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \ rm -f "$(DESTDIR)$(man8dir)/$$inst"; \ done tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ else \ test -f $(distdir)/$$file \ || cp -p $$d/$$file $(distdir)/$$file \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(MANS) installdirs: for dir in "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-exec-am: install-html: install-html-am install-info: install-info-am install-man: install-man1 install-man5 install-man8 install-pdf: install-pdf-am install-ps: install-ps-am installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-man uninstall-man: uninstall-man1 uninstall-man5 uninstall-man8 .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic distclean \ distclean-generic distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-man1 install-man5 install-man8 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ pdf-am ps ps-am uninstall uninstall-am uninstall-man \ uninstall-man1 uninstall-man5 uninstall-man8 %.1 %.5 %.8: $(srcdir)/%.n Makefile rm -f $@ sed \ -e "s!_PRINTCAP_PATH_!${PRINTCAP_PATH}!" \ -e "s!_FILTER_LD_PATH_!${FILTER_LD_PATH}!" \ -e "s!_FILTER_PATH_!${FILTER_PATH}!" \ -e "s!_LPD_PERMS_PATH_!${LPD_PERMS_PATH}!" \ -e "s!_LPD_CONF_PATH_!${LPD_CONF_PATH}!" \ -e "s!_LOCKFILE_!${LOCKFILE}!" \ -e "s!_SSL_CA_FILE_!${SSL_CA_FILE}!" \ -e "s!_SSL_CA_KEY_!${SSL_CA_KEY}!" \ -e "s!_SSL_CERTS_DIR_!${SSL_CERTS_DIR}!" \ -e "s!_SSL_SERVER_CERT_!${SSL_SERVER_CERT}!" \ -e "s!_SSL_SERVER_PASSWORD_!${SSL_SERVER_PASSWORD}!" \ -e "s!_LPD_LISTEN_PORT_!${LPD_LISTEN_PORT}!" \ $< > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: lprng-3.8.B/man/printcap.n0000644000131400013140000013173411531672130012361 00000000000000.TH PRINTCAP 5 2006-12-09 "LPRng" "lpd configuration" .SH NAME printcap \- printer capability data base .SH SYNOPSIS printcap database .SH DESCRIPTION The format of the LPRng .I printcap database was based on the .IR termcap (5) data base file format. Entries in the .I printcap Each entry in the data base is used to define various options and values to control the printing and spooling of print jobs. .SH "LPD.CONF, SYSTEM AND USER PRINTCAP FILES" Default configuration values are read from the LPRng configuration file _LPD_CONF_PATH_, consult the lpd.conf(5) man page for details about them. The system printcap file _PRINTCAP_PATH_ contains information common to all users and the LPRng printing system. Finally, the user printcap files is in ${HOME}/.printcap and contain user configurable information for printer information. The values in the user printcap file override values in the printcap file which override the default values in the _LPD_CONF_PATH_ file. .LP The user printcap file is used by client programs such as .I lpr , .I lprm , .I lpq , and .I lpq to allow the user to define either a special set of printers, provide additional configuration information, or to modify default settings in the _PRINTCAP_PATH_, or _LPD_CONF_PATH_ file. .SH CAPABILITIES The printcap database files format is based on the .I termcap (5) database format, modified as follows. Leading whitespace on each line is discarded, and blank lines or lines which then start with a comment character (#) are discarded. A line which does not start with a colon (:) or bar (|) starts a printer entry definition. Lines ending with a backslash (\e) are assumed to continue to the next line; this is for compatibility with other historical printcap file formats. Trailing blanks and tabs (whitespace) for an option value are deleted unless the last one is escaped with a backslash (``\\''). If a colon character value is required then the \e: escape sequence can be used, e.g.: dest=ftp\e://address/file. .LP A printer definition starts with a primary printer name, followed by zero or more alternative printer names, followed by a set of keyword entries and values. For example: .nf .sp .ft CW #comment # primary printer name lp #alternate names |lp2|lp3 |Example of a printer :sd=/usr/spool/LPD/lp :rw:lp=/dev/lp:mx#100 include /etc/printcap/mainprintcap .sp .fi .LP The special printcap definition .I include will read the named file, which must have an absolute pathname, as the next set of printcap entries. .LP Keywords can be 1 to an indefinite number of characters long, and are case sensitive. Values for keywords can be strings (:st=string:), signed integer values using the C language notation, (:nu#12:max#-2:mask#0x1EF:), or flags (:flag: to set to 1, :flag@: to clear to 0). Integer values must be representable as 32 bit 2's complement numbers; care should be taken with extremely large numbers. .LP If the primary name of a printcap entry starts with a punctuation character, then the entry may be referenced using the .I tc capability, but is ignored otherwise. This allows common printcap information to be placed in a single entry. .LP The special printcap entry .I oh (i.e. - only this host) may be used to select a printcap entry for use by one or more hosts. The oh entry can be a list of one or more host names or glob type of patterns. These patterns are first applied to the host's fully qualified domain name, and then used to to a lookup of an IP address. If either the glob match or the host has a matching IP address then the printcap entry is selected for use. In addition, the .I server flag indicates that only the LPD server is to use this printcap entry. This allows client and server printcap information be to be segregated in a simple manner. .LP The following is a list of the keywords currently used by the LPRng software. Many of these keywords are used only by the .I LPD server, others are used by the client programs .I LPR, .I LPC, .I LPRM, .I PAC, as well as the server. In the Use column in the table below, an .B A stands for all programs, .B D stands for .IR lpd , and .B R stands for the client programs such as .I LPR. .LP Some of these entries can only appear or have an effect if they are in the lpd.conf initialization file. See lpd.conf(5) for further details. .SH "ENTRIES BY ALPHABETICAL ORDER" .sp .nf .ta \w'\0\0\0\0'u +\w'\0\0\0\0'u +\w'Type 'u +\w'Default 'u +4n +4n +4n +4n +4n +4n 8i \fBFL Use Type Default Description\fR Xf D str NULL output filter for format X (used by lpd). 'filter' sets default filter ab D bool false always print banner, ignore lpr -h option achk D bool false If TRUE LPD and the :as specifies a remote host or filter or the :af specifies a remote host or filter then after writing the accounting information to the destination a reply will be read. The value of the reply determines how the job is to be handled. ae D str accounting format for end of job or a program to run to record accounting information (see also af, la, ar and Accounting). af D str NULL accounting file, filter, or remote accounting server (see also la, ar, as, ae, achk). If format is |/path then the program will be started and accounting information will be written to the program STDIN. If the format host%port, a tcp/ip connection will be made to port on host and the accounting information written to the remote host. In both of these cases the write operation must succeed or an error will result. If the format is neither of these cases then the value will be treated as a file and accounting information appended to the file if it exists. The accounting file will not be created, it must exist for LPD to append data to it. The :as and :ae fields have the accounting information. ah D bool false auto-hold - job held until explicitly released all A str NULL a list of all printers; (see ALL PRINTERS) allow_duplicate_flags A bool false allow duplicate command line flags; last overwrites earlier allow_getenv A bool (compile time) allows LPRng software to use the LPD_CONF environment variable to specify the location of a configuration file. This is for testing only. allow_user_logging A bool false if mail is requested using lpr -mhost%port,prot operations, and the allow_user_logging flag is true, then job logging information will be sent to host%port,prot. allow_user_setting A str NULL allow these users to impersonate other users with the lpr -U user@host, lpc -U user@host, etc., options append_z A str append these options to the -Z options for the job ar D bool true write remote transfer accounting (if af, and as/ae set) architecture A str (compile time) architecture the software was compiled for. (Obsolete.) as D str accounting format for start of job or a program to run to record accounting information (see also af, la, ar and Accounting). auth R str NULL client to server authentication type be D str banner printing program for end (overrides bp, hl) bk R bool false Berkeley-compatible: be strictly RFC-compliant or more exactly, BSD LPR compatible when sending jobs. bk_filter_options D str (see source code) when bk flag set, options for non OF print filters bk_of_filter_options D str (see source code) when bk flag set, options for OF print filters bkf R bool false use bk_filter_options and bk_of_filter_options when invoking print filter. bl D str banner line - sent to banner printer program default: $-'C:$-'n Job: $-'J Date: $-'t expands to: Class:User Job: job Date: date This is to force compatibility with vintage print filters that require a non-standard banner string. Usually used with :sb: option. bp D str banner printing program (see hl) (default: configuration variable default_banner_printer) bq_format D str l format of output from bounce queue filters br D num none if lp is a tty, set the baud rate (see ty) break_classname_priority_link A flag false Do not set priority to first letter of class name bs D str banner printing program for start (overrides bp, hl) cf D str NULL cifplot data filter check_for_nonprintable R bool false lpr checks f and p formats for printable files check_for_protocol_violations R bool false check for RFC1179 protocol violations chooser D str load balance queue destination chooser program chooser_interval D num 10 load balance queue does checks for a destination queue available at this interval chooser_routine D bool false use the user provided chooser routine for this queue class_in_status A bool true show class name in lpq status rather than priority cm A str NULL comment identifying printer (LPQ) config_file A str _LPD_CONF_PATH_ location of LPRng configuration information. Compile time option only - see allow_getenv. connect_grace A num 0 time between jobs to allow printer recovery connect_interval A num 10 time between open or connection attempts connect_timeout A num 10 timeout value for connection or open control_file_line_order D str NULL Put the control file lines in a specific order control_filter D str NULL Filter for control file. Used when sending job to remote spool queue. create_files D bool false create log, debug, etc., files automatically db A str NULL LPD debug options when serving this queue. See lf (log file) entry as well. default_format R str f default format for printing jobs default_permission D str A default permission for operation default_printer A str lp default printer for printing jobs default_priority R str A default priority for printing jobs default_remote_host A str localhost default remote host for printing operations default_tmp_dir A str /tmp default temporary directory destinations D str NULL names of printers that lpq/lprm should talk to find a job that has been processed by a router script (see README.routing) df D str NULL tex data filter (DVI format) done_jobs D num 1 retain status for last N jobs done_jobs_max_age num 0 remove status older than N seconds (0 - no removal) exit_linger_timeout A num 10 socket SO_LINGER timeout value fd D bool false if true, no forwarded jobs accepted ff D str ``\ef'' string to send for a form feed (see INITIALIZATION) filter D str NULL default filter to use for printing file filter_ld_path D str (see source) the LD_LIBARY_PATH environment variable value for filters filter_options D str (see source code) when bk flag clear, options for non OF print filters filter_path D str (default '/bin:/usr/bin') the PATH environment variable value for filters filter_poll_interval D num 30 interval to poll OF filter filter_stderr_to_status_file D bool false set the filter STDERR to the status file and do no report errors in the queue status file. fo D bool false print a form feed when device is opened force_fqdn_hostname A bool FALSE Force a fully qualified host name in control file force_ipadddr_hostname A bool FALSE Force the IP address of the host to be used for the hostname in control file force_localhost A bool TRUE Forces the clients programs (lpr, lpc, etc.) to send all print jobs and requests to the server running on the localhost entry for action. This flag effectively forces BSD LPR behavior. force_lpq_status D str NULL Specifies a list of LPQ formats and hosts which get status returned in this format. For example force_lpq_status=s=pc*;l=mac* will cause hosts whose FQDN matches pc* to get short status and those which match mac* to get long format. force_queuename A str NULL When :qq: flag or use_queuename configuration is enabled, specifies the queuename to be used for control file Q information. ff_separator D bool false need form feeds to separate job files fq D bool false print a form feed when device is closed full_time D bool detailed time format specification in log messages fx A str NULL valid output filter formats i.e. ``flp'' would allow f, l, and p default is to allow all formats gf D str NULL graph data filter (plot (3X) format) generate_banner D bool false generate a banner when forwarding job group D str daemon LPD server group id for execution hl D bool false print banner after job instead of before if D str NULL filter command, run on a per-file basis ignore_requested_user_priority D bool false Ignore the requested user priority when ordering jobs. Prevents students... um... users from queue jumping. ipv6 A bool false Use IPV6 keepalive A bool true set socket SO_KEEPALIVE option kerberos_keytab D str /etc/lpd.keytab Kerberos lpd server keytab file kerberos_life D str NULL Kerberos lpd server key lifetime kerberos_renew D str NULL Kerberos lpd server key renewal time kerberos_server_principle D str NULL Kerberos remote lpd server principle kerberos_service D str lpr Kerberos service used in principle requests la D bool true write local printer accounting (if af is set) ld D str NULL leader string printed on printer open (see INITIALIZATION) lf D str ``log'' error and debugging log file (LPD) lk D bool false lock the lp device to force arbitration lockfile D str /var/spool/lpd/lpd lpd lock file (used only in lpd.conf). The lpd_port port value is appended to the lockfile value to provide a unique lockfile even when different versions of LPRng are running on the same system. logger_destination D str NULL destination for logging information. Format is host%port logger_max_size D num 1024 logger file maximum size in K logger_path D str NULL logger file pathname logger_timeout D num 0 logger connection timeout. 0 is no timeout. longnumber D bool false use 6 digit job numbers lp D str NULL device name or pipe to send output to lpd_bounce A bool FALSE Forces lpd to filter jobs and then forward them as a single file (See Bounce Queues) lpd_force_poll A bool FALSE Forces lpd to periodically poll lpd queues. lpd_poll_time A num 600 Check queues for work at this interval; start queues in groups of 'lpd_poll_servers_started' at intervals of 'lpd_poll_start_interval' seconds lpd_poll_start_interval A num 10 Start 'lpd_poll_servers_started' queue servers at this interval. lpd_poll_servers_started A num 10 Start 'lpd_poll_servers_started' queues at once lpd_port D str printer format is [ipaddr%]port. If the ipaddr is present then the lpd listening socket is bound to the specified ip address and port only, otherwise it is bound to all interfaces. If the port value is not a number then the then the getservbyname() system call is used to get the port number. lpd_printcap_path D str (see source) printcap path for lpd, used instead of printcap path (configuration value only) lpr_bounce R bool true Forces lpr to filter jobs and then send them. (See Bounce Queues) lpr_bsd R bool false when set, LPR -m will not take argument, but will use $USER value for return mail address. mail_from D str NULL specifies the user part of email From: address mail_operator_on_error D str NULL send mail to this user when LPD encounters printing error. max_connect_interval A num 60 maximum time between connection attempts max_log_file_size D num 0 maximum log file size in K bytes (0 is unlimited) spool queue log file truncated to min_log_file_size when value is nonzero and limited exceeded. max_servers_active D num 0 maximum servers that LPD will allow to be active at one time. 0 selects the system default, which is usually pretty small, perhaps 10. (configuration value only). max_status_line D num 79 maximum number of characters on an LPQ status line max_status_size D num 10 maximum size (Kbytes) of status file mc R num 1 maximum copies allowed min_log_file_size D num 0 minimum size (Kbytes) of log file min_status_size D num 2 minimum size (Kbytes) of status file minfree D str 0 minimum space (in K) for spool directory ml R num 32 minimum printable characters for printable check ms_time_resolution D bool false log time in milliseconds mx R num 0 maximum job size in K, 0 = unlimited nb D num 0 if non-zero, do a nonblocking open on lp device nf D str NULL DITROFF data filter network_connect_grace A num 0 time between attempts to send jobs to spooler Useful when dealing with network printer using LPD interface to allow a bit of time between jobs. nline_after_file D bool false put the N (filename) after the data file information in the control file. Use to handle systems that want it that way. of D str NULL output filter, run once for all output (used for banner printing, form feeds between files) of_filter_options D str (see source code) when bk flag clear, options for OF print filters oh A str NULL Specific printcap entry for host; (printcap entry ignored unless IP address of host and entry value match. Entry is used first to do glob style match against the host's fully qualified domain name, and then interpreted as a general IP address) order_routine D bool false use a user provided routine to generate queue order information. originate_port A str 512 1023 when originating a connection, use ports in this range. pass_env A str LANG,LC_CTYPE,LC_NUMERIC,LC_TIME,LC_COLLATE,LC_MONETARY,LC_MESSAGES,LC_PAPER,LC_NAME,LC_ADDRESS,LC_TELEPHONE,LC_MEASUREMENT,LC_IDENTIFICATION,LC_ALL if not the LPD server, sanitize and put these variables in a filter environment variable list. perms_path A str _LPD_PERMS_PATH_ location of perms file (used in lpd.conf) pl D num 66 page length (in lines) pr D str ``/bin/pr'' pr program for p format prefix_o_to_z D bool false prefix the control file O line to the control file Z line. prefix_z D str NULL prefix the specified options to the control file Z line. prefix_z_to_o D bool false prefix the control file Z line to the control file O line. printcap_path A str _PRINTCAP_PATH_ location of printcap file (only in lpd.conf) ps A str ''status'' printer status file name pw D num 132 page width (in characters) px D num 0 page width in pixels (horizontal) py D num 0 page length in pixels (vertical) qq A bool false LPR - puts in the queue name (Q entry) in the job control file when spooled or transferred. LPD - when receiving or transferring a job, if the queue name (Q entry) in the job control file is not present, puts in the queue name. queue_control_file D str control.%P name of the queue control file queue_lock_file D str %P name of the queue lock file queue_status_file D str status.%P name of the queue status file queue_unspooler_file D str unspooler.%P name of the queue unspooler status file remote_support A str NULL if non-null, specifies allowed operations to remote queue. R=lpr, M=lprm, Q=lpq, V = lpq -v, C=lpc. For example, remote_support=RM would only allow LPR and LPRM operations. remove_z D str null remove these options from the control file Z line report_server_as A str NULL use the str value as the name of the server when reporting LPQ or LPC status. require_explicit_q Require a queue to be specified, do not use default queue from printcap. retry_econnrefused A bool true if set, retry a connection to a remote system when an ECONNREFUSED error is returned. retry_nolink D bool true if LPD is sending a job or opening a device for printing and the value is true, then the connection or device open is repeated indefinitely. return_short_status D str NULL Some legacy (non-LPRng) LPQ programs expect 'short' status to be returned. This option allows you to specify which hosts will get it. The value is a list of hosts and/or IP addresses and masks to which the LPD server will provide short status. For example: return_short_status=192.8.0.0/16 will make LPD return short status to all requests from hosts in subnet 192.8.0.0. (See short_status_length) reuse_addr A bool false if set, use SO_REUSEADDR on outgoing connection ports. This reduces the problems with exhausting port numbers. (usually only in lpd.conf) reverse_lpq_status D str NULL When a lpq status request arrives from one of the specified hosts or IP addresses, then the LPQ status format is inverted. For example, if reverse_lpq_status=host*,127.0.0.0/8, then when a LONG status request arrives from host1 or from IP address 127.0.0.1, the SHORT status will be returned. reverse_priority_order D bool false Make highest priority A, lowest Z rf D str NULL filter for printing FORTRAN style text files rg A str NULL (restrict to group members) Restrict use of queue to users which are members of specified groups. rm A str NULL remote-queue machine (hostname) (with rp) router D str NULL script that dynamically re-routes a job (see README.routing) rp A str NULL remote-queue printer name (with rm) rw D bool false open the printer for reading and writing safe_chars D str NULL additional safe characters for control file contents save_on_error D bool false Save job when an error occurs to allow post-mortem diagnostics or reprinting. This should only be set on print queues. It is also a diagnostic aid. save_when_done D bool false Save job when done (printed, transferred) to allow retry at a later time. This should only be set on print queues. It is also a diagnostic aid. sb D bool false short banner (one line only) sd A str NULL spool directory (only ONE printer per directory!) send_block_format A bool false Use the LPRng extended 'block job' job transmission method to send a job to a remote site. send_data_first A bool false send data files then control files when sending a job to a remote host. send_failure_action D str "remove" Action on print or transmission failure after send_try attempts; use the following codes: 'success' (JSUCC) - treat as successful 'abort' (JABORT) - abort printer 'retry' (JRETRY) - retry job 'remove' (JREMOVE)- remove job 'hold' (JHOLD) - hold job If the value is "|/filter", the filter will be run and the number of attempts can be read from standard input. The filter should exit with one of the error codes listed above to cause the appropriate action. send_job_rw_timeout A num 6000 timeout on read/write operations when sending job to printer or remote host (0 value is no timeout) send_query_rw_timeout A num 6000 timeout on read/write operations when performing a status operation (0 value is no timeout) send_try A num 3 number of times to try sending or printing a job. 0 is infinite. sendmail D str /usr/sbin/sendmail -oi -t sendmail command to send mail to user. Flags must be set so that address and other information is taken from standard input. server A bool false printcap entry for server only server_auth_command A str NULL authentication command for server program server_tmp_dir D str /tmp temporary directory for server to create files when there is no spool directory. server_user D str daemon server user name used in authentication operations sf D bool true suppress form feed separators between job files sh D bool false suppress headers and/or banner page shell D str /bin/sh SHELL environment variable value for filters short_status_length D num 1 If the return_short_status value is used and has a match against a requesting address, this amount of status is set by the short_status_length option. For most legacy systems a 1 is suitable (1 line of status). socket_linger A num 10 if nonzero, forces a SO_LINGER operation to be done on all TCP/IP connections. This usually corrects a problem with missing last data transmissions to remote hosts. spool_dir_perms D num 042700 permissions for spool directory spool_file_perms D num 0600 permissions for spool file ss D str NULL name of queue that server serves (with sv) ssl_XXX D str NULL SSL authentication and encryption options. See lprng_certs(1) for details. ssl_ca_file str A _SSL_CA_FILE_ SSL signing certificate file ssl_ca_path str A NULL SSL signing certificate directory. Default is directory containing ssl_ca_file. ssl_server_cert str A _SSL_SERVER_CERT_ SSL server certificate ssl_server_password str A _SSL_SERVER_PASSWORD_ SSL server certificate password stalled_time D num 120 Time after which to report an active job as stalled stop_on_abort D bool true Stop processing queue when print filter aborts. stty D str NULL stty settings for serial connected printer suspend_of_filter D bool true suspend OF filter and restart. If false, close filter and start new one for each activity. sv D str NULL names of servers for queue (with ss) syslog_device D str /dev/console name of syslog device to use if no syslog facility tc A str NULL reference to a printcap entry to include as part of the current entry. tf D str NULL troff data filter (C/A/T phototypesetter) tr D str NULL trailer string to print when queue empties translate_format D str NULL translate job format (similar to tr(1) utility) on outgoing jobs. Example: translate_format=pfml p format changed to f, m format to l translate_incoming_format D str NULL translate job format (similar to tr(1) utility) on incoming jobs. See translate_format. use_date A bool true add date line ('D') to control file use_identifier R bool true add job identifier lines ('A') in the control file use_info_cache D bool true cache printcap information use_shorthost R bool false use only the hostname for job control and data file names. Host information in job file will still be fully qualified domain name. user D str daemon LPD effective user (EUID) for SUID operations wait_for_eof D bool true wait for EOF on input when readable IO device, do not close immediately at job end. vf D str NULL (Versatek) raster image filter .fi .SH "ENTRIES BY FUNCTION" .LP See the alphabetical listing for detailed information. .sp .nf .ta \w'\0\0\0\0'u +\w'\0\0\0\0'u +\w'Type 'u +\w'Default 'u +4n +4n +4n 8i .sp .B "Filters and Page Formats" Xf D str NULL output filter for format X (used by lpd) 'filter' sets default filter cf D str NULL cifplot data filter control_filter D str NULL Filter for control file. Used when sending job to remote spool queue. df D str NULL tex data filter (DVI format) direct_read D bool false if true, filters are given direct access to file. This means no progress indication possible. fx A str NULL valid output filter formats i.e. ``flp'' would allow f, l, and p default is to allow all formats gf D str NULL graph data filter (plot (3X) format) if D str NULL filter command, run on a per-file basis lpd_bounce R bool false Forces lpd to filter jobs and then forward them. (See Bounce Queues) lpr_bounce R bool false Forces lpr to filter jobs and then send them. (See Bounce Queues) nf D str NULL DITROFF data filter of D str NULL output filter, run once for all output pl D num 66 page length (in lines) pr D str ``/bin/pr'' pr program for p format pw D num 132 page width (in characters) px D num 0 page width in pixels (horizontal) py D num 0 page length in pixels (vertical) rf D str NULL filter for printing FORTRAN style text files translate_format D str NULL translate job format (similar to tr(1) utility) only valid when transferring to remote spool queue. Example: translate_format=pfml p format changed to f, m format to l tf D str NULL troff data filter (C/A/T phototypesetter) vf D str NULL (Versatek) raster image filter .B Banners ab D bool false always print banner, ignore lpr -h option be D str banner printing program for end (overrides bp, hl) bp D str banner printing program (use hl to print banner at end) bs D str banner printing program for start (overrides bp, hl) hl D bool false print banner after job instead of before sb D bool false short banner (one line only) sh D bool false suppress headers and/or banner page, overrides ab .B Accounting ae D str accounting format for end of job or a program to run to record accounting information (see also af, la, ar and Accounting). af D str NULL name of accounting file (see also la, ar) ar D bool true write remote transfer accounting (if af, and as/ae set) as D str accounting format for start of job or a program to run to record accounting information (see also af, la, ar and Accounting). la D bool true write local printer accounting (if af is set) .B "Queue control" ah D bool false auto-hold - job held until explicitly released bk R bool false backwards-compatible: be strictly RFC-compliant bkf R bool false backwards-compatible filter: use Berkeley filter options bqfilter D bool false if a bounce queue (sends jobs to remote site) then when bqfilter true and a format filter is specified, sends data files through format filter before transfer. See also 'qq'. cd D str NULL control information directory for LPD server cm A str NULL comment identifying printer (LPQ) fd D bool false if true, no forwarded jobs accepted lf D str ``log'' error and debugging log file (LPD) longnumber D bool false use 6 digit job numbers mc R num 1 maximum copies allowed ml R num 32 minimum printable characters for printable check minfree D str 0 minimum space (Kb) to be left in spool filesystem You can also use nnnM for nnn megabytes. mx R num 0 maximum job size (1Kb blocks, 0 = unlimited) ps A str ''status'' printer status file name nw A bool false spool dir is on an NFS file system (take precautions when reading/writing files) qq A bool false place queue information in control file. See alphabetical for details. rm A str NULL remote-queue machine (hostname) (with rp) rp A str NULL remote-queue printer name (with rm) sd A str NULL spool directory (only ONE printer per directory!) ss D str NULL name of queue that server serves (with sv) sv D str NULL names of servers for queue (with ss) sc R bool false suppress multiple copies use_auth A str NULL authentication to use use_date A bool true add date line ('D') to control file use_identifier R bool true add job identifier lines ('A') in the control file use_shorthost R bool false use only the hostname for job control and data file names. Host information in job file will still be fully qualified domain name. .B "Connection and Interface to Printer" db A num 0 debug level when using this printer connect_interval A num 10 time between open or connection attempts connect_timeout A num 10 timeout value for connection or open (0 is infinite number) ff D str ``\ef'' string to send for a form feed (see INITIALIZATION) fo D bool false print a form feed when device is opened fq D bool false print a form feed when device is closed ld D str NULL leader string printed on printer open (see INITIALIZATION) lp D str NULL device name or pipe to send output to lk D bool false lock the lp device to force arbitration max_connect_interval A num 60 maximum time between connection attempts nb D num 0 if non-zero, do a nonblocking open on lp device retry_econnrefused A bool true if set, retry a connection to a remote system when an ECONNREFUSED error is returned. retry_nolink D bool true if LPD is sending a job or opening a device for printing and the value is true, then the connection or device open is repeated indefinitely. rs D num 300 number of seconds between spool queue status scans rt D num 3 number of times to try printing (0=infinite). rw D bool false open the printer for reading and writing save_on_error D bool false See above. save_when_done D bool false See above. send_failure_action D str remove See above. send_try alias for rt sf D bool true suppress form feed separators between job files socket_linger A num 10 if nonzero, forces a SO_LINGER operation to be done on all TCP/IP connections. This usually corrects a problem with missing last data transmissions to remote hosts. tr D str NULL trailer string to print when queue empties .B "Serial Line Setup" br D num none if lp is a tty, set the baud rate (see ty) stty D str NULL stty commands to set output line characteristics alias is sy, ms xs D num 0 like `xc' but set bits (see STTY) .B Miscellaneous .nf all A str NULL a list of all printers; (see ALL PRINTERS) destinations D str NULL names of printers that lpq/lprm should talk to find a job that has been processed by a router script (see README.routing) forward_auth D str NULL server to server authentication type, e.g. kerberos force_localhost A bool TRUE Forces the clients programs (lpr, lpc, etc.) to send all print jobs and requests to the server running on the localhost entry for action. This flag effectively forces BSD LPR behaviour. force_queuename A str NULL See above. logger_destination D str NULL destination for logging information. Format is host[%port][,(TCP|UDP)] oh D str NULL Specific printcap entry for host. See above. remote_support A str RMQC if non-null, specifies allowed operations to remote queue. R=lpr, M=lprm, Q=lpq, C=lpc router D str NULL script that dynamically re-routes a job (see README.routing) server A bool false printcap entry for server only server_auth_command D str NULL authentication command for server to use. tc A str NULL reference to a printcap entry to include as part of the current entry. use_auth D str NULL client to server authentication type, e.g. kerberos user_auth_command R str NULL authentication command for user (client program) .nf .SH "FILTERS" .PP By convention, all output filter names have the form .B Xf, where .B X is the lower case letter corresponding to the lpr formatting option. The .B filter option can specify a default filter for job files. .PP The .B of filter is started for each job and is used to print the banner page and any FF separators between individual files of the job. It is sent a special stop sequence by the lpd server, and must suspend operations until sent a SIGCONT signal. A file or job filter is run separately for each file; at the end of the job the .B of filter is restarted and used to print the trailing banner (if any) and FF separators. .LP Filters are invoked with a standard set of options defined by the bk_filter_options (backwards compatible), bk_of_filter_options (backwards compatible OF filter), and filter_options configuration variables. See the lpd(8) manual page for details. If the first characters of the filter specification are -$, i.e.- Xf=-$ filter, then the command line options are not added. Currently, the options are: .nf bk_filter_options $P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a bk_of_filter_options $w $l $x $y filter_options $C $F $H $J $L $P $Q $R $Z $a $c $d \e $e $f $h $i $j $k $l $n $s $w $x $y $-a .fi .SH "SPOOL QUEUES" .LP Printcap entries which have a spool directory value (sd) are called spool queues. Jobs sent to a printer with a spool queue are place in the spool directory. When checking the spool queue for jobs, the server will check to see if there is a printcap file in the directory with the name .BR printcap. host. If there is, the additional printcap information is processed and used by the server. .LP If the spool directory is NFS exported, then remote hosts can manipulate the spool entries directly; this can have catastrophic effects, especially in systems where the NFS implementation has defects. The printcap information is particularly vulnerable to exploitation, as well as symbolic links, jobs which cannot be removed, etc. .SH "LOCAL PRINTERS" .LP Local printers have an .B lp entry, which is the device that output should be sent to, usually a serial port tty. PLP supplements this by using the lp field to indicate a remote printer, or by allowing communication with the printer using a separate program, known as an .I lp-pipe, instead of a serial line. If the printcap .B lp entry contains a string of the form .B printer@host, jobs are forwarded to the specified remote printer on the host. If the printcap .B lp entry contains a string of the form .B | command args , the command .B command is run, with the arguments .B args . This can be used to communicate with printers connected to network terminal servers, some TCP/IP-capable printers, and just about anything you can hack up a communication program for. Read the LPRng Manual for more details. .SH "STTY OPTIONS" .PP The .B stty printcap parameter recognizes a set of .IR stty (1) options that can be used to set serial line characteristics for the printer. However, due to the differences between implementations of UNIX, there are several sets of .B ty options supported. Invoke .IR lpd (8) with the ``-v'' command-line option to see which set your installation is using. .PP Systems using the .IR sgtty tty manipulation interface may use the following .IR stty (1) options: .nf .PP .ta 16n +16n +16n +16n +16n +16n +16n +16n +16n bs0 bs1 [-]cbreak cooked cr0 cr1 cr2 cr3 [-]decctlq [-]echo [-]even ff0 ff1 [-]lcase [-]litout nl0 nl1 nl2 nl3 [-]nl [-]noflsh new [-]nohang old [-]odd [-]raw start stop tab0 tab1 tab2 [-]tabs [-]tandem tek ti700 [-]tilde tn300 tty33 tty37 vt05 [-]evenp [-]oddp [-]pass8 .fi .PP Systems using .IR termio may use the following options: .nf .PP [-]ignbrk [-]brkint [-]ignpar [-]parmrk [-]inpck [-]istrip [-]inlcr [-]igncr [-]icrnl [-]iuclc [-]ixon [-]ixany [-]ixoff [-]decctlq [-]tandem [-]imaxbel [-]opost [-]olcuc [-]onlcr [-]ocrnl [-]onocr [-]onlret [-]ofill [-]ofdel [-]cstopb [-]cread [-]parenb [-]parodd [-]hupcl [-]clocal [-]loblk [-]parity [-]evenp [-]oddp [-]stopb [-]hup [-]crtscts [-]isig [-]noisig [-]icanon [-]cbreak [-]xcase [-]echo [-]echoe [-]echok [-]crterase [-]lfkc [-]echonl [-]noflsh [-]tostop [-]echoctl [-]ctlecho [-]echoprt [-]prterase [-]echoke [-]crtkill [-]lcase [-]nl [-]litout [-]pass8 [-]raw [-]sane [-]cooked [-]nopost fill nl0 nl1 cr0 cr1 cr2 cr3 tab0 tab1 tab2 tab3 bs0 bs1 vt0 vt1 ff0 ff1 cs5 cs6 cs7 cs8 nul-fill del-fill -tabs .fi .PP And systems using .IR termios may use the following options: .nf .PP [-]ignbrk [-]brkint [-]ignpar [-]parmrk [-]inpck [-]istrip [-]inlcr [-]igncr [-]icrnl [-]iuclc [-]ixon [-]ixany [-]ixoff [-]imaxbel [-]pass8 [-]opost [-]olcuc [-]onlcr [-]ocrnl [-]onocr [-]onlret [-]ofill [-]ofdel [-]tabs nl0 nl1 cr0 cr1 cr2 cr3 tab0 tab1 tab2 tab3 bs0 bs1 vt0 vt1 ff0 ff1 cs5 cs6 cs7 cs8 [-]cstopb [-]cread [-]parenb [-]parodd [-]hupcl [-]clocal [-]crtscts [-]evenp [-]parity [-]oddp [-]pass8 [-]isig [-]icanon [-]xcase [-]echo [-]echoe [-]echok [-]echonl [-]noflsh [-]tostop [-]iexten [-]echoctl [-]ctlecho [-]echoprt [-]prterase [-]echoke [-]crtkill [-]flusho [-]pendin .fi .PP The .B fc , .B fs , .B xc , and .B xs printcap entries are obsolete, and if present with non-zero values will abort print job processing. .SH "INITIALIZATION" .LP Many printers require an initialization string to be sent to them in order to configure their operation. The leader (ld) and trailer (tr) strings are sent at the start and end of job processing. These strings are interpreted using the C language conventions for character representation: \ennn is replaced with a character with the value nnn, \en with a new line, \er with a carriage return, and so forth. .SH "ALL PRINTERS" .LP The LPRng software has the capability to use a remote database for obtaining printcap and other information. One of the difficulties arises when a list of all printers available is needed. By convention, the special printer name .B all is reserved for this information; the .B all field is a list of printers separated by spaces or punctuation. For example: .sp .nf #all printers all:all=lp1,lp2,lp3,lp4 .fi .SH ACCOUNTING .PP Accounting in the LPRng package has evolved over time to accommodate new requirements. The general approach is to use either a simple .B "log to file" method in which the accounting information is written to a log file or a more complex .B "log to program" method in which the accounting information is written to a program. The information and method and actions taken are specified by the following entries: .nf :as - start of job accounting :ae - end of job accounting :af - default job accounting :achk - used accounting for authorization. .fi .PP The value of the :as and :ae options are either a string which is used as the accounting information or a program which is executed to log or save the accounting information. If a program is executed then the value of the :af entry is ignored and the program is run to record the job accounting information. For example: .nf # string for information logging :as=jobend $H $n $P $k $b $t :ae=jobstart $H $n $P $k $b $t :as=|/usr/local/libexec/logjobstart $H $n $P $k $b $t :ae=|/usr/local/libexec/logjobend $H $n $P $k $b $t .fi .PP If the :as or :ae value is a string then the :af information is used to record the accounting information: .nf af=|/path - run program, :as or :ae written to program STDIN af=host%port - tcp/ip connection to port on host, :as or :ae written to connection af=path - treat path as a file pathname, if file exists append :as or :ae to file. .PP If the :achk flag is set then this is modified as follows. If the :as entry specifies a program or :af entry specifies a program or remote host (i.e. - logging using program) then after accounting information has been written to the program or connection a response will be read from the program STDOUT or the connection. This response is expected to be an ASCII string. If the line is blank or starts with ACCEPT then the job will be printed, HOLD will hold the job, REMOVE will remove the job, and ABORT or a non-recognizable response will cause printing to be aborted. .PP If the output is written to a program then the exit status of the program can be used as well. If the program exits with nonzero status then the exit code controls the disposition: JHOLD, JREMOVE, and JABORT will hold, remove, or abort the job respectively. If the exit status is 0, then the filter's STDOUT will be read and processed as described above. .SH "BOUNCE QUEUES AND PRINT FORMATS" .PP If the lp option value has the format .B ":lp=pr@host" or job forwarding is specified by .B ":rp=pr:rm=host" then the normal operation is simple to store and forward the print jobs. If filters are specified then the job files are first filtered and then the output of the filters is sent to the destination. For historical reasons, a spool queue that does filtering and forwarding is called a .IR "bounce queue" . The .B bounce_queue_format (default 'f') specifies the output for the filtered files. If this is not desirable the .B translate_format option can be used to specify a format. The option has the form SdSdSdN, where S is the original format and d is the final format. If none of the formats match and there is an odd number of formats then the last one is used. For example, .B pfmlf would convert formats p to f, m to l, and v to f. .PP The \&:lpd_bounce flag concatenate the output of the filters and the result will be sent as a single job file to the destination. This facility is useful when handling legacy print spooler applications that do not understand the RFC1179 copy, etc., options. The first letter of the .B bounce_queue_format (default 'f') is used as the output file format. .PP The .B lpr_bounce printcap flag can be used to cause LPR to do bounce queue filtering in exactly the same manner as the server. This should be used with caution as missing filters on the client system can cause unexpected behavior. .SH "KERBEROS, AND OTHER AUTHENTICATION METHODS" .PP LPRng supports built in kerberos authentication. To enable this, the LPD protocol has been extended to provide a way to transfer authenticated and/or encrypted jobs and commands. The details are covered in the LPRng HOWTO documentation. .PP Also, SSL can be used. See .BR lprng_certs (1) for details. .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), lpd.perms(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lprng_index_certs.n0000644000131400013140000000216011531672130014240 00000000000000.TH LPRNG_INDEX_CERTS 1 2006-12-09 "LPRng" "LPRNG_INDEX_CERTS command" .SH NAME lprng_index_certs \- lprng SSL certificate management .SH SYNOPSIS .B "lprng_index_certs [directory]" .SH DESCRIPTION .PP The .B lprng_index_certs program creates a set of index files in the LPRng signing certificate directory. See .BR lprng_certs (1) for details. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "SEE ALSO" .LP lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.conf(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lprm.n0000644000131400013140000001332311531672130011504 00000000000000.TH LPRM 1 2006-12-09 "LPRng" "lprm command" .SH NAME lprm \- remove jobs from the line printer spooling queue .SH SYNOPSIS .B lprm [ .B \-a ] [ .B \-A ] [ .BI \-D debugopt ] [ .BI \-P printer ] [ .B \-V ] [ .BI \-U user ] .ti +5n [ .IR jobid \|.\|.\|. ] [ .I all ] .SH DESCRIPTION .PP .I Lprm will send a request to the LPD server to remove jobs from a spool queue. (See .IR clean (1) for an .IR lp (1) compatible interface.) .I Lprm is normally the only method by which a user may remove a job. The jobs to be removed are specified by the job number or user name; with no specifiers the first removable in a queue will be selected for removal. Usually users may only remove jobs submitted by themselves from the host which originated the original lpr request. .PP The spool queue is searched first for jobs that the user has permissions to remove, then for jobs that match any of the specified set of tags. If no tags are specified, only the first job in the queue that the user has permissions to remove will be removed. If the .B \-a flag or the .I all spool queue is specified, .I lprm will search all available spool queues. .LP The .I all wildcard jobid is used to match all jobs in a spool queue; however unless the user has .I control permissions for the spool queue only the user's jobs will be removed. See the .BR lpd (1) man page for details about control permissions. .PP A jobid can be a job number, a user name, a job identifier, or a pattern for a .I glob based wild card match. This match is applied to the job identifier information. .PP .I Lprm will announce the names of any files it removes and is silent if there are no jobs in the queue which match the request list. If the job being removed is active, the LPD server will stop printing the job and then restart printing operations. .SH EXAMPLES .TP Remove the last job I submitted if it is in the queue: .sp lprm .TP Remove job 25 in spool queue p1: .sp lprm -Pp1 25 .TP Remove job 25 and 30 in spool queue p1: .sp lprm -Pp1 25 30 .TP Remove all of user john's jobs in spool queue p1: .sp lprm -Pp1 john .TP Remove all jobs in spool queue p1: .sp lprm -Pp1 all .TP Remove all jobs in all spool queues: .sp lprm -a all .TP Remove the jobs with identifier nobody@system in spool queue p1. Note that the quotes around the pattern are needed to suppress shell glob expansion. .sp lprm -Pp1 'nobody@system*' .SH OPTIONS .IP "\fB\-A\fR" 5 Use authentication specified by the value of the AUTH environment variable. .IP "\fB\-a\fR" 5 Remove files from all spool queues available to the user. .IP "\fB\-P\fIprinter\fR" 5 Specifies printer queue. By default, the destination printer is taken from the command line .I dest value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .IP "\fB\-U\fIuser\fR" 5 Explicitly provide a userid for doing the removal to the LPD server. This can be done only by ROOT or userids listed in the .I allow_user_setting configuration or printcap option. This facility is provided to allow printing front end systems such as SAMBA to submit job removal requests on behalf of users. .IP "\fB\-D\fIdebugopts\fR" 5 Debugging is controlled using the .B \-D option. This accepts a comma-separated list of debugging settings. These settings take one of two forms: .B facility=value , or .B value to set an overall default value. .IP "\fB\-V\fR" 5 The \-V option prints the version information for the program and verbose information about activities. .SH WARNINGS .PP Users with CONTROL (i.e.- administrative) permissions on spool queues can remove any or all jobs. The .I all wildcard defaults to all user jobs, not just those submitted by the user. This allows administrators to purge a spool queue easily. .SH ENVIRONMENT .PP By default, the destination printer is taken from the command line .I dest value, then the environment variables PRINTER, LPDEST, NPRINTER, NGPRINTER, then first entry in the printcap information, and and finally the default_printer entry from the configuration file, and then the compile time default. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.conf(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH DIAGNOSTICS Most of the diagnostics are self explanatory. If you are puzzled over the exact cause of failure, set the debugging level on (-D5) and run again. The debugging information will help you to pinpoint the exact cause of failure. .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lpd.perms.n0000644000131400013140000003262211531672130012441 00000000000000.TH LPD.PERMS 5 2006-12-09 "LPRng" "lpd.perms file" .SH NAME lpd.perms \- permissions control file for the LPRng line printer spooler system .SH DESCRIPTION The file \fBlpd.perms\fR is used to provide permission information for the LPRng Printer spooler system. Blank lines and all characters after a hash sign (``#'') to the end of line are ignored. If a hash sign is desired in the permission information, it should be escaped with a backslash (``\\''). All other lines specify permissions entry and should be of the following form: .RS ACCEPT [[not] key = value[,value]* ]* .br REJECT [[not] key = value[,value]* ]* .br DEFAULT ACCEPT .br DEFAULT REJECT .RE .PP Each LPD service request is checked against the entries in the permissions database or file. The following is a typical permissions file: .RS .nf .ft CW # Set default permissions DEFAULT ACCEPT # Reject any connections from outside our subnet REJECT SERVICE=X NOT REMOTEIP=130.191.0.0/255.255.0.0 # Only accept spooling (LPR) from # Engineering Lab or the Dean's office REJECT SERVICE=R NOT REMOTEHOST=*.eng.sdsu.edu,dean.sdsu.edu # Do not accept forwarded jobs for printing REJECT SERVICE=R FORWARD # Allow only the administrators control access ACCEPT SERVICE=C,M REMOTEHOST=spooler.eng.sdsu.edu REMOTEUSER=root,papowell ACCEPT SERVICE=C,M SERVER REMOTEUSER=root,papowell # Allow only the user on the same host who spooled job to remove it ACCEPT SERVICE=M SAMEUSER SAMEHOST # Allow users to check status ACCEPT SERVICE=C LPC=status # Require connection for other operations over UNIX socket # not TCP/IP port. Effectively requiring them to be made from the # localhost ACCEPT SERVICE=C UNIXSOCKET REJECT SERVICE=C # Variation - accept all spooled jobs, but then apply # permissions checking when job is printed. Allows # prevents remote spoolers from locking up trying resend # same request ACCEPT SERVICE=R REJECT SERVICE=P NOT REMOTEHOST=*.eng.sdsu.edu,dean.sdsu.edu .RE .fi .sp .LP Permission checking is done by using a set of keys (or fields) with associated values to check for permission. The SERVICE key has value P for printing (i.e.- unspooling), R for spooling (i.e.- LPR request), P for printing (i.e., after job has been spooled), C printer control (i.e. - LPC), M for removal (i.e.- LPRM request), and Q for queue information (i.e.- LPQ request). The .B X key is used when checking for connection information. .LP Initially, all of the keys have undefined or NULL values, and are assigned values during the permissions checking process. When a connection is made to the server, it assigns The REMOTEHOST (alias REMOTEIP) key the list of IP addresses and hostnames determined by doing a reverse Domain Name Service (DNS) lookup on the remote host's IP address. If the reverse DNS fails, then only the IP address will be used. The REMOTEPORT (PORT is an alias for REMOTEPORT) is assigned the port number of the connection origination. The UNIXSOCKET key will match (be true) if the connection is over a UNIX socket. By convention, this is from the localhost. Finally, the SERVICE value is assigned X, and the lpd server will check the database to see if the connection is accepted or rejected. .LP The server will then read the request information from the connection. If the request is for an authenticated data transfer, the server will invoke the appropriate authentication mechanism which will assign AUTH a true (or matching) value, AUTHTYPE the type of authentication, AUTHUSER the authenticated user id value, which may differ from the actual user name, and AUTHFROM the authenticated identification of the originator of the request, which may be a server if the request is forwarded. .LP Next, the SERVICE value is set to R, C, M, or Q depending on whether it is an LPR, LPC, LPRM, or LPQ request, and the LPC value set to the requested LPC command if it was an LPC request. If the request contained a user name, then REMOTEUSER is set to this name. If the request contained a printer name, then PRINTER is set to the printer name. If the request is a print request, then the HOST value is set to the list of host names and IP addresses given by a DNS lookup of the value in the H field of the job. The database is scanned again to determine if the operation can be performed on the requested queue. To simplify the rule writing, if the operation requires modification or checking of individual jobs, such as the LPC, LPQ, or LPRM commands, then the various checks that depend on jobs will succeed in this step. .LP Finally, if the operation requires modification or checking of individual jobs, such as the LPC, LPQ, or LPRM commands, then the specified print queue is scanned, and for each job in the print queue, the HOST and USER values are set to the host and user values in the control file for the job. .LP The database is checked as follows. Each line of the permissions file is scanned for key names and values, and these are matched against the request keys information. When all matches on a line are made, then search terminates with the specified action (ACCEPT/REJECT). If no match is found the default permission value is used. The DEFAULT key is used to specify the current default permission to be used for successful matches or if there is no match after scanning the entire permissions database. .LP The following keys provide some additional checking capabilities. The REMOTEGROUP entry checks that the REMOTEUSER value appears in a group or netgroup entry in the system database, and the GROUP entry for the USER value. For example, GROUP=student*,staff* would check to see if any of the group names matching student* or staff* have the specified user name in them. If a system has the .I netgroups capability, a printer, group, or remotegroup name starting with a \f(CW@\fP will be treated as a netgroup name, and specified user name or printer will be checked to see if it is in the group. .LP The SERVER entry will be true (match) if the request originated from the print server. The SAMEHOST is true (matches) if the REMOTEHOST and HOST values have a common entry, i.e. - are the same host. The SAMEUSER is true (matches) if the REMOTEUSER and USER values are identical. The AUTHSAMEUSER is true (matches) if the AUTHUSER value that originated the request and the AUTHUSER which was used to transfer a job are identical. AUTHJOB is true (matches) if the job was transferred using authentication. The FORWARD value is an alias for NOT SAMEHOST. .LP The CONTROLLINE value can be used to determine if there is a matching line in the control file. This facility has been used to ensure that jobs contain various information fields in order to be printed. .LP .sp .nf .ne 20v .ta \w'Key__________'u +\w'Match_'u +\w'Connect_'u +\w'Job___'u +\w'Job____'u +\w'LPQ__'u +\w'LPRM__'u +\w'LPC'u Key Match Connect Job Job LPQ LPRM LPC \0 \0 \0 Spool Print SERVICE S 'X' 'R' 'P' 'Q' 'M' 'C,S' USER S - JUSR JUSR JUSR JUSR JUSR HOST S RH JH JH JH JH JH GROUP S - JUSR JUSR JUSR JUSR JUSR REMOTEPORT N PORT PORT - PORT PORT PORT REMOTEUSER S - JUSR JUSR JUSR CUSR CUSR REMOTEHOST S RH RH JH RH RH RH UNIXSOCKET V SK SK SK SK SK SK REMOTEGROUP S - JUSR JUSR JUSR CUSR CUSR CONTROLLINE S - CL CL CL CL CL PRINTER S - PR PR PR PR PR FORWARD V - SA - - SA SA SAMEHOST V - SA - SA SA SA SAMEUSER V - - - SU SU SU SERVER V - SV - SV SV SV AUTH V - AU - AU AU AU AUTHTYPE S - AU - AU AU AU AUTHUSER S - AU - AU AU AU AUTHSAMEUSER S - AU - AU AU AU AUTHFROM S - AU - AU AU AU AUTHJOB V - AU - AU AU AU PORT is alias for REMOTEPORT REMOTEIP is alias for REMOTEHOST IP is alias for HOST .ta 3m +\w'RH = REMOTEHOST 'u KEY: JH = HOST host in control file RH = REMOTEHOST connecting host name/IP JUSR = USER user in control file CUSR = REMOTEUSER user from control request JIP= IP host/IP addr of host in control file RIP= REMOTEIP host/IP addr of requesting host PORT= connecting host origination port SK= match if connection over a UNIX socket CONTROLLINE= pattern match of control line in control file FW= IP of source of request == IP of host in control file SA= IP of source of request == IP of host in control file SU= user from request == user in control file SA= IP of source of request == IP of server host SV= matches if from same address as server AU= value determined by server authentication operation AUTH is true if authenticated transfer, TYPE is set to the type of authentication (kerberos, etc) AUTHUSER is user authentication id AUTHFROM is sender authentication id (can be remote server) AUTHSAMEUSER matches if remote user authentication id matches original user authentication id AUTHJOB it true if print job has authentication Match: S = string with wild card, IP = IP address[/netmask], N = low[-high] number range, V = exact value match SERVICE: 'X' - Connection request; 'R' - lpr request from remote host; 'P' - print job in queue; 'Q' - lpq request, 'M' - lprm request; 'C' - lpc spool control request; 'S' - lpc spool status request 'U' - administratively allowed user operation NOTE: when printing (P action), the remote and job check values (i.e. - RUSR, JUSR) are identical. .fi .sp .PP The special key .I letter=patterns searches the control file line starting with the (upper case) letter, and is usually used with printing and spooling checks. For example, C=A*,B* would check that the class information (i.e.- line in the control file starting with C) had a value starting with A or B. .PP A permission line consists of a list of tests and a result value. If all of the tests succeed, then a match has been found and the permission testing completes with the result value. You use the DEFAULT reserved word to set the default ACCEPT/DENY result. The NOT keyword will reverse the sense of a test. .PP Each test can have one or more optional values separated by commas. For example USER=john,paul,mark has 3 test values. The Match value specifies how the matching is done. .sp .nf S = string type match - string match with glob. .ta 4n +4n +4n +4n +4n +4n .nf Format: string with wildcards (*) * matches 0 or more chars Character comparison is case insensitive. For example - USER=th*s matches uTHS, This, This, Theses .sp IP = IP address and submask. IP address must be in dotted form. Format: x.x.x.x[/y.y.y.y or /z] x.x.x.x is IP address y.y.y.y is optional submask, default is 255.255.255.255 z is a netmask with most significant z bits set. Match is done by IP address to a 32 bit value and using: success = ((x ^ IP ) & y) == 0 (C language notation) i.e.- only bits where mask is non-zero are used in comparison. For example - IP=130.191.0.0/255.255.0.0 matches all address 130.191.X.X IP=130.191.0.0/16 has the same value. .sp N = numerical range - low-high integer range. Format: low[-high] Example: PORT=0-1023 matches a port in range 0 - 1023 (privileged) .fi .PP The authentication entries AUTH, AUTHTYPE, AUTHUSER, AUTHSAMEUSER and AUTHFROM can be used to check permissions for authenticated operations. AUTH is set (true) if authentication was done. We can use this to reject non-authenticated transfers: .br REJECT NOT AUTH .br The AUTHTYPE will match the authentication type being used or requested by the remote client or server. The AUTHUSER matches the original client authentication information used by the client to make a request to the server, and the AUTHFROM matches the sender authentication information. The AUTHSAMEUSER will match if the remote client or user authentication id is the same as that used for the job generation. .SH "LPC=OP" .PP The LPC=op entry is useful to allow various users to perform administration operations. The following permissions entry would allows users to hold or release their own jobs: .br ACCEPT SERVICE=C SAMEUSER SAMEHOST LPC=release .SH "DNS, IPV6, AND MULTIHOMED HOSTS" .PP There is a subtle problem with names and IP addresses which are obtained for 'multi-homed hosts', i.e. - those with multiple Ethernet interfaces, and for IPV6 (IP Version 6), in which a host can have multiple addresses, and for the normal host which can have both a short name and a fully qualified domain name. .PP When performing an IP address match, the entire list of IP addresses for a system will now be checked. If one of these matches, then success is reported. Similarly, the entire list of host names and aliases will be checked. If one of these matches, then success will be reported. .br .SH FILES .PP The files used by LPRng are set by values in the printer configuration file. The following are a commonly used set of default values. .nf .ta \w'/var/spool/lpd/printcap. 'u _LPD_CONF_PATH_ LPRng configuration file ${HOME}/.printcap user printer description file _PRINTCAP_PATH_ printer description file _LPD_PERMS_PATH_ permissions _LOCKFILE_ lock file for queue control /var/spool/lpd spool directories /var/spool/lpd/QUEUE/control queue control /var/spool/lpd/QUEUE/log trace or debug log file /var/spool/lpd/QUEUE/acct accounting file /var/spool/lpd/QUEUE/status status file .fi .SH "SEE ALSO" lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/man/lpbanner.n0000644000131400013140000000415011531672130012331 00000000000000.TH LPBANNER 1 2006-12-09 "LPRng" "lpbanner filter" .SH NAME lpbanner, pclbanner, psbanner \- printer banners in text, PCL and PostScript .SH SYNOPSIS .B lpbanner [ .BI "\-l " length ] [ .BI "\-w " width ] [ .BI "\-P " printer ] [ .BI "\-L " bannername ] [ .BI "\-n " loginname ] [ .BI "\-h " host ] [ .BI "\-J " jobtitle ] [ .BI "\-C " class ] [ .BI "\-? " option .BI args ] [ all ] .SH DESCRIPTION The .B lpbanner program is used to print a simple banner on a fixed size font printer, the .B pclbanner program generates a PCL banner and the .B psbanner program generates a PostScript banner. All information to be printed is passed using command line arguments. In order to be compatible with vintage line printer spoolers, reads a line form standard input, but ignores the information. .SH OPTIONS .TP .BI \-w " width" Page width in characters (default 132). .TP .BI \-l " length" Page length in lines (default 60). .TP .BI \-P " printer" printer queue for banner information. .TP .BI \-L " bannername" Name used on banner as main name. .TP .BI \-n " loginname" Name used on banner as login name. .TP .BI \-h " host" Name used on banner as host name. .TP .BI \-J " jobtitle" String used on banner as main title. .TP .BI \-C " class" String used on banner as class. .TP .BI \-? " value" All other options and arguments provided by LPRng are ignored. .SH "EXIT STATUS" .PP The following exit values are returned: .TP 15 .B "zero (0)" Successful completion. .TP .B "non-zero (!=0)" An error occurred. .SH "SEE ALSO" .LP lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), lpd.conf(5), pr(1), lprng_certs(1), lprng_index_certs(1). .SH "AUTHOR" Patrick Powell . .SH "HISTORY" LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting .B https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to .B lprng-request@lists.sourceforge.net with the word .I subscribe in the body. .br The software is available via .B http://lprng.sourceforge.net lprng-3.8.B/install-sh0000755000131400013140000003246411531672272011622 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2006-12-25.00 # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-end: "$" # End: