diff --git a/.gitignore b/.gitignore index 1817e0203..6dc8ad04d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ /config.log /config.status /configure~ -/cups.pc +/cups3.pc /Makedefs /cups/fuzzipp /cups/libcups.dylib @@ -22,6 +22,7 @@ /cups/testcreds /cups/testcups /cups/testdest +/cups/testdnssd /cups/testfile /cups/testgetdests /cups/testhttp diff --git a/CHANGES.md b/CHANGES.md index 48ba415df..b2a600a8f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,11 +11,15 @@ libcups v3.0b1 (Month DD, YYYY) - Now require ZLIB. - Now require POSIX or Windows threading support. - Now require the `poll` function (`WSAPoll` on Windows). +- Now install with a prefix by default to allow coexistance with CUPS 2.x + (Issue #21) - Added new `GENERATE-FILE` directive for `ipptool` test files. - Added new `ATTR-IF-DEFINED` and `ATTR-IF-NOT-DEFINED` directives to IPP data files (Issue #3) - Added `ippFile` API for working with IPP data files as used by `ipptool`, `ippexeprinter`, and other tools (Issue #14) +- Added a roll to the default color ippeveprinter printer. +- Added new DNS-SD API (Issue #19) - Updated the CUPS API for consistency. - Removed all obsolete/deprecated CUPS 2.x APIs. - Removed (obsolete) Kerberos support. diff --git a/Makedefs.in b/Makedefs.in index 3c78bb098..4b4901107 100644 --- a/Makedefs.in +++ b/Makedefs.in @@ -61,8 +61,10 @@ LOCALTARGET = @LOCALTARGET@ # Libraries... # +CUPS_PC = @CUPS_PC@ LIBCUPS = @LIBCUPS@ LIBCUPS_STATIC = @LIBCUPS_STATIC@ +LINKCUPS = -L../cups @LINKCUPS@ # diff --git a/Makefile b/Makefile index 71f8a0e75..d33bed16f 100644 --- a/Makefile +++ b/Makefile @@ -76,9 +76,12 @@ install: echo Installing all in $$dir... ;\ (cd $$dir; $(MAKE) $(MFLAGS) install) || exit 1;\ done - echo Installing cups.pc file... + echo Installing $(CUPS_PC) file... $(INSTALL_DIR) $(BUILDROOT)$(libdir)/pkgconfig - $(INSTALL_DATA) cups.pc $(BUILDROOT)$(libdir)/pkgconfig/cups.pc + $(INSTALL_DATA) cups3.pc $(BUILDROOT)$(libdir)/pkgconfig/cups3.pc + if test "$(CUPS_PC)" = cups.pc; then \ + $(LN) cups3.pc $(BUILDROOT)$(libdir)/pkgconfig/cups.pc; \ + fi # @@ -90,7 +93,10 @@ uninstall: echo Uninstalling in $$dir... ;\ (cd $$dir; $(MAKE) $(MFLAGS) uninstall) || exit 1;\ done - $(RM) $(BUILDROOT)$(libdir)/pkgconfig/cups.pc + $(RM) $(BUILDROOT)$(libdir)/pkgconfig/cups3.pc + if test "$(CUPS_PC)" = cups.pc; then \ + $(RM) $(BUILDROOT)$(libdir)/pkgconfig/cups.pc; \ + fi -$(RMDIR) $(BUILDROOT)$(libdir)/pkgconfig diff --git a/config.guess b/config.guess index 9afd67620..1817bdce9 100755 --- a/config.guess +++ b/config.guess @@ -1,12 +1,14 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2022 Free Software Foundation, Inc. -timestamp='2013-11-29' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-05-25' # This file 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 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -15,7 +17,7 @@ timestamp='2013-11-29' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -24,12 +26,20 @@ timestamp='2013-11-29' # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # -# Originally written by Per Bothner. +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess # -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . + + +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. me=`echo "$0" | sed -e 's,.*/,,'` @@ -39,7 +49,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -84,7 +94,8 @@ if test $# != 0; then exit 1 fi -trap 'exit 1' 1 2 15 +# Just in case it came from the environment. +GUESS= # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires @@ -96,66 +107,90 @@ trap 'exit 1' 1 2 15 # Portable tmp directory creation inspired by the Autoconf team. -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' +tmp= +# shellcheck disable=SC2172 +trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15 + +set_cc_for_build() { + # prevent multiple calls if $tmp is already set + test "$tmp" && return 0 + : "${TMPDIR=/tmp}" + # shellcheck disable=SC2039,SC3028 + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } + dummy=$tmp/dummy + case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in + ,,) echo "int x;" > "$dummy.c" + for driver in cc gcc c89 c99 ; do + if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD=$driver + break + fi + done + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; + esac +} # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then +if test -f /.attbin/uname ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case $UNAME_SYSTEM in Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu + LIBC=unknown - eval $set_cc_for_build - cat <<-EOF > $dummy.c + set_cc_for_build + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc - #else + #elif defined(__GLIBC__) LIBC=gnu + #else + #include + /* First heuristic to detect musl libc. */ + #ifdef __DEFINED_va_list + LIBC=musl + #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "$cc_set_libc" + + # Second heuristic to detect musl libc. + if [ "$LIBC" = unknown ] && + command -v ldd >/dev/null && + ldd --version 2>&1 | grep -q ^musl; then + LIBC=musl + fi + + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + if [ "$LIBC" = unknown ]; then + LIBC=gnu + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -167,22 +202,32 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \ + echo unknown)` + case $UNAME_MACHINE_ARCH in + aarch64eb) machine=aarch64_be-unknown ;; armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; + *) machine=$UNAME_MACHINE_ARCH-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in + # to ELF recently (or will in the future) and ABI. + case $UNAME_MACHINE_ARCH in + earm*) + os=netbsdelf + ;; arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -197,45 +242,80 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in os=netbsd ;; esac + # Determine ABI tags. + case $UNAME_MACHINE_ARCH in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case $UNAME_VERSION in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; + GUESS=$machine-${os}${release}${abi-} + ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE + ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE + ;; + *:SecBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE + ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE + ;; + *:MidnightBSD:*:*) + GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE + ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE + ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE + ;; + *:OS108:*:*) + GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE + ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE + ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE + ;; + *:Sortix:*:*) + GUESS=$UNAME_MACHINE-unknown-sortix + ;; + *:Twizzler:*:*) + GUESS=$UNAME_MACHINE-unknown-twizzler + ;; + *:Redox:*:*) + GUESS=$UNAME_MACHINE-unknown-redox + ;; + mips:OSF1:*.*) + GUESS=mips-dec-osf1 + ;; alpha:OSF1:*:*) + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + trap '' 0 case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` @@ -249,163 +329,158 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in + case $ALPHA_CPU_TYPE in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; + OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + GUESS=$UNAME_MACHINE-dec-osf$OSF_REL + ;; Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; + GUESS=m68k-unknown-sysv4 + ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; + GUESS=$UNAME_MACHINE-unknown-amigaos + ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; + GUESS=$UNAME_MACHINE-unknown-morphos + ;; *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; + GUESS=i370-ibm-openedition + ;; *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; + GUESS=s390-ibm-zvmoe + ;; *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; + GUESS=powerpc-ibm-os400 + ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; + GUESS=arm-acorn-riscix$UNAME_RELEASE + ;; arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; + GUESS=arm-unknown-riscos + ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; + GUESS=hppa1.1-hitachi-hiuxmpp + ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; + case `(/bin/universe) 2>/dev/null` in + att) GUESS=pyramid-pyramid-sysv3 ;; + *) GUESS=pyramid-pyramid-bsd ;; + esac + ;; NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; + GUESS=pyramid-pyramid-svr4 + ;; DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; + GUESS=sparc-icl-nx6 + ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; + sparc) GUESS=sparc-icl-nx7 ;; + esac + ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL + ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-hal-solaris2$SUN_REL + ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris2$SUN_REL + ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-auroraux$UNAME_RELEASE + ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + set_cc_for_build + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if test "$CC_FOR_BUILD" != no_compiler_found; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=$SUN_ARCH-pc-solaris2$SUN_REL + ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=sparc-sun-solaris3$SUN_REL + ;; sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in + case `/usr/bin/arch -k` in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` + GUESS=sparc-sun-sunos$SUN_REL + ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; + GUESS=m68k-sun-sunos$UNAME_RELEASE + ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case `/bin/arch` in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + GUESS=m68k-sun-sunos$UNAME_RELEASE ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + GUESS=sparc-sun-sunos$UNAME_RELEASE ;; esac - exit ;; + ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; + GUESS=sparc-auspex-sunos$UNAME_RELEASE + ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor @@ -415,44 +490,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-atari-mint$UNAME_RELEASE + ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-milan-mint$UNAME_RELEASE + ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-hades-mint$UNAME_RELEASE + ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-mint$UNAME_RELEASE + ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-machten$UNAME_RELEASE + ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-machten$UNAME_RELEASE + ;; RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; + GUESS=mips-dec-mach_bsd4.3 + ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=mips-dec-ultrix$UNAME_RELEASE + ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; + GUESS=vax-dec-ultrix$UNAME_RELEASE + ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; + GUESS=clipper-intergraph-clix$UNAME_RELEASE + ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -461,95 +536,96 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; + GUESS=mips-mips-riscos$UNAME_RELEASE + ;; Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; + GUESS=powerpc-motorola-powermax + ;; Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; + GUESS=powerpc-harris-powermax + ;; Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; + GUESS=powerpc-harris-powerunix + ;; m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; + GUESS=m88k-harris-cxux7 + ;; m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; + GUESS=m88k-motorola-sysv4 + ;; m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ + test "$TARGET_BINARY_INTERFACE"x = x then - echo m88k-dg-dgux${UNAME_RELEASE} + GUESS=m88k-dg-dgux$UNAME_RELEASE else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + GUESS=m88k-dg-dguxbcs$UNAME_RELEASE fi else - echo i586-dg-dgux${UNAME_RELEASE} + GUESS=i586-dg-dgux$UNAME_RELEASE fi - exit ;; + ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; + GUESS=m88k-dolphin-sysv3 + ;; M88*:*:R3*:*) # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; + GUESS=m88k-motorola-sysv3 + ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; + GUESS=m88k-tektronix-sysv3 + ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; + GUESS=m68k-tektronix-bsd + ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; + IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'` + GUESS=mips-sgi-irix$IRIX_REL + ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + GUESS=romp-ibm-aix # uname -m gives an 8 hex-code CPU id + ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; + GUESS=i386-ibm-aix + ;; ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then + if test -x /usr/bin/oslevel ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; + GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV + ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -560,76 +636,77 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then - echo "$SYSTEM_NAME" + GUESS=$SYSTEM_NAME else - echo rs6000-ibm-aix3.2.5 + GUESS=rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 + GUESS=rs6000-ibm-aix3.2.4 else - echo rs6000-ibm-aix3.2 + GUESS=rs6000-ibm-aix3.2 fi - exit ;; + ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` + if test -x /usr/bin/lslpp ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \ + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV=$UNAME_VERSION.$UNAME_RELEASE fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; + GUESS=$IBM_ARCH-ibm-aix$IBM_REV + ;; *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; + GUESS=rs6000-ibm-aix + ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + GUESS=romp-ibm-bsd4.4 + ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 + GUESS=romp-ibm-bsd$UNAME_RELEASE # 4.3 with uname added to + ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; + GUESS=rs6000-bull-bosx + ;; DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; + GUESS=m68k-bull-sysv3 + ;; 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; + GUESS=m68k-hp-bsd + ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; + GUESS=m68k-hp-bsd4.4 + ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + case $UNAME_MACHINE in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then + if test -x /usr/bin/getconf; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + case $sc_cpu_version in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + case $sc_kernel_bits in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if test "$HP_ARCH" = ""; then + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -662,13 +739,13 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if test "$HP_ARCH" = hppa2.0w then - eval $set_cc_for_build + set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -679,23 +756,23 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; + GUESS=$HP_ARCH-hp-hpux$HPUX_REV + ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; + HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'` + GUESS=ia64-hp-hpux$HPUX_REV + ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -720,38 +797,38 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; + GUESS=unknown-hitachi-hiuxwe2 + ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + GUESS=hppa1.1-hp-bsd + ;; 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; + GUESS=hppa1.0-hp-bsd + ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; + GUESS=hppa1.0-hp-mpeix + ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + GUESS=hppa1.1-hp-osf + ;; hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; + GUESS=hppa1.0-hp-osf + ;; i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + if test -x /usr/sbin/sysversion ; then + GUESS=$UNAME_MACHINE-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + GUESS=$UNAME_MACHINE-unknown-osf1 fi - exit ;; + ;; parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; + GUESS=hppa1.1-hp-lites + ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; + GUESS=c1-convex-bsd + ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd @@ -759,139 +836,148 @@ EOF fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; + GUESS=c34-convex-bsd + ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; + GUESS=c38-convex-bsd + ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; + GUESS=c4-convex-bsd + ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=ymp-cray-unicos$CRAY_REL + ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=t90-cray-unicos$CRAY_REL + ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=alphaev5-cray-unicosmk$CRAY_REL + ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=sv1-cray-unicos$CRAY_REL + ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; + CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'` + GUESS=craynv-cray-unicosmp$CRAY_REL + ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL} + ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE + ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-bsdi$UNAME_RELEASE + ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE + ;; + arm:FreeBSD:*:*) + UNAME_PROCESSOR=`uname -p` + set_cc_for_build + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi + else + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf + fi + ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case $UNAME_PROCESSOR in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac - exit ;; + FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL + ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; + GUESS=$UNAME_MACHINE-pc-cygwin + ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw64 + ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-mingw32 + ;; + *:MSYS*:*) + GUESS=$UNAME_MACHINE-pc-msys + ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; + GUESS=$UNAME_MACHINE-pc-pw32 + ;; + *:SerenityOS:*:*) + GUESS=$UNAME_MACHINE-pc-serenity + ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case $UNAME_MACHINE in x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; + GUESS=i586-pc-interix$UNAME_RELEASE + ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=x86_64-unknown-interix$UNAME_RELEASE + ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} - exit ;; + GUESS=ia64-unknown-interix$UNAME_RELEASE + ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; + GUESS=$UNAME_MACHINE-pc-uwin + ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; + GUESS=x86_64-pc-cygwin + ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; + SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'` + GUESS=powerpcle-unknown-solaris2$SUN_REL + ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; + GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'` + GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL + ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; + GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"` + GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC + ;; + *:Minix:*:*) + GUESS=$UNAME_MACHINE-unknown-minix + ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; @@ -901,172 +987,237 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; arm*:Linux:*:*) - eval $set_cc_for_build + set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf fi fi - exit ;; + ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-axis-linux-$LIBC + ;; + e2k:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-pc-linux-$LIBC + ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + k1om:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + set_cc_for_build + IS_GLIBC=0 + test x"${LIBC}" = xgnu && IS_GLIBC=1 + sed 's/^ //' << EOF > "$dummy.c" #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el + #undef mips + #undef mipsel + #undef mips64 + #undef mips64el + #if ${IS_GLIBC} && defined(_ABI64) + LIBCABI=gnuabi64 + #else + #if ${IS_GLIBC} && defined(_ABIN32) + LIBCABI=gnuabin32 + #else + LIBCABI=${LIBC} + #endif + #endif + + #if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa64r6 + #else + #if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6 + CPU=mipsisa32r6 + #else + #if defined(__mips64) + CPU=mips64 + #else + CPU=mips + #endif + #endif + #endif + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el + MIPS_ENDIAN=el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} + MIPS_ENDIAN= #else - CPU= + MIPS_ENDIAN= #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'` + eval "$cc_set_vars" + test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } + ;; + mips64el:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + openrisc*:Linux:*:*) + GUESS=or1k-unknown-linux-$LIBC + ;; + or32:Linux:*:* | or1k*:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} - exit ;; + GUESS=sparc-unknown-linux-$LIBC + ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} - exit ;; + GUESS=hppa64-unknown-linux-$LIBC + ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;; + PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;; + *) GUESS=hppa-unknown-linux-$LIBC ;; esac - exit ;; + ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64-unknown-linux-$LIBC + ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc-unknown-linux-$LIBC + ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} - exit ;; + GUESS=powerpc64le-unknown-linux-$LIBC + ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} - exit ;; + GUESS=powerpcle-unknown-linux-$LIBC + ;; + riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-ibm-linux-$LIBC + ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-dec-linux-$LIBC + ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac + fi + GUESS=$CPU-pc-linux-$LIBCABI + ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; + GUESS=i386-sequent-sysv4 + ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION + ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; + GUESS=$UNAME_MACHINE-pc-os2-emx + ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; + GUESS=$UNAME_MACHINE-unknown-stop + ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; + GUESS=$UNAME_MACHINE-unknown-atheos + ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; + GUESS=$UNAME_MACHINE-pc-syllable + ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=i386-unknown-lynxos$UNAME_RELEASE + ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + GUESS=$UNAME_MACHINE-pc-msdosdjgpp + ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL fi - exit ;; + ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in @@ -1074,12 +1225,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; + GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1089,43 +1240,43 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL else - echo ${UNAME_MACHINE}-pc-sysv32 + GUESS=$UNAME_MACHINE-pc-sysv32 fi - exit ;; + ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; + GUESS=i586-pc-msdosdjgpp + ;; Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; + GUESS=i386-pc-mach3 + ;; paragon:*:*:*) - echo i860-intel-osf1 - exit ;; + GUESS=i860-intel-osf1 + ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + GUESS=i860-stardent-sysv$UNAME_RELEASE # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + GUESS=i860-unknown-sysv$UNAME_RELEASE # Unknown i860-SVR4 fi - exit ;; + ;; mini*:CTIX:SYS*5:*) # "miniframe" - echo m68010-convergent-sysv - exit ;; + GUESS=m68010-convergent-sysv + ;; mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; + GUESS=m68k-convergent-sysv + ;; M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; + GUESS=m68k-diab-dnix + ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) @@ -1133,9 +1284,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1144,238 +1295,287 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=m68k-unknown-lynxos$UNAME_RELEASE + ;; mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; + GUESS=m68k-atari-sysv4 + ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=sparc-unknown-lynxos$UNAME_RELEASE + ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=rs6000-unknown-lynxos$UNAME_RELEASE + ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; + GUESS=powerpc-unknown-lynxos$UNAME_RELEASE + ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; + GUESS=mips-dde-sysv$UNAME_RELEASE + ;; RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; + GUESS=mips-sni-sysv4 + ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + GUESS=$UNAME_MACHINE-sni-sysv4 else - echo ns32k-sni-sysv + GUESS=ns32k-sni-sysv fi - exit ;; + ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says - echo i586-unisys-sysv4 - exit ;; + GUESS=i586-unisys-sysv4 + ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; + GUESS=hppa1.1-stratus-sysv4 + ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; + GUESS=i860-stratus-sysv4 + ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; + GUESS=$UNAME_MACHINE-stratus-vos + ;; *:VOS:*:*) # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; + GUESS=hppa1.1-stratus-vos + ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; + GUESS=m68k-apple-aux$UNAME_RELEASE + ;; news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; + GUESS=mips-sony-newsos6 + ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + if test -d /usr/nec; then + GUESS=mips-nec-sysv$UNAME_RELEASE else - echo mips-unknown-sysv${UNAME_RELEASE} + GUESS=mips-unknown-sysv$UNAME_RELEASE fi - exit ;; + ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; + GUESS=powerpc-be-beos + ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; + GUESS=powerpc-apple-beos + ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; + GUESS=i586-pc-beos + ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-unknown-haiku - exit ;; + GUESS=i586-pc-haiku + ;; + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku + ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx4-nec-superux$UNAME_RELEASE + ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx5-nec-superux$UNAME_RELEASE + ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx6-nec-superux$UNAME_RELEASE + ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx7-nec-superux$UNAME_RELEASE + ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8-nec-superux$UNAME_RELEASE + ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; + GUESS=sx8r-nec-superux$UNAME_RELEASE + ;; + SX-ACE:SUPER-UX:*:*) + GUESS=sxace-nec-superux$UNAME_RELEASE + ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=powerpc-apple-rhapsody$UNAME_RELEASE + ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE + ;; + arm64:Darwin:*:*) + GUESS=aarch64-apple-darwin$UNAME_RELEASE + ;; *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc + UNAME_PROCESSOR=`uname -p` + case $UNAME_PROCESSOR in + unknown) UNAME_PROCESSOR=powerpc ;; + esac + if command -v xcode-select > /dev/null 2> /dev/null && \ + ! xcode-select --print-path > /dev/null 2> /dev/null ; then + # Avoid executing cc if there is no toolchain installed as + # cc will be a stub that puts up a graphical alert + # prompting the user to install developer tools. + CC_FOR_BUILD=no_compiler_found + else + set_cc_for_build fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi + if test "$CC_FOR_BUILD" != no_compiler_found; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc fi elif test "$UNAME_PROCESSOR" = i386 ; then - # Avoid executing cc on OS X 10.9, as it ships with a stub - # that puts up a graphical alert prompting to install - # developer tools. Any system running Mac OS X 10.7 or - # later (Darwin 11 and later) is required to have a 64-bit - # processor. This is not true of the ARM version of Darwin - # that Apple uses in portable devices. - UNAME_PROCESSOR=x86_64 + # uname -m returns i386 or x86_64 + UNAME_PROCESSOR=$UNAME_MACHINE fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE + ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE + ;; *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=i386-pc-qnx + ;; + NEO-*:NONSTOP_KERNEL:*:*) + GUESS=neo-tandem-nsk$UNAME_RELEASE + ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; + GUESS=nse-tandem-nsk$UNAME_RELEASE + ;; + NSR-*:NONSTOP_KERNEL:*:*) + GUESS=nsr-tandem-nsk$UNAME_RELEASE + ;; + NSV-*:NONSTOP_KERNEL:*:*) + GUESS=nsv-tandem-nsk$UNAME_RELEASE + ;; + NSX-*:NONSTOP_KERNEL:*:*) + GUESS=nsx-tandem-nsk$UNAME_RELEASE + ;; *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; + GUESS=mips-compaq-nonstopux + ;; BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; + GUESS=bs2000-siemens-sysv + ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; + GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE + ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "${cputype-}" = 386; then UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" + elif test "x${cputype-}" != x; then + UNAME_MACHINE=$cputype fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; + GUESS=$UNAME_MACHINE-unknown-plan9 + ;; *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; + GUESS=pdp10-unknown-tops10 + ;; *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; + GUESS=pdp10-unknown-tenex + ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; + GUESS=pdp10-dec-tops20 + ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; + GUESS=pdp10-xkl-tops20 + ;; *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; + GUESS=pdp10-unknown-tops20 + ;; *:ITS:*:*) - echo pdp10-unknown-its - exit ;; + GUESS=pdp10-unknown-its + ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; + GUESS=mips-sei-seiux$UNAME_RELEASE + ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; + DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` + GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL + ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; + case $UNAME_MACHINE in + A*) GUESS=alpha-dec-vms ;; + I*) GUESS=ia64-dec-vms ;; + V*) GUESS=vax-dec-vms ;; esac ;; *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; + GUESS=i386-pc-xenix + ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; + SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'` + GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL + ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; + GUESS=$UNAME_MACHINE-pc-rdos + ;; + i*86:Fiwix:*:*) + GUESS=$UNAME_MACHINE-pc-fiwix + ;; + *:AROS:*:*) + GUESS=$UNAME_MACHINE-unknown-aros + ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx - exit ;; + GUESS=$UNAME_MACHINE-unknown-esx + ;; + amd64:Isilon\ OneFS:*:*) + GUESS=x86_64-unknown-onefs + ;; + *:Unleashed:*:*) + GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE + ;; esac -eval $set_cc_for_build -cat >$dummy.c < "$dummy.c" < -# include +#include +#include +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#include +#if defined(_SIZE_T_) || defined(SIGLOST) +#include +#endif +#endif #endif main () { @@ -1388,20 +1588,12 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" -#endif - ); exit (0); -#endif + "" #endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); + ); exit (0); #endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) @@ -1443,39 +1635,54 @@ main () #endif #if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); + struct utsname un; + uname(&un); + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif +#if !defined (ultrix) +#include +#if defined (BSD) +#if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +#else +#if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#endif +#else + printf ("vax-dec-bsd\n"); exit (0); +#endif +#else +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname un; + uname (&un); + printf ("vax-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif +#endif +#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__) +#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__) +#if defined(_SIZE_T_) || defined(SIGLOST) + struct utsname *un; + uname (&un); + printf ("mips-dec-ultrix%s\n", un.release); exit (0); +#else + printf ("mips-dec-ultrix\n"); exit (0); +#endif +#endif #endif #if defined (alliant) && defined (i860) @@ -1486,54 +1693,46 @@ main () } EOF -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && +$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. +test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; } -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } +echo "$0: unable to guess system type" >&2 -# Convex versions that predate uname can use getsysinfo(1) +case $UNAME_MACHINE:$UNAME_SYSTEM in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +our_year=`echo $timestamp | sed 's,-.*,,'` +thisyear=`date +%Y` +# shellcheck disable=SC2003 +script_age=`expr "$thisyear" - "$our_year"` +if test "$script_age" -lt 3 ; then + cat >&2 </dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF +fi exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.sub b/config.sub index 61cb4bc22..dba16e84c 100755 --- a/config.sub +++ b/config.sub @@ -1,12 +1,14 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. +# Copyright 1992-2022 Free Software Foundation, Inc. -timestamp='2013-10-01' +# shellcheck disable=SC2006,SC2268 # see below for rationale + +timestamp='2022-01-03' # This file 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 3 of the License, or +# the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but @@ -15,7 +17,7 @@ timestamp='2013-10-01' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -25,7 +27,7 @@ timestamp='2013-10-01' # of the GNU General Public License, version 3 ("GPLv3"). -# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# Please send patches to . # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. @@ -33,7 +35,7 @@ timestamp='2013-10-01' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -50,15 +52,21 @@ timestamp='2013-10-01' # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. +# The "shellcheck disable" line above the timestamp inhibits complaints +# about features and limitations of the classic Bourne shell that were +# superseded or lifted in POSIX. However, this script identifies a wide +# variety of pre-POSIX systems that do not have POSIX shells at all, and +# even some reasonably current systems (Solaris 10 as case-in-point) still +# have a pre-POSIX /bin/sh. + me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -68,7 +76,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2013 Free Software Foundation, Inc. +Copyright 1992-2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -90,12 +98,12 @@ while test $# -gt 0 ; do - ) # Use stdin as input. break ;; -* ) - echo "$me: invalid option $1$help" + echo "$me: invalid option $1$help" >&2 exit 1 ;; *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -111,1211 +119,1186 @@ case $# in exit 1;; esac -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac +# Split fields of configuration type +# shellcheck disable=SC2162 +saved_IFS=$IFS +IFS="-" read field1 field2 field3 field4 <&2 + exit 1 ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + *-*-*-*) + basic_machine=$field1-$field2 + basic_os=$field3-$field4 ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + *-*-*) + # Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two + # parts + maybe_os=$field2-$field3 + case $maybe_os in + nto-qnx* | linux-* | uclinux-uclibc* \ + | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ + | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ + | storm-chaos* | os2-emx* | rtmk-nova*) + basic_machine=$field1 + basic_os=$maybe_os + ;; + android-linux) + basic_machine=$field1-unknown + basic_os=linux-android + ;; + *) + basic_machine=$field1-$field2 + basic_os=$field3 + ;; + esac ;; - -psos*) - os=-psos + *-*) + # A lone config we happen to match not fitting any pattern + case $field1-$field2 in + decstation-3100) + basic_machine=mips-dec + basic_os= + ;; + *-*) + # Second component is usually, but not always the OS + case $field2 in + # Prevent following clause from handling this valid os + sun*os*) + basic_machine=$field1 + basic_os=$field2 + ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; + # Manufacturers + dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ + | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ + | unicom* | ibm* | next | hp | isi* | apollo | altos* \ + | convergent* | ncr* | news | 32* | 3600* | 3100* \ + | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ + | ultra | tti* | harris | dolphin | highlevel | gould \ + | cbm | ns | masscomp | apple | axis | knuth | cray \ + | microblaze* | sim | cisco \ + | oki | wec | wrs | winbond) + basic_machine=$field1-$field2 + basic_os= + ;; + *) + basic_machine=$field1 + basic_os=$field2 + ;; + esac + ;; + esac ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint + *) + # Convert single-component short-hands not valid as part of + # multi-component configurations. + case $field1 in + 386bsd) + basic_machine=i386-pc + basic_os=bsd + ;; + a29khif) + basic_machine=a29k-amd + basic_os=udi + ;; + adobe68k) + basic_machine=m68010-adobe + basic_os=scout + ;; + alliant) + basic_machine=fx80-alliant + basic_os= + ;; + altos | altos3068) + basic_machine=m68k-altos + basic_os= + ;; + am29k) + basic_machine=a29k-none + basic_os=bsd + ;; + amdahl) + basic_machine=580-amdahl + basic_os=sysv + ;; + amiga) + basic_machine=m68k-unknown + basic_os= + ;; + amigaos | amigados) + basic_machine=m68k-unknown + basic_os=amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + basic_os=sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + basic_os=sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + basic_os=bsd + ;; + aros) + basic_machine=i386-pc + basic_os=aros + ;; + aux) + basic_machine=m68k-apple + basic_os=aux + ;; + balance) + basic_machine=ns32k-sequent + basic_os=dynix + ;; + blackfin) + basic_machine=bfin-unknown + basic_os=linux + ;; + cegcc) + basic_machine=arm-unknown + basic_os=cegcc + ;; + convex-c1) + basic_machine=c1-convex + basic_os=bsd + ;; + convex-c2) + basic_machine=c2-convex + basic_os=bsd + ;; + convex-c32) + basic_machine=c32-convex + basic_os=bsd + ;; + convex-c34) + basic_machine=c34-convex + basic_os=bsd + ;; + convex-c38) + basic_machine=c38-convex + basic_os=bsd + ;; + cray) + basic_machine=j90-cray + basic_os=unicos + ;; + crds | unos) + basic_machine=m68k-crds + basic_os= + ;; + da30) + basic_machine=m68k-da30 + basic_os= + ;; + decstation | pmax | pmin | dec3100 | decstatn) + basic_machine=mips-dec + basic_os= + ;; + delta88) + basic_machine=m88k-motorola + basic_os=sysv3 + ;; + dicos) + basic_machine=i686-pc + basic_os=dicos + ;; + djgpp) + basic_machine=i586-pc + basic_os=msdosdjgpp + ;; + ebmon29k) + basic_machine=a29k-amd + basic_os=ebmon + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + basic_os=ose + ;; + gmicro) + basic_machine=tron-gmicro + basic_os=sysv + ;; + go32) + basic_machine=i386-pc + basic_os=go32 + ;; + h8300hms) + basic_machine=h8300-hitachi + basic_os=hms + ;; + h8300xray) + basic_machine=h8300-hitachi + basic_os=xray + ;; + h8500hms) + basic_machine=h8500-hitachi + basic_os=hms + ;; + harris) + basic_machine=m88k-harris + basic_os=sysv3 + ;; + hp300 | hp300hpux) + basic_machine=m68k-hp + basic_os=hpux + ;; + hp300bsd) + basic_machine=m68k-hp + basic_os=bsd + ;; + hppaosf) + basic_machine=hppa1.1-hp + basic_os=osf + ;; + hppro) + basic_machine=hppa1.1-hp + basic_os=proelf + ;; + i386mach) + basic_machine=i386-mach + basic_os=mach + ;; + isi68 | isi) + basic_machine=m68k-isi + basic_os=sysv + ;; + m68knommu) + basic_machine=m68k-unknown + basic_os=linux + ;; + magnum | m3230) + basic_machine=mips-mips + basic_os=sysv + ;; + merlin) + basic_machine=ns32k-utek + basic_os=sysv + ;; + mingw64) + basic_machine=x86_64-pc + basic_os=mingw64 + ;; + mingw32) + basic_machine=i686-pc + basic_os=mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + basic_os=mingw32ce + ;; + monitor) + basic_machine=m68k-rom68k + basic_os=coff + ;; + morphos) + basic_machine=powerpc-unknown + basic_os=morphos + ;; + moxiebox) + basic_machine=moxie-unknown + basic_os=moxiebox + ;; + msdos) + basic_machine=i386-pc + basic_os=msdos + ;; + msys) + basic_machine=i686-pc + basic_os=msys + ;; + mvs) + basic_machine=i370-ibm + basic_os=mvs + ;; + nacl) + basic_machine=le32-unknown + basic_os=nacl + ;; + ncr3000) + basic_machine=i486-ncr + basic_os=sysv4 + ;; + netbsd386) + basic_machine=i386-pc + basic_os=netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + basic_os=linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + basic_os=newsos + ;; + news1000) + basic_machine=m68030-sony + basic_os=newsos + ;; + necv70) + basic_machine=v70-nec + basic_os=sysv + ;; + nh3000) + basic_machine=m68k-harris + basic_os=cxux + ;; + nh[45]000) + basic_machine=m88k-harris + basic_os=cxux + ;; + nindy960) + basic_machine=i960-intel + basic_os=nindy + ;; + mon960) + basic_machine=i960-intel + basic_os=mon960 + ;; + nonstopux) + basic_machine=mips-compaq + basic_os=nonstopux + ;; + os400) + basic_machine=powerpc-ibm + basic_os=os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + basic_os=ose + ;; + os68k) + basic_machine=m68k-none + basic_os=os68k + ;; + paragon) + basic_machine=i860-intel + basic_os=osf + ;; + parisc) + basic_machine=hppa-unknown + basic_os=linux + ;; + psp) + basic_machine=mipsallegrexel-sony + basic_os=psp + ;; + pw32) + basic_machine=i586-unknown + basic_os=pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + basic_os=rdos + ;; + rdos32) + basic_machine=i386-pc + basic_os=rdos + ;; + rom68k) + basic_machine=m68k-rom68k + basic_os=coff + ;; + sa29200) + basic_machine=a29k-amd + basic_os=udi + ;; + sei) + basic_machine=mips-sei + basic_os=seiux + ;; + sequent) + basic_machine=i386-sequent + basic_os= + ;; + sps7) + basic_machine=m68k-bull + basic_os=sysv2 + ;; + st2000) + basic_machine=m68k-tandem + basic_os= + ;; + stratus) + basic_machine=i860-stratus + basic_os=sysv4 + ;; + sun2) + basic_machine=m68000-sun + basic_os= + ;; + sun2os3) + basic_machine=m68000-sun + basic_os=sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + basic_os=sunos4 + ;; + sun3) + basic_machine=m68k-sun + basic_os= + ;; + sun3os3) + basic_machine=m68k-sun + basic_os=sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + basic_os=sunos4 + ;; + sun4) + basic_machine=sparc-sun + basic_os= + ;; + sun4os3) + basic_machine=sparc-sun + basic_os=sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + basic_os=sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + basic_os=solaris2 + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + basic_os= + ;; + sv1) + basic_machine=sv1-cray + basic_os=unicos + ;; + symmetry) + basic_machine=i386-sequent + basic_os=dynix + ;; + t3e) + basic_machine=alphaev5-cray + basic_os=unicos + ;; + t90) + basic_machine=t90-cray + basic_os=unicos + ;; + toad1) + basic_machine=pdp10-xkl + basic_os=tops20 + ;; + tpf) + basic_machine=s390x-ibm + basic_os=tpf + ;; + udi29k) + basic_machine=a29k-amd + basic_os=udi + ;; + ultra3) + basic_machine=a29k-nyu + basic_os=sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + basic_os=none + ;; + vaxv) + basic_machine=vax-dec + basic_os=sysv + ;; + vms) + basic_machine=vax-dec + basic_os=vms + ;; + vsta) + basic_machine=i386-pc + basic_os=vsta + ;; + vxworks960) + basic_machine=i960-wrs + basic_os=vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + basic_os=vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + basic_os=vxworks + ;; + xbox) + basic_machine=i686-pc + basic_os=mingw32 + ;; + ymp) + basic_machine=ymp-cray + basic_os=unicos + ;; + *) + basic_machine=$1 + basic_os= + ;; + esac ;; esac -# Decode aliases for certain CPU-COMPANY combinations. +# Decode 1-component or ad-hoc basic machines case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | c8051 | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | k1om \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown + # Here we handle the default manufacturer of certain CPU types. It is in + # some cases the only manufacturer, in others, it is the most popular. + w89k) + cpu=hppa1.1 + vendor=winbond ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown + op50n) + cpu=hppa1.1 + vendor=oki ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none + op60c) + cpu=hppa1.1 + vendor=oki ;; - xscaleeb) - basic_machine=armeb-unknown + ibm*) + cpu=i370 + vendor=ibm ;; - - xscaleel) - basic_machine=armel-unknown + orion105) + cpu=clipper + vendor=highlevel ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 + mac | mpw | mac-mpw) + cpu=m68k + vendor=apple ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | c8051-* | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | k1om-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown + pmac | pmac-mpw) + cpu=powerpc + vendor=apple ;; + # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att + cpu=m68000 + vendor=att ;; 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=we32k + vendor=att ;; bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec + cpu=powerpc + vendor=ibm + basic_os=cnk ;; decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 + cpu=pdp10 + vendor=dec + basic_os=tops10 ;; decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 + cpu=pdp10 + vendor=dec + basic_os=tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon + cpu=m68k + vendor=motorola ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd + dpx2*) + cpu=m68k + vendor=bull + basic_os=sysv3 ;; encore | umax | mmax) - basic_machine=ns32k-encore + cpu=ns32k + vendor=encore ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose + elxsi) + cpu=elxsi + vendor=elxsi + basic_os=${basic_os:-bsd} ;; fx2800) - basic_machine=i860-alliant + cpu=i860 + vendor=alliant ;; genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 + cpu=ns32k + vendor=ns ;; h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp + cpu=m68000 + vendor=hp ;; hp9k3[2-9][0-9]) - basic_machine=m68k-hp + cpu=m68k + vendor=hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp + cpu=hppa1.0 + vendor=hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp + cpu=hppa1.1 + vendor=hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm + cpu=hppa1.0 + vendor=hp ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach + cpu=`echo "$1" | sed -e 's/86.*/86/'` + vendor=pc + basic_os=solaris2 ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta + j90 | j90-cray) + cpu=j90 + vendor=cray + basic_os=${basic_os:-unicos} ;; iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) + cpu=mips + vendor=sgi + case $basic_os in + irix*) ;; *) - os=-irix4 + basic_os=irix4 ;; esac ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i686-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; miniframe) - basic_machine=m68000-convergent + cpu=m68000 + vendor=convergent ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i686-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos + *mint | mint[0-9]* | *MiNT | *MiNT[0-9]*) + cpu=m68k + vendor=atari + basic_os=mint ;; news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) + cpu=mips + vendor=sony + basic_os=newsos + ;; + next | m*-next) + cpu=m68k + vendor=next + case $basic_os in + openstep*) + ;; + nextstep*) ;; - -ns2*) - os=-nextstep2 + ns2*) + basic_os=nextstep2 ;; *) - os=-nextstep3 + basic_os=nextstep3 ;; esac ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem + cpu=np1 + vendor=gould ;; op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k + cpu=hppa1.1 + vendor=oki + basic_os=proelf ;; pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux + cpu=hppa1.1 + vendor=hitachi + basic_os=hiuxwe2 ;; pbd) - basic_machine=sparc-tti + cpu=sparc + vendor=tti ;; pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + cpu=m68k + vendor=tti ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + pc532) + cpu=ns32k + vendor=pc532 ;; pn) - basic_machine=pn-gould + cpu=pn + vendor=gould ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + power) + cpu=power + vendor=ibm ;; ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff + cpu=i386 + vendor=ibm ;; rm[46]00) - basic_machine=mips-siemens + cpu=mips + vendor=siemens ;; rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm + cpu=romp + vendor=ibm ;; - sa29200) - basic_machine=a29k-amd - os=-udi + sde) + cpu=mipsisa32 + vendor=sde + basic_os=${basic_os:-elf} ;; - sb1) - basic_machine=mipsisa64sb1-unknown + simso-wrs) + cpu=sparclite + vendor=wrs + basic_os=vxworks ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown + tower | tower-32) + cpu=m68k + vendor=ncr ;; - sde) - basic_machine=mipsisa32-sde - os=-elf + vpp*|vx|vx-*) + cpu=f301 + vendor=fujitsu ;; - sei) - basic_machine=mips-sei - os=-seiux + w65) + cpu=w65 + vendor=wdc ;; - sequent) - basic_machine=i386-sequent + w89k-*) + cpu=hppa1.1 + vendor=winbond + basic_os=proelf ;; - sh) - basic_machine=sh-hitachi - os=-hms + none) + cpu=none + vendor=none ;; - sh5el) - basic_machine=sh5le-unknown + leon|leon[3-9]) + cpu=sparc + vendor=$basic_machine ;; - sh64) - basic_machine=sh64-unknown + leon-*|leon[3-9]-*) + cpu=sparc + vendor=`echo "$basic_machine" | sed 's/-.*//'` ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks + + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read cpu vendor <&2 - exit 1 + # Recognize the canonical CPU types that are allowed with any + # company name. + case $cpu in + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | abacus \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \ + | alphapca5[67] | alpha64pca5[67] \ + | am33_2.0 \ + | amdgcn \ + | arc | arceb | arc32 | arc64 \ + | arm | arm[lb]e | arme[lb] | armv* \ + | avr | avr32 \ + | asmjs \ + | ba \ + | be32 | be64 \ + | bfin | bpf | bs2000 \ + | c[123]* | c30 | [cjt]90 | c4x \ + | c8051 | clipper | craynv | csky | cydra \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | elxsi | epiphany \ + | f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \ + | h8300 | h8500 \ + | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i*86 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | loongarch32 | loongarch64 | loongarchx32 \ + | m32c | m32r | m32rle \ + | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \ + | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \ + | m88110 | m88k | maxq | mb | mcore | mep | metag \ + | microblaze | microblazeel \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64eb | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r3 | mipsisa32r3el \ + | mipsisa32r5 | mipsisa32r5el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r3 | mipsisa64r3el \ + | mipsisa64r5 | mipsisa64r5el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mmix \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nfp \ + | nios | nios2 | nios2eb | nios2el \ + | none | np1 | ns16k | ns32k | nvptx \ + | open8 \ + | or1k* \ + | or32 \ + | orion \ + | picochip \ + | pdp10 | pdp11 | pj | pjl | pn | power \ + | powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \ + | pru \ + | pyramid \ + | riscv | riscv32 | riscv32be | riscv64 | riscv64be \ + | rl78 | romp | rs6000 | rx \ + | s390 | s390x \ + | score \ + | sh | shl \ + | sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \ + | sh[1234]e[lb] | sh[12345][lb]e | sh[23]ele | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \ + | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ + | spu \ + | tahoe \ + | thumbv7* \ + | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ + | tron \ + | ubicom32 \ + | v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \ + | vax \ + | visium \ + | w65 \ + | wasm32 | wasm64 \ + | we32k \ + | x86 | x86_64 | xc16x | xgate | xps100 \ + | xstormy16 | xtensa* \ + | ymp \ + | z8k | z80) + ;; + + *) + echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2 + exit 1 + ;; + esac ;; esac # Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` +case $vendor in + digital*) + vendor=dec ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + commodore*) + vendor=cbm ;; *) ;; @@ -1323,200 +1306,215 @@ esac # Decode manufacturer-specific aliases for certain operating systems. -if [ x"$os" != x"" ] +if test x$basic_os != x then + +# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just +# set os. +case $basic_os in + gnu/linux*) + kernel=linux + os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'` + ;; + os2-emx) + kernel=os2 + os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'` + ;; + nto-qnx*) + kernel=nto + os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` + ;; + *-*) + # shellcheck disable=SC2162 + saved_IFS=$IFS + IFS="-" read kernel os <&2 - exit 1 + # No normalization, but not necessarily accepted, that comes below. ;; esac + else # Here we handle the default operating systems that come with various machines. @@ -1529,264 +1527,363 @@ else # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. -case $basic_machine in +kernel= +case $cpu-$vendor in score-*) - os=-elf + os=elf ;; spu-*) - os=-elf + os=elf ;; *-acorn) - os=-riscix1.2 + os=riscix1.2 ;; arm*-rebel) - os=-linux + kernel=linux + os=gnu ;; arm*-semi) - os=-aout + os=aout ;; c4x-* | tic4x-*) - os=-coff + os=coff ;; c8051-*) - os=-elf + os=elf + ;; + clipper-intergraph) + os=clix ;; hexagon-*) - os=-elf + os=elf ;; tic54x-*) - os=-coff + os=coff ;; tic55x-*) - os=-coff + os=coff ;; tic6x-*) - os=-coff + os=coff ;; # This must come before the *-dec entry. pdp10-*) - os=-tops20 + os=tops20 ;; pdp11-*) - os=-none + os=none ;; *-dec | vax-*) - os=-ultrix4.2 + os=ultrix4.2 ;; m68*-apollo) - os=-domain + os=domain ;; i386-sun) - os=-sunos4.0.2 + os=sunos4.0.2 ;; m68000-sun) - os=-sunos3 + os=sunos3 ;; m68*-cisco) - os=-aout + os=aout ;; mep-*) - os=-elf + os=elf ;; mips*-cisco) - os=-elf + os=elf ;; mips*-*) - os=-elf - ;; - or1k-*) - os=-elf + os=elf ;; or32-*) - os=-coff + os=coff ;; *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 + os=sysv3 ;; sparc-* | *-sun) - os=-sunos4.1.1 + os=sunos4.1.1 ;; - *-be) - os=-beos + pru-*) + os=elf ;; - *-haiku) - os=-haiku + *-be) + os=beos ;; *-ibm) - os=-aix + os=aix ;; *-knuth) - os=-mmixware + os=mmixware ;; *-wec) - os=-proelf + os=proelf ;; *-winbond) - os=-proelf + os=proelf ;; *-oki) - os=-proelf + os=proelf ;; *-hp) - os=-hpux + os=hpux ;; *-hitachi) - os=-hiux + os=hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv + os=sysv ;; *-cbm) - os=-amigaos + os=amigaos ;; *-dg) - os=-dgux + os=dgux ;; *-dolphin) - os=-sysv3 + os=sysv3 ;; m68k-ccur) - os=-rtu + os=rtu ;; m88k-omron*) - os=-luna + os=luna ;; - *-next ) - os=-nextstep + *-next) + os=nextstep ;; *-sequent) - os=-ptx + os=ptx ;; *-crds) - os=-unos + os=unos ;; *-ns) - os=-genix + os=genix ;; i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 + os=mvs ;; *-gould) - os=-sysv + os=sysv ;; *-highlevel) - os=-bsd + os=bsd ;; *-encore) - os=-bsd + os=bsd ;; *-sgi) - os=-irix + os=irix ;; *-siemens) - os=-sysv4 + os=sysv4 ;; *-masscomp) - os=-rtu + os=rtu ;; f30[01]-fujitsu | f700-fujitsu) - os=-uxpv + os=uxpv ;; *-rom68k) - os=-coff + os=coff ;; *-*bug) - os=-coff + os=coff ;; *-apple) - os=-macos + os=macos ;; *-atari*) - os=-mint + os=mint + ;; + *-wrs) + os=vxworks ;; *) - os=-none + os=none ;; esac + fi +# Now, validate our (potentially fixed-up) OS. +case $os in + # Sometimes we do "kernel-libc", so those need to count as OSes. + musl* | newlib* | relibc* | uclibc*) + ;; + # Likewise for "kernel-abi" + eabi* | gnueabi*) + ;; + # VxWorks passes extra cpu info in the 4th filed. + simlinux | simwindows | spe) + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \ + | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \ + | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \ + | sym* | plan9* | psp* | sim* | xray* | os68k* | v88r* \ + | hiux* | abug | nacl* | netware* | windows* \ + | os9* | macos* | osx* | ios* \ + | mpw* | magic* | mmixware* | mon960* | lnews* \ + | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \ + | aos* | aros* | cloudabi* | sortix* | twizzler* \ + | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \ + | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \ + | mirbsd* | netbsd* | dicos* | openedition* | ose* \ + | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \ + | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \ + | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \ + | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \ + | udi* | lites* | ieee* | go32* | aux* | hcos* \ + | chorusrdb* | cegcc* | glidix* | serenity* \ + | cygwin* | msys* | pe* | moss* | proelf* | rtems* \ + | midipix* | mingw32* | mingw64* | mint* \ + | uxpv* | beos* | mpeix* | udk* | moxiebox* \ + | interix* | uwin* | mks* | rhapsody* | darwin* \ + | openstep* | oskit* | conix* | pw32* | nonstopux* \ + | storm-chaos* | tops10* | tenex* | tops20* | its* \ + | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \ + | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \ + | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \ + | skyos* | haiku* | rdos* | toppers* | drops* | es* \ + | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ + | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ + | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \ + | fiwix* ) + ;; + # This one is extra strict with allowed versions + sco3.2v2 | sco3.2v[4-9]* | sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + ;; + none) + ;; + *) + echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac + +# As a final step for OS-related things, validate the OS-kernel combination +# (given a valid OS), if there is a kernel. +case $kernel-$os in + linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ + | linux-musl* | linux-relibc* | linux-uclibc* ) + ;; + uclinux-uclibc* ) + ;; + -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + # These are just libc implementations, not actual OSes, and thus + # require a kernel. + echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + exit 1 + ;; + kfreebsd*-gnu* | kopensolaris*-gnu*) + ;; + vxworks-simlinux | vxworks-simwindows | vxworks-spe) + ;; + nto-qnx*) + ;; + os2-emx) + ;; + *-eabi* | *-gnueabi*) + ;; + -*) + # Blank kernel with real OS is always fine. + ;; + *-*) + echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + exit 1 + ;; +esac + # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) +case $vendor in + unknown) + case $cpu-$os in + *-riscix*) vendor=acorn ;; - -sunos*) + *-sunos*) vendor=sun ;; - -cnk*|-aix*) + *-cnk* | *-aix*) vendor=ibm ;; - -beos*) + *-beos*) vendor=be ;; - -hpux*) + *-hpux*) vendor=hp ;; - -mpeix*) + *-mpeix*) vendor=hp ;; - -hiux*) + *-hiux*) vendor=hitachi ;; - -unos*) + *-unos*) vendor=crds ;; - -dgux*) + *-dgux*) vendor=dg ;; - -luna*) + *-luna*) vendor=omron ;; - -genix*) + *-genix*) vendor=ns ;; - -mvs* | -opened*) + *-clix*) + vendor=intergraph + ;; + *-mvs* | *-opened*) + vendor=ibm + ;; + *-os400*) vendor=ibm ;; - -os400*) + s390-* | s390x-*) vendor=ibm ;; - -ptx*) + *-ptx*) vendor=sequent ;; - -tpf*) + *-tpf*) vendor=ibm ;; - -vxsim* | -vxworks* | -windiss*) + *-vxsim* | *-vxworks* | *-windiss*) vendor=wrs ;; - -aux*) + *-aux*) vendor=apple ;; - -hms*) + *-hms*) vendor=hitachi ;; - -mpw* | -macos*) + *-mpw* | *-macos*) vendor=apple ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + *-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*) vendor=atari ;; - -vos*) + *-vos*) vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$cpu-$vendor-${kernel:+$kernel-}$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index a46313d29..d82ad2119 100755 --- a/configure +++ b/configure @@ -655,6 +655,7 @@ CSFLAGS LIBCUPS_STATIC LIBCUPS INSTALL_STATIC +CUPS_PC PKGCONFIG_AVAHI PKGCONFIG_REQUIRES_PRIVATE PKGCONFIG_REQUIRES @@ -662,6 +663,7 @@ PKGCONFIG_LIBS_PRIVATE PKGCONFIG_LIBS PKGCONFIG_CFLAGS PKGCONFIG +LINKCUPS ARFLAGS LN RMDIR @@ -734,6 +736,7 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_libcups3_prefix with_dnssd with_tls enable_static @@ -1374,6 +1377,8 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-libcups3-prefix + do not add libcups3 prefix to header/library files --disable-static do not install static library --disable-shared do not install shared library --enable-debug turn on debugging, default=no @@ -4027,6 +4032,32 @@ INSTALL="$(pwd)/install-sh" printf "%s\n" "using $INSTALL" >&6; } +# Check whether --enable-libcups3-prefix was given. +if test ${enable_libcups3_prefix+y} +then : + enableval=$enable_libcups3_prefix; +fi + + +if test x$enable_libcups3_prefix != xno +then : + + CUPS_PC="cups3.pc" + INCLUDE_PREFIX="/libcups3" + LIBCUPS_BASE="libcups3" + LINKCUPS="-lcups3" + +else $as_nop + + CUPS_PC="cups.pc" + INCLUDE_PREFIX="" + LIBCUPS_BASE="libcups" + LINKCUPS="-lcups" + +fi + + + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 @@ -4137,7 +4168,7 @@ fi PKGCONFIG_CFLAGS="" -PKGCONFIG_LIBS="-L\${libdir} -lcups" +PKGCONFIG_LIBS="-L\${libdir} $LINKCUPS" PKGCONFIG_LIBS_PRIVATE="-lz -lm" PKGCONFIG_REQUIRES="" PKGCONFIG_REQUIRES_PRIVATE="zlib" @@ -5157,25 +5188,27 @@ then : fi +LIBCUPS_STATIC="$LIBCUPS_BASE.a" + if test x$enable_shared != xno then : case "$host_os_name" in #( linux* | gnu* | *bsd*) : - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; #( darwin*) : - LIBCUPS="libcups.3.dylib" + LIBCUPS="$LIBCUPS_BASE.3.dylib" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -single_module -lc" ;; #( sunos*) : - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G" ;; #( @@ -5183,7 +5216,7 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Warning: Shared libraries may not work, trying -shared option." >&5 printf "%s\n" "$as_me: Warning: Shared libraries may not work, trying -shared option." >&6;} - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ;; #( @@ -5197,20 +5230,17 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Installing static libraries..." >&5 printf "%s\n" "$as_me: Installing static libraries..." >&6;} INSTALL_STATIC="install-static" - LIBCUPS_STATIC="libcups.a" else $as_nop INSTALL_STATIC="" - LIBCUPS_STATIC="" fi else $as_nop INSTALL_STATIC="" - LIBCUPS="libcups.a" - LIBCUPS_STATIC="" + LIBCUPS="$LIBCUPS_BASE.a" PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS_PRIVATE="" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES $PKGCONFIG_REQUIRES_PRIVATE" @@ -5223,6 +5253,7 @@ fi + # Check whether --enable-debug was given. if test ${enable_debug+y} then : @@ -5446,6 +5477,7 @@ then : fi + if test "$prefix" = NONE then : @@ -5458,12 +5490,24 @@ else $as_nop fi +if test "$includedir" = NONE -o "$includedir" = "\${prefix}/include" +then : + + includedir="$realprefix/include$INCLUDE_PREFIX" + +fi +if test "$includedir" != "/usr/include" -a "$includedir" != "/usr/local/include" +then : + + PKGCONFIG_CFLAGS="-I\${includedir} $PKGCONFIG_CFLAGS" + +fi PKGCONFIG_REQUIRES="$(echo $PKGCONFIG_REQUIRES | sed -e '1,$s/,$//')" PKGCONFIG_REQUIRES_PRIVATE="$(echo $PKGCONFIG_REQUIRES_PRIVATE | sed -e '1,$s/,$//')" -ac_config_files="$ac_config_files Makedefs cups.pc packaging/libcups.list" +ac_config_files="$ac_config_files Makedefs cups3.pc packaging/libcups.list" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -6152,7 +6196,7 @@ do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "Makedefs") CONFIG_FILES="$CONFIG_FILES Makedefs" ;; - "cups.pc") CONFIG_FILES="$CONFIG_FILES cups.pc" ;; + "cups3.pc") CONFIG_FILES="$CONFIG_FILES cups3.pc" ;; "packaging/libcups.list") CONFIG_FILES="$CONFIG_FILES packaging/libcups.list" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; diff --git a/configure.ac b/configure.ac index 883cd23f0..7380e3c43 100644 --- a/configure.ac +++ b/configure.ac @@ -101,11 +101,28 @@ AC_SUBST([INSTALL]) AC_MSG_RESULT([using $INSTALL]) +dnl Library prefix... +AC_ARG_ENABLE([libcups3-prefix], AS_HELP_STRING([--disable-libcups3-prefix], [do not add libcups3 prefix to header/library files])) + +AS_IF([test x$enable_libcups3_prefix != xno], [ + CUPS_PC="cups3.pc" + INCLUDE_PREFIX="/libcups3" + LIBCUPS_BASE="libcups3" + LINKCUPS="-lcups3" +], [ + CUPS_PC="cups.pc" + INCLUDE_PREFIX="" + LIBCUPS_BASE="libcups" + LINKCUPS="-lcups" +]) +AC_SUBST([LINKCUPS]) + + dnl Check for pkg-config, which is used for some other tests later on... AC_PATH_TOOL([PKGCONFIG], [pkg-config]) PKGCONFIG_CFLAGS="" -PKGCONFIG_LIBS="-L\${libdir} -lcups" +PKGCONFIG_LIBS="-L\${libdir} $LINKCUPS" PKGCONFIG_LIBS_PRIVATE="-lz -lm" PKGCONFIG_REQUIRES="" PKGCONFIG_REQUIRES_PRIVATE="zlib" @@ -396,22 +413,24 @@ dnl Library targets... AC_ARG_ENABLE([static], AS_HELP_STRING([--disable-static], [do not install static library])) AC_ARG_ENABLE([shared], AS_HELP_STRING([--disable-shared], [do not install shared library])) +LIBCUPS_STATIC="$LIBCUPS_BASE.a" + AS_IF([test x$enable_shared != xno], [ AS_CASE(["$host_os_name"], [linux* | gnu* | *bsd*], [ - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ], [darwin*], [ - LIBCUPS="libcups.3.dylib" + LIBCUPS="$LIBCUPS_BASE.3.dylib" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-no_warn_inits -dynamiclib -single_module -lc" ], [sunos*], [ - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-h,\`basename \$@\` -G" ], [*], [ AC_MSG_NOTICE([Warning: Shared libraries may not work, trying -shared option.]) - LIBCUPS="libcups.so.3" + LIBCUPS="$LIBCUPS_BASE.so.3" DSO="\$(CC)" DSOFLAGS="$DSOFLAGS -Wl,-soname,\`basename \$@\` -shared" ]) @@ -419,21 +438,19 @@ AS_IF([test x$enable_shared != xno], [ AS_IF([test x$enable_static != xno], [ AC_MSG_NOTICE([Installing static libraries...]) INSTALL_STATIC="install-static" - LIBCUPS_STATIC="libcups.a" ], [ INSTALL_STATIC="" - LIBCUPS_STATIC="" ]) ], [ INSTALL_STATIC="" - LIBCUPS="libcups.a" - LIBCUPS_STATIC="" + LIBCUPS="$LIBCUPS_BASE.a" PKGCONFIG_LIBS="$PKGCONFIG_LIBS $PKGCONFIG_LIBS_PRIVATE" PKGCONFIG_LIBS_PRIVATE="" PKGCONFIG_REQUIRES="$PKGCONFIG_REQUIRES $PKGCONFIG_REQUIRES_PRIVATE" PKGCONFIG_REQUIRES_PRIVATE="" ]) +AC_SUBST([CUPS_PC]) AC_SUBST([INSTALL_STATIC]) AC_SUBST([LIBCUPS]) AC_SUBST([LIBCUPS_STATIC]) @@ -548,7 +565,8 @@ AC_ARG_WITH([ldflags], AS_HELP_STRING([--with-ldflags=...], [Specify additional LDFLAGS="$withval $LDFLAGS" ]) -dnl State and run directories for root servers... + +dnl Fix prefix and includedir... AS_IF([test "$prefix" = NONE], [ # Default prefix isn't bound until AC_OUTPUT... realprefix="/usr/local" @@ -556,6 +574,12 @@ AS_IF([test "$prefix" = NONE], [ realprefix="$prefix" ]) +AS_IF([test "$includedir" = NONE -o "$includedir" = "\${prefix}/include"], [ + includedir="$realprefix/include$INCLUDE_PREFIX" +]) +AS_IF([test "$includedir" != "/usr/include" -a "$includedir" != "/usr/local/include"], [ + PKGCONFIG_CFLAGS="-I\${includedir} $PKGCONFIG_CFLAGS" +]) dnl Clean up pkg-config "requires" content... [PKGCONFIG_REQUIRES="$(echo $PKGCONFIG_REQUIRES | sed -e '1,$s/,$//')"] @@ -563,5 +587,5 @@ dnl Clean up pkg-config "requires" content... dnl Provide autoconf with a list of files to generate and output them... -AC_CONFIG_FILES([Makedefs cups.pc packaging/libcups.list]) +AC_CONFIG_FILES([Makedefs cups3.pc packaging/libcups.list]) AC_OUTPUT diff --git a/cups/Makefile b/cups/Makefile index cb899f79f..55ade0392 100644 --- a/cups/Makefile +++ b/cups/Makefile @@ -23,6 +23,7 @@ LIBOBJS = \ dest-localization.o \ dest-options.o \ dir.o \ + dnssd.o \ encode.o \ file.o \ getputfile.o \ @@ -59,6 +60,7 @@ TESTOBJS = \ testclient.o \ testcreds.o \ testdest.o \ + testdnssd.o \ testfile.o \ testgetdests.o \ testhttp.o \ @@ -87,6 +89,7 @@ HEADERS = \ base.h \ cups.h \ dir.h \ + dnssd.h \ file.h \ http.h \ ipp.h \ @@ -102,7 +105,7 @@ HEADERS = \ # LIBTARGETS = \ - libcups.a \ + $(LIBCUPS_STATIC) \ $(LIBCUPS) UNITTARGETS = \ @@ -112,6 +115,7 @@ UNITTARGETS = \ testclient \ testcreds \ testdest \ + testdnssd \ testfile \ testgetdests \ testhttp \ @@ -190,16 +194,16 @@ install: all $(INSTALL_STATIC) for file in $(HEADERS); do \ $(INSTALL_DATA) $$file $(BUILDROOT)$(includedir)/cups; \ done - echo "Installing libraries to $(BUILDROOT)$(libdir)..." + echo "Installing library to $(BUILDROOT)$(libdir)..." $(INSTALL_DIR) $(BUILDROOT)$(libdir) $(INSTALL_LIB) $(LIBCUPS) $(BUILDROOT)$(libdir) - if test $(LIBCUPS) = "libcups.so.3"; then \ + if test $(LIBCUPS) = "libcups.so.3" -o $(LIBCUPS) = "libcups3.so.3"; then \ $(RM) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3`; \ $(LN) $(LIBCUPS) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3`; \ fi - if test $(LIBCUPS) = "libcups.3.dylib"; then \ - $(RM) $(BUILDROOT)$(libdir)/libcups.dylib; \ - $(LN) $(LIBCUPS) $(BUILDROOT)$(libdir)/libcups.dylib; \ + if test $(LIBCUPS) = "libcups.3.dylib" -o $(LIBCUPS) = "libcups3.3.dylib"; then \ + $(RM) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3.dylib`.dylib; \ + $(LN) $(LIBCUPS) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3.dylib`.dylib; \ fi if test "x$(SYMROOT)" != "x"; then \ echo "Copying debug symbols to $(SYMROOT)..."; \ @@ -209,10 +213,10 @@ install: all $(INSTALL_STATIC) fi install-static: - echo "Installing static libraries to $(BUILDROOT)$(libdir)..." + echo "Installing static library to $(BUILDROOT)$(libdir)..." $(INSTALL_DIR) $(BUILDROOT)$(libdir) - $(INSTALL_LIB) libcups.a $(BUILDROOT)$(libdir) - $(RANLIB) $(BUILDROOT)$(libdir)/libcups.a + $(INSTALL_LIB) $(LIBCUPS_STATIC) $(BUILDROOT)$(libdir) + $(RANLIB) $(BUILDROOT)$(libdir)/$(LIBCUPS_STATIC) # @@ -220,11 +224,14 @@ install-static: # uninstall: - $(RM) $(BUILDROOT)$(libdir)/libcups.3.dylib - $(RM) $(BUILDROOT)$(libdir)/libcups.a - $(RM) $(BUILDROOT)$(libdir)/libcups.dylib - $(RM) $(BUILDROOT)$(libdir)/libcups.so - $(RM) $(BUILDROOT)$(libdir)/libcups.so.3 + $(RM) $(BUILDROOT)$(libdir)/$(LIBCUPS) + $(RM) $(BUILDROOT)$(libdir)/$(LIBCUPS_STATIC) + if test $(LIBCUPS) = "libcups.so.3" -o $(LIBCUPS) = "libcups3.so.3"; then \ + $(RM) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3`; \ + fi + if test $(LIBCUPS) = "libcups.3.dylib" -o $(LIBCUPS) = "libcups3.3.dylib"; then \ + $(RM) $(BUILDROOT)$(libdir)/`basename $(LIBCUPS) .3.dylib`.dylib; \ + fi -$(RMDIR) $(BUILDROOT)$(libdir) for file in $(HEADERS); do \ $(RM) $(BUILDROOT)$(includedir)/cups/$$file; \ @@ -233,10 +240,10 @@ uninstall: # -# libcups.so.3 +# libcups.so.3 / libcups3.so.3 # -libcups.so.3: $(LIBOBJS) +libcups.so.3 libcups3.so.3: $(LIBOBJS) echo Linking $@... $(CC) $(DSOFLAGS) $(OPTIM) -o $@ $(LIBOBJS) $(LIBS) $(RM) `basename $@ .3` @@ -244,24 +251,24 @@ libcups.so.3: $(LIBOBJS) # -# libcups.3.dylib +# libcups.3.dylib / libcups3.3.dylib # -libcups.3.dylib: $(LIBOBJS) +libcups.3.dylib libcups3.3.dylib: $(LIBOBJS) echo Linking $@... $(CC) $(DSOFLAGS) $(OPTIM) -o $@ -install_name $(libdir)/$@ \ -current_version 3.0.0 -compatibility_version 3.0.0 \ $(LIBOBJS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ - $(RM) libcups.dylib - $(LN) $@ libcups.dylib + $(RM) `basename $@ .3.dylib`.dylib + $(LN) $@ `basename $@ .3.dylib`.dylib # -# libcups.a +# libcups.a / libcups3.a # -libcups.a: $(LIBOBJS) +libcups.a / libcups3.a: $(LIBOBJS) echo Archiving $@... $(RM) $@ $(AR) $(ARFLAGS) $@ $(LIBOBJS) @@ -287,9 +294,9 @@ libcups3.def: $(LIBOBJS) $(IMAGEOBJS) Makefile # fuzzipp (dependency on static CUPS library is intentional) # -fuzzipp: fuzzipp.o libcups.a +fuzzipp: fuzzipp.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ fuzzipp.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ fuzzipp.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -297,9 +304,9 @@ fuzzipp: fuzzipp.o libcups.a # rasterbench (dependency on static CUPS library is intentional) # -rasterbench: rasterbench.o libcups.a +rasterbench: rasterbench.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ rasterbench.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ rasterbench.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -307,9 +314,9 @@ rasterbench: rasterbench.o libcups.a # testarray (dependency on static CUPS library is intentional) # -testarray: testarray.o libcups.a +testarray: testarray.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testarray.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testarray.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -317,9 +324,9 @@ testarray: testarray.o libcups.a # testclient (dependency on static libraries is intentional) # -testclient: testclient.o libcups.a +testclient: testclient.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testclient.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testclient.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -327,9 +334,9 @@ testclient: testclient.o libcups.a # testcreds (dependency on static CUPS library is intentional) # -testcreds: testcreds.o libcups.a +testcreds: testcreds.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testcreds.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testcreds.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -337,9 +344,9 @@ testcreds: testcreds.o libcups.a # testcups (dependency on static CUPS library is intentional) # -testcups: testcups.o libcups.a +testcups: testcups.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testcups.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testcups.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -347,9 +354,19 @@ testcups: testcups.o libcups.a # testdest (dependency on static CUPS library is intentional) # -testdest: testdest.o libcups.a +testdest: testdest.o $(LIBCUPS_STATIC) + echo Linking $@... + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testdest.o $(LIBCUPS_STATIC) $(LIBS) + $(CODE_SIGN) $(CSFLAGS) $@ + + +# +# testdnssd (dependency on static CUPS library is intentional) +# + +testdnssd: testdnssd.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testdest.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testdnssd.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -357,9 +374,9 @@ testdest: testdest.o libcups.a # testfile (dependency on static CUPS library is intentional) # -testfile: testfile.o libcups.a +testfile: testfile.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testfile.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testfile.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -367,9 +384,9 @@ testfile: testfile.o libcups.a # testgetdests (dependency on static CUPS library is intentional) # -testgetdests: testgetdests.o libcups.a +testgetdests: testgetdests.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testgetdests.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testgetdests.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -377,9 +394,9 @@ testgetdests: testgetdests.o libcups.a # testhttp (dependency on static CUPS library is intentional) # -testhttp: testhttp.o libcups.a +testhttp: testhttp.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testhttp.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testhttp.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -387,9 +404,9 @@ testhttp: testhttp.o libcups.a # testipp (dependency on static CUPS library is intentional) # -testipp: testipp.o libcups.a +testipp: testipp.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testipp.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testipp.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -397,9 +414,9 @@ testipp: testipp.o libcups.a # testi18n (dependency on static CUPS library is intentional) # -testi18n: testi18n.o libcups.a +testi18n: testi18n.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testi18n.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testi18n.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -407,9 +424,9 @@ testi18n: testi18n.o libcups.a # testlang (dependency on static CUPS library is intentional) # -testlang: testlang.o libcups.a +testlang: testlang.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testlang.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testlang.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ echo Creating locale directory structure... $(RM) -r locale @@ -428,9 +445,9 @@ testlang: testlang.o libcups.a # testoptions (dependency on static CUPS library is intentional) # -testoptions: testoptions.o libcups.a +testoptions: testoptions.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testoptions.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testoptions.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -438,9 +455,9 @@ testoptions: testoptions.o libcups.a # testpwg (dependency on static CUPS library is intentional) # -testpwg: testpwg.o libcups.a test.ppd +testpwg: testpwg.o $(LIBCUPS_STATIC) test.ppd echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testpwg.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testpwg.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ echo Running PWG API tests... ./testpwg test.ppd @@ -450,9 +467,9 @@ testpwg: testpwg.o libcups.a test.ppd # testraster (dependency on static CUPS library is intentional) # -testraster: testraster.o libcups.a +testraster: testraster.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testraster.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testraster.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -460,9 +477,9 @@ testraster: testraster.o libcups.a # testtestpage (dependency on static CUPS library is intentional) # -testtestpage: testtestpage.o libcups.a +testtestpage: testtestpage.o $(LIBCUPS_STATIC) echo Compiling $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testtestpage.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testtestpage.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -470,9 +487,9 @@ testtestpage: testtestpage.o libcups.a # testthreads (dependency on static CUPS library is intentional) # -testthreads: testthreads.o libcups.a +testthreads: testthreads.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ testthreads.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ testthreads.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -480,9 +497,9 @@ testthreads: testthreads.o libcups.a # tlscheck (dependency on static CUPS library is intentional) # -tlscheck: tlscheck.o libcups.a +tlscheck: tlscheck.o $(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ tlscheck.o libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ tlscheck.o $(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ diff --git a/cups/cupspm.md b/cups/cupspm.md index d67409613..d7a50d644 100644 --- a/cups/cupspm.md +++ b/cups/cupspm.md @@ -94,8 +94,8 @@ Click *Next* and enter a name for the project, for example "firstcups". Click *Next* and choose a project directory. The click *Next* to create the project. In the project window, click on the *Build Phases* group and expand the -*Link Binary with Libraries* section. Click *+*, type "libcups" to show the -library, and then double-click on `libcups.tbd`. +*Link Binary with Libraries* section. Click *+*, choose "Other...", and then +find and choose the `libcups3.dylib` file in `/usr/local/lib`. Finally, click on the `main.c` file in the sidebar and copy the example program to the file. Build and run (CMD+R) to see the list of destinations. @@ -107,7 +107,7 @@ From the command-line, create a file called `simple.c` using your favorite editor, copy the example to this file, and save. Then run the following command to compile it with GCC and run it: - gcc -o simple `pkg-config --cflags cups` simple.c `pkg-config --libs cups` + gcc -o simple `pkg-config --cflags cups3` simple.c `pkg-config --libs cups3` ./simple The `pkg-config` command provides the compiler flags diff --git a/cups/dest.c b/cups/dest.c index 8cb68438d..3fcc9d738 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -25,19 +25,7 @@ # include #endif // !_WIN32 -#ifdef HAVE_MDNSRESPONDER -# include -#endif /* HAVE_MDNSRESPONDER */ - -#ifdef HAVE_AVAHI -# include -# include -# include -# include -# include -# include -#define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX -#endif /* HAVE_AVAHI */ +#include "dnssd.h" /* @@ -57,19 +45,14 @@ # define kUseLastPrinter CFSTR("UseLastPrinter") #endif /* __APPLE__ */ -#ifdef HAVE_DNSSD -# define _CUPS_DNSSD_GET_DESTS 250 /* Milliseconds for cupsGetDests */ -# define _CUPS_DNSSD_MAXTIME 50 /* Milliseconds for maximum quantum of time */ -#else -# define _CUPS_DNSSD_GET_DESTS 0 /* Milliseconds for cupsGetDests */ -#endif /* HAVE_DNSSD */ +#define _CUPS_DNSSD_GET_DESTS 250 /* Milliseconds for cupsGetDests */ +#define _CUPS_DNSSD_MAXTIME 50 /* Milliseconds for maximum quantum of time */ /* * Types... */ -#ifdef HAVE_DNSSD typedef enum _cups_dnssd_state_e /* Enumerated device state */ { _CUPS_DNSSD_NEW, @@ -82,14 +65,8 @@ typedef enum _cups_dnssd_state_e /* Enumerated device state */ typedef struct _cups_dnssd_data_s /* Enumeration data */ { -# ifdef HAVE_MDNSRESPONDER - DNSServiceRef main_ref; /* Main service reference */ -# else /* HAVE_AVAHI */ - AvahiSimplePoll *simple_poll; /* Polling interface */ - AvahiClient *client; /* Client information */ - bool got_data; /* Did we get data? */ - size_t browsers; /* How many browsers are running? */ -# endif /* HAVE_MDNSRESPONDER */ + cups_rwlock_t rwlock; /* Reader/writer lock */ + cups_dnssd_t *dnssd; /* DNS-SD context */ cups_dest_cb_t cb; /* Callback */ void *user_data; /* User data pointer */ cups_ptype_t type, /* Printer type filter */ @@ -104,24 +81,19 @@ typedef struct _cups_dnssd_data_s /* Enumeration data */ typedef struct _cups_dnssd_device_s /* Enumerated device */ { _cups_dnssd_state_t state; /* State of device listing */ -# ifdef HAVE_MDNSRESPONDER - DNSServiceRef ref; /* Service reference for query */ -# else /* HAVE_AVAHI */ - AvahiRecordBrowser *ref; /* Browser for query */ -# endif /* HAVE_MDNSRESPONDER */ - char *fullName, /* Full name */ + cups_dnssd_query_t *query; /* DNS-SD query request */ + char *fullname, /* Full name */ *regtype, /* Registration type */ *domain; /* Domain name */ cups_ptype_t type; /* Device registration type */ cups_dest_t dest; /* Destination record */ } _cups_dnssd_device_t; -typedef struct _cups_dnssd_resolve_s /* Data for resolving URI */ +typedef struct _cups_dnssd_resdata_s /* Data for resolving URI */ { int *cancel; /* Pointer to "cancel" variable */ struct timeval end_time; /* Ending time */ -} _cups_dnssd_resolve_t; -#endif /* HAVE_DNSSD */ +} _cups_dnssd_resdata_t; typedef struct _cups_getdata_s { @@ -154,27 +126,15 @@ static CFStringRef appleGetPrinter(CFArrayRef locations, CFStringRef network, CF #endif /* _CUPS_LOCATION_DEFAULTS */ static cups_dest_t *cups_add_dest(const char *name, const char *instance, size_t *num_dests, cups_dest_t **dests); static int cups_compare_dests(cups_dest_t *a, cups_dest_t *b); -#ifdef HAVE_DNSSD -# ifdef HAVE_MDNSRESPONDER -static void cups_dnssd_browse_cb(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context); -# else /* HAVE_AVAHI */ -static void cups_dnssd_browse_cb(AvahiServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *serviceName, const char *regtype, const char *replyDomain, AvahiLookupResultFlags flags, void *context); -static void cups_dnssd_client_cb(AvahiClient *client, AvahiClientState state, void *context); -# endif /* HAVE_MDNSRESPONDER */ +static void cups_dest_browse_cb(cups_dnssd_browse_t *browse, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *name, const char *regtype, const char *domain); static int cups_dnssd_compare_devices(_cups_dnssd_device_t *a, _cups_dnssd_device_t *b); static void cups_dnssd_free_device(_cups_dnssd_device_t *device, _cups_dnssd_data_t *data); static _cups_dnssd_device_t *cups_dnssd_get_device(_cups_dnssd_data_t *data, const char *serviceName, const char *regtype, const char *replyDomain); -# ifdef HAVE_MDNSRESPONDER -static void cups_dnssd_query_cb(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullName, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, void *context); -# else /* HAVE_AVAHI */ -static int cups_dnssd_poll_cb(struct pollfd *pollfds, unsigned int num_pollfds, int timeout, void *context); -static void cups_dnssd_query_cb(AvahiRecordBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, uint16_t rrclass, uint16_t rrtype, const void *rdata, size_t rdlen, AvahiLookupResultFlags flags, void *context); -# endif /* HAVE_MDNSRESPONDER */ -static const char *cups_dnssd_resolve(cups_dest_t *dest, const char *uri, int msec, int *cancel, cups_dest_cb_t cb, void *user_data); -static bool cups_dnssd_resolve_cb(void *context); +static void cups_dest_query_cb(cups_dnssd_query_t *query, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, uint16_t rrtype, const void *qdata, uint16_t qlen); +static const char *cups_dest_resolve(cups_dest_t *dest, const char *uri, int msec, int *cancel, cups_dest_cb_t cb, void *user_data); +static bool cups_dest_resolve_cb(void *context); static void cups_dnssd_unquote(char *dst, const char *src, size_t dstsize); static int cups_elapsed(struct timeval *t); -#endif /* HAVE_DNSSD */ static bool cups_enum_dests(http_t *http, unsigned flags, int msec, int *cancel, cups_ptype_t type, cups_ptype_t mask, cups_dest_cb_t cb, void *user_data); static size_t cups_find_dest(const char *name, const char *instance, size_t num_dests, cups_dest_t *dests, size_t prev, int *rdiff); static bool cups_get_cb(_cups_getdata_t *data, unsigned flags, cups_dest_t *dest); @@ -583,7 +543,7 @@ cupsConnectDest( { #ifdef HAVE_DNSSD if (strstr(uri, "._tcp")) - uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb, user_data); + uri = cups_dest_resolve(dest, uri, msec, cancel, cb, user_data); #endif /* HAVE_DNSSD */ } } @@ -593,7 +553,7 @@ cupsConnectDest( { #ifdef HAVE_DNSSD if (strstr(uri, "._tcp")) - uri = cups_dnssd_resolve(dest, uri, msec, cancel, cb, user_data); + uri = cups_dest_resolve(dest, uri, msec, cancel, cb, user_data); #endif /* HAVE_DNSSD */ } @@ -1009,7 +969,7 @@ _cupsGetDestResource( #ifdef HAVE_DNSSD if (((flags & CUPS_DEST_FLAGS_DEVICE) || !printer_uri) && device_uri && strstr(device_uri, "._tcp")) { - if ((device_uri = cups_dnssd_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL) + if ((device_uri = cups_dest_resolve(dest, device_uri, 5000, NULL, NULL, NULL)) != NULL) { DEBUG_printf(("1_cupsGetDestResource: Resolved device-uri=\"%s\".", device_uri)); } @@ -2382,34 +2342,31 @@ cups_compare_dests(cups_dest_t *a, /* I - First destination */ } -#ifdef HAVE_DNSSD -# ifdef HAVE_MDNSRESPONDER /* - * 'cups_dnssd_browse_cb()' - Browse for printers. + * 'cups_dest_browse_cb()' - Browse for printers. */ static void -cups_dnssd_browse_cb( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Option flags */ - uint32_t interfaceIndex, /* I - Interface number */ - DNSServiceErrorType errorCode, /* I - Error, if any */ +cups_dest_browse_cb( + cups_dnssd_browse_t *browse, /* I - DNS-SD browser */ + void *context, /* I - Enumeration data */ + cups_dnssd_flags_t flags, /* I - Flags */ + uint32_t if_index, /* I - Interface */ const char *serviceName, /* I - Name of service/device */ const char *regtype, /* I - Type of service */ - const char *replyDomain, /* I - Service domain */ - void *context) /* I - Enumeration data */ + const char *replyDomain) /* I - Service domain */ { _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; /* Enumeration data */ - DEBUG_printf(("5cups_dnssd_browse_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\", context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, serviceName, regtype, replyDomain, context)); + DEBUG_printf(("5cups_dest_browse_cb(browse=%p, context=%p, flags=%x, if_index=%d, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\")", (void *)browse, context, flags, if_index, serviceName, regtype, replyDomain)); /* - * Don't do anything on error... + * Don't do anything on error, only add services... */ - if (errorCode != kDNSServiceErr_NoError) + if ((flags & CUPS_DNSSD_FLAGS_ERROR) || !(flags & CUPS_DNSSD_FLAGS_ADD)) return; /* @@ -2418,97 +2375,6 @@ cups_dnssd_browse_cb( cups_dnssd_get_device(data, serviceName, regtype, replyDomain); } - - -# else /* HAVE_AVAHI */ -/* - * 'cups_dnssd_browse_cb()' - Browse for printers. - */ - -static void -cups_dnssd_browse_cb( - AvahiServiceBrowser *browser, /* I - Browser */ - AvahiIfIndex interface, /* I - Interface index (unused) */ - AvahiProtocol protocol, /* I - Network protocol (unused) */ - AvahiBrowserEvent event, /* I - What happened */ - const char *name, /* I - Service name */ - const char *type, /* I - Registration type */ - const char *domain, /* I - Domain */ - AvahiLookupResultFlags flags, /* I - Flags */ - void *context) /* I - Devices array */ -{ -#ifdef DEBUG - AvahiClient *client = avahi_service_browser_get_client(browser); - /* Client information */ -#endif /* DEBUG */ - _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; - /* Enumeration data */ - - - (void)interface; - (void)protocol; - (void)context; - - DEBUG_printf(("cups_dnssd_browse_cb(..., name=\"%s\", type=\"%s\", domain=\"%s\", ...);", name, type, domain)); - - switch (event) - { - case AVAHI_BROWSER_FAILURE: - DEBUG_printf(("cups_dnssd_browse_cb: %s", avahi_strerror(avahi_client_errno(client)))); - avahi_simple_poll_quit(data->simple_poll); - break; - - case AVAHI_BROWSER_NEW: - /* - * This object is new on the network. - */ - - cups_dnssd_get_device(data, name, type, domain); - break; - - case AVAHI_BROWSER_REMOVE : - case AVAHI_BROWSER_CACHE_EXHAUSTED : - break; - - case AVAHI_BROWSER_ALL_FOR_NOW : - DEBUG_puts("cups_dnssd_browse_cb: ALL_FOR_NOW"); - data->browsers --; - break; - } -} - - -/* - * 'cups_dnssd_client_cb()' - Avahi client callback function. - */ - -static void -cups_dnssd_client_cb( - AvahiClient *client, /* I - Client information (unused) */ - AvahiClientState state, /* I - Current state */ - void *context) /* I - User data (unused) */ -{ - _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; - /* Enumeration data */ - - - (void)client; - - DEBUG_printf(("cups_dnssd_client_cb(client=%p, state=%d, context=%p)", client, state, context)); - - /* - * If the connection drops, quit. - */ - - if (state == AVAHI_CLIENT_FAILURE) - { - DEBUG_puts("cups_dnssd_client_cb: Avahi connection failed."); - avahi_simple_poll_quit(data->simple_poll); - } -} -# endif /* HAVE_MDNSRESPONDER */ - - /* * 'cups_dnssd_compare_device()' - Compare two devices. */ @@ -2533,16 +2399,8 @@ cups_dnssd_free_device( { DEBUG_printf(("5cups_dnssd_free_device(device=%p(%s), data=%p)", (void *)device, device->dest.name, (void *)data)); -# ifdef HAVE_MDNSRESPONDER - if (device->ref) - DNSServiceRefDeallocate(device->ref); -# else /* HAVE_AVAHI */ - if (device->ref) - avahi_record_browser_free(device->ref); -# endif /* HAVE_MDNSRESPONDER */ - _cupsStrFree(device->domain); - _cupsStrFree(device->fullName); + _cupsStrFree(device->fullname); _cupsStrFree(device->regtype); _cupsStrFree(device->dest.name); @@ -2565,8 +2423,7 @@ cups_dnssd_get_device( { _cups_dnssd_device_t key, /* Search key */ *device; /* Device */ - char fullName[kDNSServiceMaxDomainName], - /* Full name for query */ + char fullname[1024], /* Full name for query */ name[128]; /* Queue name */ @@ -2580,7 +2437,13 @@ cups_dnssd_get_device( key.dest.name = name; - if ((device = cupsArrayFind(data->devices, &key)) != NULL) + cupsRWLockRead(&data->rwlock); + + device = cupsArrayFind(data->devices, &key); + + cupsRWUnlock(&data->rwlock); + + if (device) { /* * Yes, see if we need to do anything with this... @@ -2588,8 +2451,7 @@ cups_dnssd_get_device( int update = 0; /* Non-zero if we need to update */ - if (!_cups_strcasecmp(replyDomain, "local.") && - _cups_strcasecmp(device->domain, replyDomain)) + if (!_cups_strcasecmp(replyDomain, "local.") && _cups_strcasecmp(device->domain, replyDomain)) { /* * Update the "global" listing to use the .local domain name instead. @@ -2604,8 +2466,7 @@ cups_dnssd_get_device( update = 1; } - if (!_cups_strcasecmp(regtype, "_ipps._tcp") && - _cups_strcasecmp(device->regtype, regtype)) + if (!_cups_strcasecmp(regtype, "_ipps._tcp") && _cups_strcasecmp(device->regtype, regtype)) { /* * Prefer IPPS over IPP. @@ -2647,32 +2508,21 @@ cups_dnssd_get_device( device->dest.num_options = cupsAddOption("printer-info", serviceName, 0, &device->dest.options); + cupsRWLockWrite(&data->rwlock); cupsArrayAdd(data->devices, device); + cupsRWUnlock(&data->rwlock); } /* * Set the "full name" of this service, which is used for queries... */ -# ifdef HAVE_MDNSRESPONDER - DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain); -# else /* HAVE_AVAHI */ - avahi_service_name_join(fullName, kDNSServiceMaxDomainName, serviceName, regtype, replyDomain); -# endif /* HAVE_MDNSRESPONDER */ - - _cupsStrFree(device->fullName); - device->fullName = _cupsStrAlloc(fullName); + cupsDNSSDAssembleFullName(fullname, sizeof(fullname), serviceName, regtype, replyDomain); + _cupsStrFree(device->fullname); + device->fullname = _cupsStrAlloc(fullname); - if (device->ref) - { -# ifdef HAVE_MDNSRESPONDER - DNSServiceRefDeallocate(device->ref); -# else /* HAVE_AVAHI */ - avahi_record_browser_free(device->ref); -# endif /* HAVE_MDNSRESPONDER */ - - device->ref = 0; - } + cupsDNSSDQueryDelete(device->query); + device->query = NULL; if (device->state == _CUPS_DNSSD_ACTIVE) { @@ -2686,87 +2536,21 @@ cups_dnssd_get_device( } -# ifdef HAVE_AVAHI -/* - * 'cups_dnssd_poll_cb()' - Wait for input on the specified file descriptors. - * - * Note: This function is needed because avahi_simple_poll_iterate is broken - * and always uses a timeout of 0 (!) milliseconds. - * (https://github.com/lathiat/avahi/issues/127) - * - * @private@ - */ - -static int /* O - Number of file descriptors matching */ -cups_dnssd_poll_cb( - struct pollfd *pollfds, /* I - File descriptors */ - unsigned int num_pollfds, /* I - Number of file descriptors */ - int timeout, /* I - Timeout in milliseconds (unused) */ - void *context) /* I - User data (unused) */ -{ - _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; - /* Enumeration data */ - int val; /* Return value */ - - - DEBUG_printf(("cups_dnssd_poll_cb(pollfds=%p, num_pollfds=%d, timeout=%d, context=%p)", pollfds, num_pollfds, timeout, context)); - - (void)timeout; - - val = poll(pollfds, num_pollfds, _CUPS_DNSSD_MAXTIME); - - DEBUG_printf(("cups_dnssd_poll_cb: poll() returned %d", val)); - - if (val < 0) - { - DEBUG_printf(("cups_dnssd_poll_cb: %s", strerror(errno))); - } - else if (val > 0) - { - data->got_data = true; - } - - return (val); -} -# endif /* HAVE_AVAHI */ - - /* - * 'cups_dnssd_query_cb()' - Process query data. + * 'cups_dest_query_cb()' - Process query data. */ static void -cups_dnssd_query_cb( -# ifdef HAVE_MDNSRESPONDER - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Data flags */ - uint32_t interfaceIndex, /* I - Interface */ - DNSServiceErrorType errorCode, /* I - Error, if any */ - const char *fullName, /* I - Full service name */ +cups_dest_query_cb( + cups_dnssd_query_t *query, /* I - Query request */ + void *context, /* I - Enumeration data */ + cups_dnssd_flags_t flags, /* I - DNS-SD flags */ + uint32_t if_index, /* I - Interface */ + const char *fullname, /* I - Full service name */ uint16_t rrtype, /* I - Record type */ - uint16_t rrclass, /* I - Record class */ - uint16_t rdlen, /* I - Length of record data */ const void *rdata, /* I - Record data */ - uint32_t ttl, /* I - Time-to-live */ -# else /* HAVE_AVAHI */ - AvahiRecordBrowser *browser, /* I - Record browser */ - AvahiIfIndex interfaceIndex, - /* I - Interface index (unused) */ - AvahiProtocol protocol, /* I - Network protocol (unused) */ - AvahiBrowserEvent event, /* I - What happened? */ - const char *fullName, /* I - Service name */ - uint16_t rrclass, /* I - Record class */ - uint16_t rrtype, /* I - Record type */ - const void *rdata, /* I - TXT record */ - size_t rdlen, /* I - Length of TXT record */ - AvahiLookupResultFlags flags, /* I - Flags */ -# endif /* HAVE_MDNSRESPONDER */ - void *context) /* I - Enumeration data */ + uint16_t rdlen) /* I - Length of record data */ { -# if defined(DEBUG) && defined(HAVE_AVAHI) - AvahiClient *client = avahi_record_browser_get_client(browser); - /* Client information */ -# endif /* DEBUG && HAVE_AVAHI */ _cups_dnssd_data_t *data = (_cups_dnssd_data_t *)context; /* Enumeration data */ char serviceName[256],/* Service name */ @@ -2776,37 +2560,22 @@ cups_dnssd_query_cb( *device; /* Device */ -# ifdef HAVE_MDNSRESPONDER - DEBUG_printf(("5cups_dnssd_query_cb(sdRef=%p, flags=%x, interfaceIndex=%d, errorCode=%d, fullName=\"%s\", rrtype=%u, rrclass=%u, rdlen=%u, rdata=%p, ttl=%u, context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, fullName, rrtype, rrclass, rdlen, rdata, ttl, context)); - - /* - * Only process "add" data... - */ - - if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) - return; - -# else /* HAVE_AVAHI */ - DEBUG_printf(("cups_dnssd_query_cb(browser=%p, interfaceIndex=%d, protocol=%d, event=%d, fullName=\"%s\", rrclass=%u, rrtype=%u, rdata=%p, rdlen=%u, flags=%x, context=%p)", browser, interfaceIndex, protocol, event, fullName, rrclass, rrtype, rdata, (unsigned)rdlen, flags, context)); + (void)query; + (void)if_index; + (void)rrtype; /* * Only process "add" data... */ - if (event != AVAHI_BROWSER_NEW) - { - if (event == AVAHI_BROWSER_FAILURE) - DEBUG_printf(("cups_dnssd_query_cb: %s", avahi_strerror(avahi_client_errno(client)))); - + if (!(flags & CUPS_DNSSD_FLAGS_ADD) || (flags & CUPS_DNSSD_FLAGS_ERROR)) return; - } -# endif /* HAVE_MDNSRESPONDER */ /* * Lookup the service in the devices array. */ - cups_dnssd_unquote(serviceName, fullName, sizeof(serviceName)); + cups_dnssd_unquote(serviceName, fullname, sizeof(serviceName)); if ((ptr = strstr(serviceName, "._")) != NULL) *ptr = '\0'; @@ -2871,11 +2640,11 @@ cups_dnssd_query_cb( memcpy(value, txt, (size_t)(txtnext - txt)); value[txtnext - txt] = '\0'; - DEBUG_printf(("6cups_dnssd_query_cb: %s=%s", key, value)); + DEBUG_printf(("6cups_dest_query_cb: %s=%s", key, value)); } else { - DEBUG_printf(("6cups_dnssd_query_cb: '%s' with no value.", key)); + DEBUG_printf(("6cups_dest_query_cb: '%s' with no value.", key)); continue; } @@ -3025,7 +2794,7 @@ cups_dnssd_query_cb( * Save the URI... */ - cups_dnssd_unquote(uriname, device->fullName, sizeof(uriname)); + cups_dnssd_unquote(uriname, device->fullname, sizeof(uriname)); httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), !strcmp(device->regtype, "_ipps._tcp") ? "ipps" : "ipp", NULL, uriname, 0, saw_printer_type ? "/cups" : "/"); @@ -3036,16 +2805,16 @@ cups_dnssd_query_cb( } else DEBUG_printf(("6cups_dnssd_query: Ignoring TXT record for '%s'.", - fullName)); + fullname)); } /* - * 'cups_dnssd_resolve()' - Resolve a Bonjour printer URI. + * 'cups_dest_resolve()' - Resolve a Bonjour printer URI. */ static const char * /* O - Resolved URI or NULL */ -cups_dnssd_resolve( +cups_dest_resolve( cups_dest_t *dest, /* I - Destination */ const char *uri, /* I - Current printer URI */ int msec, /* I - Time in milliseconds */ @@ -3054,7 +2823,7 @@ cups_dnssd_resolve( void *user_data) /* I - User data for callback */ { char tempuri[1024]; /* Temporary URI buffer */ - _cups_dnssd_resolve_t resolve; /* Resolve data */ + _cups_dnssd_resdata_t resolve; /* Resolve data */ /* @@ -3080,7 +2849,7 @@ cups_dnssd_resolve( if (cb) (*cb)(user_data, CUPS_DEST_FLAGS_UNCONNECTED | CUPS_DEST_FLAGS_RESOLVING, dest); - if ((uri = httpResolveURI(uri, tempuri, sizeof(tempuri), HTTP_RESOLVE_DEFAULT, cups_dnssd_resolve_cb, &resolve)) == NULL) + if ((uri = httpResolveURI(uri, tempuri, sizeof(tempuri), HTTP_RESOLVE_DEFAULT, cups_dest_resolve_cb, &resolve)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to resolve printer-uri."), 1); @@ -3101,13 +2870,13 @@ cups_dnssd_resolve( /* - * 'cups_dnssd_resolve_cb()' - See if we should continue resolving. + * 'cups_dest_resolve_cb()' - See if we should continue resolving. */ static bool /* O - `true` to continue, `false` to stop */ -cups_dnssd_resolve_cb(void *context) /* I - Resolve data */ +cups_dest_resolve_cb(void *context) /* I - Resolve data */ { - _cups_dnssd_resolve_t *resolve = (_cups_dnssd_resolve_t *)context; + _cups_dnssd_resdata_t *resolve = (_cups_dnssd_resdata_t *)context; /* Resolve data */ struct timeval curtime; /* Current time */ @@ -3118,7 +2887,7 @@ cups_dnssd_resolve_cb(void *context) /* I - Resolve data */ if (resolve->cancel && *(resolve->cancel)) { - DEBUG_puts("4cups_dnssd_resolve_cb: Canceled."); + DEBUG_puts("4cups_dest_resolve_cb: Canceled."); return (false); } @@ -3128,7 +2897,7 @@ cups_dnssd_resolve_cb(void *context) /* I - Resolve data */ gettimeofday(&curtime, NULL); - DEBUG_printf(("4cups_dnssd_resolve_cb: curtime=%d.%06d, end_time=%d.%06d", (int)curtime.tv_sec, (int)curtime.tv_usec, (int)resolve->end_time.tv_sec, (int)resolve->end_time.tv_usec)); + DEBUG_printf(("4cups_dest_resolve_cb: curtime=%d.%06d, end_time=%d.%06d", (int)curtime.tv_sec, (int)curtime.tv_usec, (int)resolve->end_time.tv_sec, (int)resolve->end_time.tv_usec)); return (curtime.tv_sec < resolve->end_time.tv_sec || (curtime.tv_sec == resolve->end_time.tv_sec && curtime.tv_usec < resolve->end_time.tv_usec)); } @@ -3187,7 +2956,6 @@ cups_elapsed(struct timeval *t) /* IO - Previous time */ return (msecs); } -#endif /* HAVE_DNSSD */ /* @@ -3206,36 +2974,19 @@ cups_enum_dests( void *user_data) /* I - User data */ { size_t i, j, k, /* Looping vars */ - num_dests; /* Number of destinations */ + num_dests, /* Number of destinations */ + num_devices; /* Number of devices */ cups_dest_t *dests = NULL, /* Destinations */ *dest; /* Current destination */ cups_option_t *option; /* Current option */ const char *user_default; /* Default printer from environment */ -#ifdef HAVE_DNSSD size_t count, /* Number of queries started */ completed; /* Number of completed queries */ int remaining; /* Remainder of timeout */ struct timeval curtime; /* Current time */ _cups_dnssd_data_t data; /* Data for callback */ _cups_dnssd_device_t *device; /* Current device */ -# ifdef HAVE_MDNSRESPONDER - int nfds, /* Number of files responded */ - main_fd; /* File descriptor for lookups */ - DNSServiceRef ipp_ref = NULL; /* IPP browser */ -# ifdef HAVE_TLS - DNSServiceRef ipps_ref = NULL; /* IPPS browser */ -# endif /* HAVE_TLS */ - struct pollfd pfd; /* Polling data */ -# else /* HAVE_AVAHI */ - int error; /* Error value */ - AvahiServiceBrowser *ipp_ref = NULL; /* IPP browser */ -# ifdef HAVE_TLS - AvahiServiceBrowser *ipps_ref = NULL; /* IPPS browser */ -# endif /* HAVE_TLS */ -# endif /* HAVE_MDNSRESPONDER */ -#else - _cups_getdata_t data; /* Data for callback */ -#endif /* HAVE_DNSSD */ + cups_dnssd_t *dnssd = NULL; /* DNS-SD context */ char filename[1024]; /* Local lpoptions file */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ @@ -3311,13 +3062,13 @@ cups_enum_dests( * Get ready to enumerate... */ -#ifdef HAVE_DNSSD + cupsRWInit(&data.rwlock); + data.type = type; data.mask = mask; data.cb = cb; data.user_data = user_data; data.devices = cupsArrayNew((cups_array_cb_t)cups_dnssd_compare_devices, NULL, NULL, 0, NULL, (cups_afree_cb_t)cups_dnssd_free_device); -#endif /* HAVE_DNSSD */ if (!(mask & CUPS_PRINTER_DISCOVERED) || !(type & CUPS_PRINTER_DISCOVERED)) { @@ -3343,9 +3094,7 @@ cups_enum_dests( for (i = num_dests, dest = dests; i > 0 && (!cancel || !*cancel); i --, dest ++) { cups_dest_t *user_dest; /* Destination from lpoptions */ -#ifdef HAVE_DNSSD const char *device_uri; /* Device URI */ -#endif /* HAVE_DNSSD */ if ((user_dest = cupsGetDest(dest->name, NULL, data.num_dests, data.dests)) != NULL) { @@ -3374,7 +3123,6 @@ cups_enum_dests( else if (!(*cb)(user_data, i > 1 ? CUPS_DEST_FLAGS_MORE : CUPS_DEST_FLAGS_NONE, dest)) break; -#ifdef HAVE_DNSSD if (!dest->instance && (device_uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL && !strncmp(device_uri, "dnssd://", 8)) { /* @@ -3406,7 +3154,6 @@ cups_enum_dests( } } } -#endif /* HAVE_DNSSD */ } cupsFreeDests(num_dests, dests); @@ -3422,15 +3169,13 @@ cups_enum_dests( if ((mask & CUPS_PRINTER_DISCOVERED) && !(type & CUPS_PRINTER_DISCOVERED)) goto enum_finished; -#ifdef HAVE_DNSSD /* - * Get Bonjour-shared printers... + * Get DNS-SD printers... */ gettimeofday(&curtime, NULL); -# ifdef HAVE_MDNSRESPONDER - if (DNSServiceCreateConnection(&data.main_ref) != kDNSServiceErr_NoError) + if ((dnssd = cupsDNSSDNew(NULL, NULL)) == NULL) { DEBUG_puts("1cups_enum_dests: Unable to create service browser, returning 0."); @@ -3440,13 +3185,10 @@ cups_enum_dests( return (false); } - main_fd = DNSServiceRefSockFD(data.main_ref); - - ipp_ref = data.main_ref; - if (DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError) + if (!cupsDNSSDBrowseNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "_ipp._tcp", /*domain*/NULL, cups_dest_browse_cb, &data)) { DEBUG_puts("1cups_enum_dests: Unable to create IPP browser, returning 0."); - DNSServiceRefDeallocate(data.main_ref); + cupsDNSSDDelete(dnssd); cupsFreeDests(data.num_dests, data.dests); cupsArrayDelete(data.devices); @@ -3454,76 +3196,16 @@ cups_enum_dests( return (false); } -# ifdef HAVE_TLS - ipps_ref = data.main_ref; - if (DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, (DNSServiceBrowseReply)cups_dnssd_browse_cb, &data) != kDNSServiceErr_NoError) + if (!cupsDNSSDBrowseNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "_ipps._tcp", /*domain*/NULL, cups_dest_browse_cb, &data)) { DEBUG_puts("1cups_enum_dests: Unable to create IPPS browser, returning 0."); - DNSServiceRefDeallocate(data.main_ref); + cupsDNSSDDelete(dnssd); cupsFreeDests(data.num_dests, data.dests); cupsArrayDelete(data.devices); return (false); } -# endif /* HAVE_TLS */ - -# else /* HAVE_AVAHI */ - if ((data.simple_poll = avahi_simple_poll_new()) == NULL) - { - DEBUG_puts("1cups_enum_dests: Unable to create Avahi poll, returning 0."); - - cupsFreeDests(data.num_dests, data.dests); - cupsArrayDelete(data.devices); - - return (false); - } - - avahi_simple_poll_set_func(data.simple_poll, cups_dnssd_poll_cb, &data); - - data.client = avahi_client_new(avahi_simple_poll_get(data.simple_poll), 0, cups_dnssd_client_cb, &data, &error); - if (!data.client) - { - DEBUG_puts("1cups_enum_dests: Unable to create Avahi client, returning 0."); - avahi_simple_poll_free(data.simple_poll); - - cupsFreeDests(data.num_dests, data.dests); - cupsArrayDelete(data.devices); - - return (false); - } - - data.browsers = 1; - if ((ipp_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL) - { - DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPP browser, returning 0."); - - avahi_client_free(data.client); - avahi_simple_poll_free(data.simple_poll); - - cupsFreeDests(data.num_dests, data.dests); - cupsArrayDelete(data.devices); - - return (false); - } - -# ifdef HAVE_TLS - data.browsers ++; - if ((ipps_ref = avahi_service_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, cups_dnssd_browse_cb, &data)) == NULL) - { - DEBUG_puts("1cups_enum_dests: Unable to create Avahi IPPS browser, returning 0."); - - avahi_service_browser_free(ipp_ref); - avahi_client_free(data.client); - avahi_simple_poll_free(data.simple_poll); - - cupsFreeDests(data.num_dests, data.dests); - cupsArrayDelete(data.devices); - - return (false); - } -# endif /* HAVE_TLS */ -# endif /* HAVE_MDNSRESPONDER */ if (msec < 0) remaining = INT_MAX; @@ -3540,87 +3222,40 @@ cups_enum_dests( cups_elapsed(&curtime); -# ifdef HAVE_MDNSRESPONDER - pfd.fd = main_fd; - pfd.events = POLLIN; - - if ((nfds = poll(&pfd, 1, remaining > _CUPS_DNSSD_MAXTIME ? _CUPS_DNSSD_MAXTIME : remaining)) > 0) - DNSServiceProcessResult(data.main_ref); -# ifdef _WIN32 - else if (nfds < 0 && WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK) - break; -# else - else if (nfds < 0 && errno != EINTR && errno != EAGAIN) - break; -# endif /* _WIN32 */ + remaining -= cups_elapsed(&curtime); -# else /* HAVE_AVAHI */ - data.got_data = false; + cupsRWLockRead(&data.rwlock); - if ((error = avahi_simple_poll_iterate(data.simple_poll, _CUPS_DNSSD_MAXTIME)) > 0) + for (i = 0, num_devices = cupsArrayGetCount(data.devices), count = 0, completed = 0; i < num_devices; i ++) { - /* - * We've been told to exit the loop. Perhaps the connection to - * Avahi failed. - */ - - break; - } - - DEBUG_printf(("1cups_enum_dests: got_data=%s", data.got_data ? "true" : "false")); -# endif /* HAVE_MDNSRESPONDER */ - - remaining -= cups_elapsed(&curtime); + device = cupsArrayGetElement(data.devices, i); - for (device = (_cups_dnssd_device_t *)cupsArrayGetFirst(data.devices), - count = 0, completed = 0; - device; - device = (_cups_dnssd_device_t *)cupsArrayGetNext(data.devices)) - { - if (device->ref) + if (device->query) count ++; if (device->state == _CUPS_DNSSD_ACTIVE) completed ++; - if (!device->ref && device->state == _CUPS_DNSSD_NEW) + if (!device->query && device->state == _CUPS_DNSSD_NEW) { - DEBUG_printf(("1cups_enum_dests: Querying '%s'.", device->fullName)); - -# ifdef HAVE_MDNSRESPONDER - device->ref = data.main_ref; + DEBUG_printf(("1cups_enum_dests: Querying '%s'.", device->fullname)); - if (DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, (DNSServiceQueryRecordReply)cups_dnssd_query_cb, &data) == kDNSServiceErr_NoError) + if ((device->query = cupsDNSSDQueryNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, device->fullname, CUPS_DNSSD_RRTYPE_TXT, cups_dest_query_cb, &data)) != NULL) { count ++; } else { - device->ref = 0; device->state = _CUPS_DNSSD_ERROR; DEBUG_puts("1cups_enum_dests: Query failed."); } - -# else /* HAVE_AVAHI */ - if ((device->ref = avahi_record_browser_new(data.client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, cups_dnssd_query_cb, &data)) != NULL) - { - DEBUG_printf(("1cups_enum_dests: Query ref=%p", device->ref)); - count ++; - } - else - { - device->state = _CUPS_DNSSD_ERROR; - - DEBUG_printf(("1cups_enum_dests: Query failed: %s", avahi_strerror(avahi_client_errno(data.client)))); - } -# endif /* HAVE_MDNSRESPONDER */ } - else if (device->ref && device->state == _CUPS_DNSSD_PENDING) + else if (device->query && device->state == _CUPS_DNSSD_PENDING) { completed ++; - DEBUG_printf(("1cups_enum_dests: Query for \"%s\" is complete.", device->fullName)); + DEBUG_printf(("1cups_enum_dests: Query for \"%s\" is complete.", device->fullname)); if ((device->type & mask) == type) { @@ -3676,19 +3311,15 @@ cups_enum_dests( } } -# ifdef HAVE_AVAHI - DEBUG_printf(("1cups_enum_dests: remaining=%d, browsers=%u, completed=%u, count=%u, devices count=%u", remaining, (unsigned)data.browsers, (unsigned)completed, (unsigned)count, (unsigned)cupsArrayGetCount(data.devices))); - - if (data.browsers == 0 && completed == cupsArrayGetCount(data.devices)) - break; -# else DEBUG_printf(("1cups_enum_dests: remaining=%d, completed=%u, count=%u, devices count=%u", remaining, (unsigned)completed, (unsigned)count, (unsigned)cupsArrayGetCount(data.devices))); - if (completed == cupsArrayGetCount(data.devices)) + cupsRWUnlock(&data.rwlock); + + if (completed && completed == cupsArrayGetCount(data.devices)) break; -# endif /* HAVE_AVAHI */ + + usleep(100000); } -#endif /* HAVE_DNSSD */ /* * Return... @@ -3696,39 +3327,12 @@ cups_enum_dests( enum_finished: - cupsFreeDests(data.num_dests, data.dests); + cupsDNSSDDelete(dnssd); -#ifdef HAVE_DNSSD + cupsFreeDests(data.num_dests, data.dests); cupsArrayDelete(data.devices); -# ifdef HAVE_MDNSRESPONDER - if (ipp_ref) - DNSServiceRefDeallocate(ipp_ref); - -# ifdef HAVE_TLS - if (ipps_ref) - DNSServiceRefDeallocate(ipps_ref); -# endif /* HAVE_TLS */ - - if (data.main_ref) - DNSServiceRefDeallocate(data.main_ref); - -# else /* HAVE_AVAHI */ - if (ipp_ref) - avahi_service_browser_free(ipp_ref); -# ifdef HAVE_TLS - if (ipps_ref) - avahi_service_browser_free(ipps_ref); -# endif /* HAVE_TLS */ - - if (data.client) - avahi_client_free(data.client); - if (data.simple_poll) - avahi_simple_poll_free(data.simple_poll); -# endif /* HAVE_MDNSRESPONDER */ -#endif /* HAVE_DNSSD */ - - DEBUG_puts("1cups_enum_dests: Returning 1."); + DEBUG_puts("1cups_enum_dests: Returning true."); return (true); } diff --git a/cups/dnssd.c b/cups/dnssd.c new file mode 100644 index 000000000..ea44e7b9e --- /dev/null +++ b/cups/dnssd.c @@ -0,0 +1,2011 @@ +// +// DNS-SD API functions for CUPS. +// +// Copyright © 2022 by OpenPrinting. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#include +#include "cups-private.h" +#include "dnssd.h" +#include "debug-internal.h" + +#ifdef __APPLE__ +# include +# include +# include +#endif // __APPLE__ + +#ifdef HAVE_MDNSRESPONDER +# include +# include +#elif _WIN32 +# include +#else // HAVE_AVAHI +# include +# include +# include +# include +# include +# include +# include +# include +# define AVAHI_DNS_TYPE_LOC 29 // Per RFC 1876 +#endif // HAVE_MDNSRESPONDER + + +// +// Private structures... +// + +struct _cups_dnssd_s // DNS-SD context +{ + cups_mutex_t mutex; // Mutex for context + size_t config_changes; // Number of hostname/network changes + cups_dnssd_error_cb_t cb; // Error callback function + void *cb_data; // Error callback data + cups_array_t *browses, // Browse requests + *queries, // Query requests + *resolves, // Resolve requests + *services; // Registered services + +#ifdef __APPLE__ + SCDynamicStoreRef sc; // Dyanmic store context for host info +#endif // __APPLE__ + +#ifdef HAVE_MDNSRESPONDER + DNSServiceRef ref; // Master service reference + cups_thread_t monitor; // Monitoring thread + +#elif _WIN32 + +#else // HAVE_AVAHI + AvahiClient *client; // Avahi client connection + AvahiSimplePoll *poll; // Avahi poll class + cups_thread_t monitor; // Monitoring thread +#endif // HAVE_MDNSRESPONDER +}; + +struct _cups_dnssd_browse_s // DNS-SD browse request +{ + cups_dnssd_t *dnssd; // DNS-SD context + cups_dnssd_browse_cb_t cb; // Browse callback + void *cb_data; // Browse callback data + +#ifdef HAVE_MDNSRESPONDER + DNSServiceRef ref; // Browse reference +#elif _WIN32 +#else // HAVE_AVAHI + AvahiServiceBrowser *browser; // Browser +#endif // HAVE_MDNSRESPONDER +}; + +struct _cups_dnssd_query_s // DNS-SD query request +{ + cups_dnssd_t *dnssd; // DNS-SD context + cups_dnssd_query_cb_t cb; // Query callback + void *cb_data; // Query callback data + +#ifdef HAVE_MDNSRESPONDER + DNSServiceRef ref; // Query reference +#elif _WIN32 +#else // HAVE_AVAHI + AvahiRecordBrowser *browser; // Browser +#endif // HAVE_MDNSRESPONDER +}; + +struct _cups_dnssd_resolve_s // DNS-SD resolve request +{ + cups_dnssd_t *dnssd; // DNS-SD context + cups_dnssd_resolve_cb_t cb; // Resolve callback + void *cb_data; // Resolve callback data + +#ifdef HAVE_MDNSRESPONDER + DNSServiceRef ref; // Resolve reference +#elif _WIN32 +#else // HAVE_AVAHI + AvahiServiceResolver *resolver; // Resolver +#endif // HAVE_MDNSRESPONDER +}; + +struct _cups_dnssd_service_s // DNS-SD service registration +{ + cups_dnssd_t *dnssd; // DNS-SD context + char *name; // Service name + uint32_t if_index; // Interface index + cups_dnssd_service_cb_t cb; // Service callback + void *cb_data; // Service callback data + unsigned char loc[16]; // LOC record data + bool loc_set; // Is the location data set? + +#ifdef HAVE_MDNSRESPONDER + size_t num_refs; // Number of service references + DNSServiceRef refs[16]; // Service references + DNSRecordRef loc_refs[16]; // Service location records +#elif _WIN32 +#else // HAVE_AVAHI + AvahiEntryGroup *group; // Group of services under this name +#endif // HAVE_MDNSRESPONDER +}; + + +// +// Local functions... +// + +static void delete_browse(cups_dnssd_browse_t *browse); +static void delete_query(cups_dnssd_query_t *query); +static void delete_resolve(cups_dnssd_resolve_t *resolve); +static void delete_service(cups_dnssd_service_t *service); +static void record_config_change(cups_dnssd_t *dnssd, cups_dnssd_flags_t flags); +static void report_error(cups_dnssd_t *dnssd, const char *message, ...) _CUPS_FORMAT(2,3); + +#ifdef __APPLE__ +static void apple_sc_cb(SCDynamicStoreRef sc, CFArrayRef changed, cups_dnssd_t *dnssd); +#endif // __APPLE__ + +#ifdef HAVE_MDNSRESPONDER +static void *mdns_monitor(cups_dnssd_t *dnssd); +static void mdns_browse_cb(DNSServiceRef ref, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType error, const char *name, const char *regtype, const char *domain, cups_dnssd_browse_t *browse); +static void mdns_query_cb(DNSServiceRef ref, DNSServiceFlags flags, uint32_t if_index, DNSServiceErrorType error, const char *name, uint16_t rrtype, uint16_t rrclass, uint16_t rdlen, const void *rdata, uint32_t ttl, cups_dnssd_query_t *query); +static void mdns_resolve_cb(DNSServiceRef ref, DNSServiceFlags flags, uint32_t if_index, DNSServiceErrorType error, const char *fullname, const char *host, uint16_t port, uint16_t txtlen, const unsigned char *txt, cups_dnssd_resolve_t *resolve); +static void mdns_service_cb(DNSServiceRef ref, DNSServiceFlags flags, DNSServiceErrorType error, const char *name, const char *regtype, const char *domain, cups_dnssd_service_t *service); +static const char *mdns_strerror(DNSServiceErrorType errorCode); +static cups_dnssd_flags_t mdns_to_cups(DNSServiceFlags flags, DNSServiceErrorType error); + +#elif _WIN32 + +#else // HAVE_AVAHI +static void avahi_browse_cb(AvahiServiceBrowser *browser, AvahiIfIndex if_index, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, cups_dnssd_browse_t *browse); +static void avahi_client_cb(AvahiClient *c, AvahiClientState state, cups_dnssd_t *dnssd); +static void *avahi_monitor(cups_dnssd_t *dnssd); +static void avahi_query_cb(AvahiRecordBrowser *browser, AvahiIfIndex if_index, AvahiProtocol protocol, AvahiBrowserEvent event, const char *fullName, uint16_t rrclass, uint16_t rrtype, const void *rdata, size_t rdlen, AvahiLookupResultFlags flags, cups_dnssd_query_t *query); +static void avahi_resolve_cb(AvahiServiceResolver *resolver, AvahiIfIndex if_index, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txtrec, AvahiLookupResultFlags flags, cups_dnssd_resolve_t *resolve); +static void avahi_service_cb(AvahiEntryGroup *srv, AvahiEntryGroupState state, cups_dnssd_service_t *service); +#endif // HAVE_MDNSRESPONDER + + +// +// 'cupsDNSSDAssembleFullName()' - Create a full service name from the instance +// name, registration type, and domain. +// +// This function combines an instance name ("Example Name"), registration type +// ("_ipp._tcp"), and domain ("local.") to create a properly escaped full +// service name ("Example\032Name._ipp._tcp.local."). +// + +bool // O - `true` on success, `false` on failure +cupsDNSSDAssembleFullName( + char *fullname, // I - Buffer for full name + size_t fullsize, // I - Size of buffer + const char *name, // I - Service instance name + const char *type, // I - Registration type + const char *domain) // I - Domain +{ + if (!fullname || !fullsize || !name || !type) + return (false); + +#ifdef HAVE_MDNSRESPONDER + if (fullsize < kDNSServiceMaxDomainName) + return (false); + + return (DNSServiceConstructFullName(fullname, name, type, domain) == kDNSServiceErr_NoError); + +#elif _WIN32 + return (false); + +#else // HAVE_AVAHI + return (!avahi_service_name_join(fullname, fullsize, name, type, domain)); +#endif // HAVE_MDNSRESPONDER +} + + +// +// 'cupsDNSSDDecodeTXT()' - Decode a TXT record into key/value pairs. +// +// This function converts the DNS TXT record encoding of key/value pairs into +// `cups_option_t` elements that can be accessed using the @link cupsGetOption@ +// function and freed using the @link cupsFreeOptions@ function. +// + +size_t // O - Number of key/value pairs +cupsDNSSDDecodeTXT( + const unsigned char *txtrec, // I - TXT record data + uint16_t txtlen, // I - TXT record length + cups_option_t **txt) // O - Key/value pairs +{ + size_t num_txt = 0; // Number of key/value pairs + unsigned char keylen; // Length of key/value + char key[256], // Key/value buffer + *value; // Pointer to value + const unsigned char *txtptr, // Pointer into TXT record data + *txtend; // End of TXT record data + + + // Range check input... + if (txt) + *txt = NULL; + if (!txtrec || !txtlen || !txt) + return (0); + + // Loop through the record... + for (txtptr = txtrec, txtend = txtrec + txtlen; txtptr < txtend; txtptr += keylen) + { + // Format is a length byte followed by "key=value" + keylen = *txtptr++; + if (keylen == 0 || (txtptr + keylen) > txtend) + break; // Bogus length + + // Copy the data to a C string... + memcpy(key, txtptr, keylen); + key[keylen] = '\0'; + + if ((value = strchr(key, '=')) != NULL) + { + // Got value separator, add it... + *value++ = '\0'; + + num_txt = cupsAddOption(key, value, num_txt, txt); + } + else + { + // No value, stop... + break; + } + } + + // Return the number of pairs we parsed... + return (num_txt); + +} + + +// +// 'cupsDNSSDSeparateFullName()' - Separate a full service name into an instance +// name, registration type, and domain. +// +// This function separates a full service name such as +// "Example\032Name._ipp._tcp.local.") into its instance name ("Example Name"), +// registration type ("_ipp._tcp"), and domain ("local."). +// + +bool // O - `true` on success, `false` on error +cupsDNSSDSeparateFullName( + const char *fullname, // I - Full service name + char *name, // I - Instance name buffer + size_t namesize, // I - Size of instance name buffer + char *type, // I - Registration type buffer + size_t typesize, // I - Size of registration type buffer + char *domain, // I - Domain name buffer + size_t domainsize) // I - Size of domain name buffer +{ + // Range check input.. + if (!fullname || !name || !namesize || !type || !typesize || !domain || !domainsize) + { + if (name) + *name = '\0'; + if (type) + *type = '\0'; + if (domain) + *domain = '\0'; + + return (false); + } + +#if _WIN32 || defined(HAVE_MDNSRESPONDER) + bool ret = true; // Return value + char *ptr, // Pointer into name/type/domain + *end; // Pointer to end of name/type/domain + + // Get the service name... + for (ptr = name, end = name + namesize - 1; *fullname; fullname ++) + { + if (*fullname == '.') + { + // Service type separator... + break; + } + else if (*fullname == '\\' && isdigit(fullname[1] & 255) && isdigit(fullname[2] & 255) && isdigit(fullname[3] & 255)) + { + // Escaped character + if (ptr < end) + *ptr++ = (fullname[1] - '0') * 100 + (fullname[2] - '0') * 10 + fullname[3] - '0'; + else + ret = false; + + fullname += 3; + } + else if (ptr < end) + *ptr++ = *fullname; + else + ret = false; + } + *ptr = '\0'; + + if (*fullname) + fullname ++; + + // Get the type... + for (ptr = type, end = type + typesize - 1; *fullname; fullname ++) + { + if (*fullname == '.' && fullname[1] != '_') + { + // Service type separator... + break; + } + else if (*fullname == '\\' && isdigit(fullname[1] & 255) && isdigit(fullname[2] & 255) && isdigit(fullname[3] & 255)) + { + // Escaped character + if (ptr < end) + *ptr++ = (fullname[1] - '0') * 100 + (fullname[2] - '0') * 10 + fullname[3] - '0'; + else + ret = false; + + fullname += 3; + } + else if (ptr < end) + *ptr++ = *fullname; + else + ret = false; + } + *ptr = '\0'; + + if (*fullname) + fullname ++; + + // Get the domain... + for (ptr = domain, end = domain + domainsize - 1; *fullname; fullname ++) + { + if (*fullname == '\\' && isdigit(fullname[1] & 255) && isdigit(fullname[2] & 255) && isdigit(fullname[3] & 255)) + { + // Escaped character + if (ptr < end) + *ptr++ = (fullname[1] - '0') * 100 + (fullname[2] - '0') * 10 + fullname[3] - '0'; + else + ret = false; + + fullname += 3; + } + else if (ptr < end) + *ptr++ = *fullname; + else + ret = false; + } + *ptr = '\0'; + + return (ret); + +#else // HAVE_AVAHI + return (!avahi_service_name_split(fullname, name, namesize, type, typesize, domain, domainsize)); +#endif // _WIN32 || HAVE_MDNSRESPONDER +} + + +// +// 'cupsDNSSDDelete()' - Delete a DNS-SD context and all its requests. +// + +void +cupsDNSSDDelete(cups_dnssd_t *dnssd) // I - DNS-SD context +{ + if (!dnssd) + return; + + cupsMutexLock(&dnssd->mutex); + + cupsArrayDelete(dnssd->browses); + cupsArrayDelete(dnssd->queries); + cupsArrayDelete(dnssd->resolves); + cupsArrayDelete(dnssd->services); + +#ifdef HAVE_MDNSRESPONDER + cupsThreadCancel(dnssd->monitor); + DNSServiceRefDeallocate(dnssd->ref); + +#elif _WIN32 + +#else // HAVE_AVAHI + cupsThreadCancel(dnssd->monitor); + avahi_simple_poll_free(dnssd->poll); +#endif // HAVE_MDNSRESPONDER + + cupsMutexUnlock(&dnssd->mutex); + cupsMutexDestroy(&dnssd->mutex); + free(dnssd); +} + + +// +// 'cupsDNSSDGetHostName()' - Get the current mDNS host name for the system. +// +// This function gets the current mDNS (".local") host name for the system. +// + +const char * // O - Local host name or `NULL` for none +cupsDNSSDGetHostName( + cups_dnssd_t *dnssd, // I - DNS-SD context + char *buffer, // I - Host name buffer + size_t bufsize) // I - Size of host name buffer +{ + // Range check input... + if (buffer) + *buffer = '\0'; + + if (!dnssd || !buffer || !bufsize) + return (NULL); + +#if _WIN32 || defined(HAVE_MDNSRESPONDER) + char *bufptr; // Pointer into buffer +# ifdef __APPLE__ + CFStringRef localname; // Local host name as a CF string + + if ((localname = SCDynamicStoreCopyLocalHostName(dnssd->sc)) != NULL) + { + CFStringGetCString(localname, buffer, (CFIndex)bufsize, kCFStringEncodingUTF8); + CFRelease(localname); + } + else +# endif // __APPLE__ + gethostname(buffer, bufsize); + + if ((bufptr = strchr(buffer, '.')) != NULL) + { + // Replace domain with .local as needed... + if (strcmp(bufptr, ".local")) + cupsCopyString(bufptr, ".local", bufsize - (size_t)(bufptr - buffer)); + } + else + { + // Add .local... + cupsConcatString(buffer, ".local", bufsize); + } + +#else // HAVE_AVAHI + cupsCopyString(buffer, avahi_client_get_host_name_fqdn(dnssd->client), bufsize); +#endif // _WIN32 || HAVE_MDNSRESPONDER + + return (buffer); +} + + +// +// 'cupsDNSSDGetConfigChanges()' - Get the number of host name/network +// configuration changes seen. +// +// This function returns the number of host name or network configuration +// changes that have been seen since the context was created. The value can be +// used to track when local services need to be updated. Registered services +// will also get a callback with the `CUPS_DNSSD_FLAGS_HOST_CHANGE` bit set in +// the "flags" argument for host name changes and/or +// `CUPS_DNSSD_FLAGS_NETWORK_CHANGE` for network changes. +// + +size_t // O - Number of host name changes +cupsDNSSDGetConfigChanges( + cups_dnssd_t *dnssd) // I - DNS-SD context +{ + return (dnssd ? dnssd->config_changes : 0); +} + + +// +// 'cupsDNSSDNew()' - Create a new DNS-SD context. +// +// This function creates a new DNS-SD context for browsing, querying, resolving, +// and/or registering services. Call @link cupsDNSSDDelete@ to stop any pending +// browses, queries, or resolves, unregister any services, and free the DNS-SD +// context. +// + +cups_dnssd_t * // O - DNS-SD context +cupsDNSSDNew( + cups_dnssd_error_cb_t error_cb, // I - Error callback function + void *cb_data) // I - Error callback data +{ + cups_dnssd_t *dnssd; // DNS-SD context + + + // Allocate memory... + if ((dnssd = (cups_dnssd_t *)calloc(1, sizeof(cups_dnssd_t))) == NULL) + return (NULL); + + // Save the error callback... + dnssd->cb = error_cb; + dnssd->cb_data = cb_data; + + // Initialize the mutex... + cupsMutexInit(&dnssd->mutex); + +#ifdef __APPLE__ + // Use the system configuration dynamic store for host info... + SCDynamicStoreContext scinfo; // Information for callback + + memset(&scinfo, 0, sizeof(scinfo)); + scinfo.info = dnssd; + + dnssd->sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("libcups3"), (SCDynamicStoreCallBack)apple_sc_cb, &scinfo); +#endif // __APPLE__ + + // Setup the DNS-SD connection and monitor thread... +#ifdef HAVE_MDNSRESPONDER + DNSServiceErrorType error; // Error code + + if ((error = DNSServiceCreateConnection(&dnssd->ref)) == kDNSServiceErr_NoError) + { + // Start the background monitoring thread... + if ((dnssd->monitor = cupsThreadCreate((void *(*)(void *))mdns_monitor, dnssd)) == 0) + { + report_error(dnssd, "Unable to create DNS-SD thread: %s", strerror(errno)); + cupsDNSSDDelete(dnssd); + return (NULL); + } + + cupsThreadDetach(dnssd->monitor); + } + else + { + // Unable to create connection... + report_error(dnssd, "Unable to initialize DNS-SD: %s", mdns_strerror(error)); + cupsDNSSDDelete(dnssd); + return (NULL); + } + +#elif _WIN32 + +#else // HAVE_AVAHI + int error; // Error code + + if ((dnssd->poll = avahi_simple_poll_new()) == NULL) + { + // Unable to create the background thread... + report_error(dnssd, "Unable to initialize DNS-SD: %s", strerror(errno)); + cupsDNSSDDelete(dnssd); + return (NULL); + } + else if ((dnssd->client = avahi_client_new(avahi_simple_poll_get(dnssd->poll), AVAHI_CLIENT_NO_FAIL, (AvahiClientCallback)avahi_client_cb, dnssd, &error)) == NULL) + { + // Unable to create the client... + report_error(dnssd, "Unable to initialize DNS-SD: %s", avahi_strerror(error)); + avahi_simple_poll_free(dnssd->poll); + cupsDNSSDDelete(dnssd); + return (NULL); + } + else if ((dnssd->monitor = cupsThreadCreate((void *(*)(void *))avahi_monitor, dnssd)) == 0) + { + report_error(dnssd, "Unable to create DNS-SD thread: %s", strerror(errno)); + cupsDNSSDDelete(dnssd); + return (NULL); + } + + cupsThreadDetach(dnssd->monitor); +#endif // HAVE_MDNSRESPONDER + + return (dnssd); +} + + +// +// 'cupsDNSSDBrowseDelete()' - Cancel and delete a browse request. +// + +void +cupsDNSSDBrowseDelete( + cups_dnssd_browse_t *browse) // I - Browse request +{ + if (browse) + { + cups_dnssd_t *dnssd = browse->dnssd; + + cupsMutexLock(&dnssd->mutex); + cupsArrayRemove(dnssd->browses, browse); + cupsMutexUnlock(&dnssd->mutex); + } +} + + +// +// 'cupsDNSSDBrowseGetContext()' - Get the DNS-SD context for the browse request. +// + +cups_dnssd_t * // O - Context or `NULL` +cupsDNSSDBrowseGetContext( + cups_dnssd_browse_t *browse) // I - Browse request +{ + return (browse ? browse->dnssd : NULL); +} + + +// +// 'cupsDNSSDBrowseNew()' - Create a new DNS-SD browse request. +// +// This function creates a new DNS-SD browse request for the specified service +// types and optional domain and interface index. The "types" argument can be a +// single service type ("_ipp._tcp") or a service type and comma-delimited list +// of sub-types ("_ipp._tcp,_print,_universal"). +// +// Newly discovered services are reported using the required browse callback +// function, with the "flags" argument set to `CUPS_DNSSD_FLAGS_ADD` for newly +// discovered services, `CUPS_DNSSD_FLAGS_NONE` for removed services, or +// `CUPS_DNSSD_FLAGS_ERROR` on an error: +// +// ``` +// void +// browse_cb( +// cups_dnssd_browse_t *browse, +// void *cb_data, +// cups_dnssd_flags_t flags, +// uint32_t if_index, +// const char *name, +// const char *regtype, +// const char *domain) +// { +// // Process added/removed service +// } +// ``` +// + +cups_dnssd_browse_t * // O - Browse request or `NULL` on error +cupsDNSSDBrowseNew( + cups_dnssd_t *dnssd, // I - DNS-SD context + uint32_t if_index, // I - Interface index, `CUPS_DNSSD_IF_ANY`, or `CUPS_DNSSD_IF_LOCAL` + const char *types, // I - Service types + const char *domain, // I - Domain name or `NULL` for default + cups_dnssd_browse_cb_t browse_cb, // I - Browse callback function + void *cb_data) // I - Browse callback data +{ + cups_dnssd_browse_t *browse; // Browse request + + + // Range check input... + if (!dnssd || !types || !browse_cb) + return (NULL); + + // Allocate memory for the browser... + if ((browse = (cups_dnssd_browse_t *)calloc(1, sizeof(cups_dnssd_browse_t))) == NULL) + return (NULL); + + browse->dnssd = dnssd; + browse->cb = browse_cb; + browse->cb_data = cb_data; + + cupsMutexLock(&dnssd->mutex); + + if (!dnssd->browses) + { + // Create an array of browsers... + if ((dnssd->browses = cupsArrayNew(NULL, NULL, NULL, 0, NULL, (cups_afree_cb_t)delete_browse)) == NULL) + { + // Unable to create... + free(browse); + browse = NULL; + goto done; + } + } + +#ifdef HAVE_MDNSRESPONDER + DNSServiceErrorType error; // Error, if any + + browse->ref = dnssd->ref; + if ((error = DNSServiceBrowse(&browse->ref, kDNSServiceFlagsShareConnection, if_index, types, domain, (DNSServiceBrowseReply)mdns_browse_cb, browse)) != kDNSServiceErr_NoError) + { + report_error(dnssd, "Unable to create DNS-SD browse request: %s", mdns_strerror(error)); + free(browse); + browse = NULL; + goto done; + } + +#elif _WIN32 + +#else // HAVE_AVAHI + browse->browser = avahi_service_browser_new(dnssd->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, types, NULL, 0, (AvahiServiceBrowserCallback)avahi_browse_cb, browse); + + if (!browse->browser) + { + report_error(dnssd, "Unable to create DNS-SD browse request: %s", avahi_strerror(avahi_client_errno(dnssd->client))); + free(browse); + browse = NULL; + goto done; + } +#endif // HAVE_MDNSRESPONDER + + cupsArrayAdd(dnssd->browses, browse); + + done: + + cupsMutexUnlock(&dnssd->mutex); + + return (browse); +} + + + +// +// 'cupsDNSSDQueryDelete()' - Cancel and delete a query request. +// + +void +cupsDNSSDQueryDelete( + cups_dnssd_query_t *query) // I - Query request +{ + if (query) + { + cups_dnssd_t *dnssd = query->dnssd; + + cupsMutexLock(&dnssd->mutex); + cupsArrayRemove(dnssd->queries, query); + cupsMutexUnlock(&dnssd->mutex); + } +} + + +// +// 'cupsDNSSDQueryGetContext()' - Get the DNS-SD context for the query request. +// + +cups_dnssd_t * // O - DNS-SD context or `NULL` +cupsDNSSDQueryGetContext( + cups_dnssd_query_t *query) // I - Query request +{ + return (query ? query->dnssd : NULL); +} + + +// +// 'cupsDNSSDQueryNew()' - Create a new query request. +// +// This function creates a new DNS-SD query request for the specified full +// service name and DNS record type. The "fullname" parameter specifies the +// full DNS name of the service (instance name, type, and domain) being queried. +// Responses to the query are reported using the required query callback +// function with the "flags" argument set to `CUPS_DNSSD_FLAGS_NONE` on success +// or `CUPS_DNSSD_FLAGS_ERROR` on error: +// +// ``` +// void +// query_cb( +// cups_dnssd_query_t *query, +// void *cb_data, +// cups_dnssd_flags_t flags, +// uint32_t if_index, +// const char *fullname, +// uint16_t rrtype, +// const void *qdata, +// uint16_t qlen) +// { +// // Process query record +// } +// ``` +// + +cups_dnssd_query_t * // O - Query request or `NULL` on error +cupsDNSSDQueryNew( + cups_dnssd_t *dnssd, // I - DNS-SD context + uint32_t if_index, // I - Interface index or `CUPS_DNSSD_IF_ANY` or `CUPS_DNSSD_IF_LOCAL` + const char *fullname, // I - Full DNS name including types and domain + uint16_t rrtype, // I - Record type to query (`CUPS_DNSSD_RRTYPE_TXT`, etc.) + cups_dnssd_query_cb_t query_cb, // I - Query callback function + void *cb_data) // I - Query callback data +{ + cups_dnssd_query_t *query; // Query request + + + // Range check input... + if (!dnssd || !fullname || !query_cb) + return (NULL); + + // Allocate memory for the queryr... + if ((query = (cups_dnssd_query_t *)calloc(1, sizeof(cups_dnssd_query_t))) == NULL) + return (NULL); + + query->dnssd = dnssd; + query->cb = query_cb; + query->cb_data = cb_data; + + cupsMutexLock(&dnssd->mutex); + + if (!dnssd->queries) + { + // Create an array of queryrs... + if ((dnssd->queries = cupsArrayNew(NULL, NULL, NULL, 0, NULL, (cups_afree_cb_t)delete_query)) == NULL) + { + // Unable to create... + free(query); + query = NULL; + goto done; + } + } + +#ifdef HAVE_MDNSRESPONDER + DNSServiceErrorType error; // Error, if any + + query->ref = dnssd->ref; + if ((error = DNSServiceQueryRecord(&query->ref, kDNSServiceFlagsShareConnection, if_index, fullname, rrtype, kDNSServiceClass_IN, (DNSServiceQueryRecordReply)mdns_query_cb, query)) != kDNSServiceErr_NoError) + { + report_error(dnssd, "Unable to create DNS-SD query request: %s", mdns_strerror(error)); + free(query); + query = NULL; + goto done; + } + +#elif _WIN32 + +#else // HAVE_AVAHI + query->browser = avahi_record_browser_new(dnssd->client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, fullname, AVAHI_DNS_CLASS_IN, rrtype, 0, (AvahiRecordBrowserCallback)avahi_query_cb, query); + + if (!query->browser) + { + report_error(dnssd, "Unable to create DNS-SD query request: %s", avahi_strerror(avahi_client_errno(dnssd->client))); + free(query); + query = NULL; + goto done; + } +#endif // HAVE_MDNSRESPONDER + + cupsArrayAdd(dnssd->queries, query); + + done: + + cupsMutexUnlock(&dnssd->mutex); + + return (query); +} + + + +// +// 'cupsDNSSDResolveDelete()' - Cancel and free a resolve request. +// + +void +cupsDNSSDResolveDelete( + cups_dnssd_resolve_t *res) // I - Resolve request +{ + if (res) + { + cups_dnssd_t *dnssd = res->dnssd; + + cupsMutexLock(&dnssd->mutex); + cupsArrayRemove(dnssd->resolves, res); + cupsMutexUnlock(&dnssd->mutex); + } +} + + +// +// 'cupsDNSSDResolveGetContext()' - Get the DNS-SD context for the resolve request. +// + +cups_dnssd_t * // O - DNS-SD context or `NULL` +cupsDNSSDResolveGetContext( + cups_dnssd_resolve_t *resolve) // I - Resolve request +{ + return (resolve ? resolve->dnssd : NULL); +} + + +// +// 'cupsDNSSDResolveNew()' - Create a new DNS-SD resolve request. +// +// This function creates a new DNS-SD resolver for the specified instance name, +// service type, and optional domain and interface index. Resikved services +// are reported using the required resolve callback function, with the "flags" +// argument set to `CUPS_DNSSD_FLAGS_NONE` on success or +// `CUPS_DNSSD_FLAGS_ERROR` on error: +// +// ``` +// void +// resolve_cb( +// cups_dnssd_resolve_t *resolve, +// void *cb_data, +// cups_dnssd_flags_t flags, +// uint32_t if_index, +// const char *fullname, +// const char *host, +// uint16_t port, +// size_t num_txt, +// cups_option_t *txt) +// { +// // Process resolved service +// } +// ``` +// + +cups_dnssd_resolve_t * // O - Resolve request or `NULL` on error +cupsDNSSDResolveNew( + cups_dnssd_t *dnssd, // I - DNS-SD context + uint32_t if_index, // I - Interface index or `CUPS_DNSSD_IF_ANY` or `CUPS_DNSSD_IF_LOCAL` + const char *name, // I - Service name + const char *type, // I - Service type + const char *domain, // I - Domain name or `NULL` for default + cups_dnssd_resolve_cb_t resolve_cb, // I - Resolve callback function + void *cb_data) // I - Resolve callback data +{ + cups_dnssd_resolve_t *resolve; // Resolve request + + + // Range check input... + if (!dnssd || !name || !type || !resolve_cb) + return (NULL); + + // Allocate memory for the queryr... + if ((resolve = (cups_dnssd_resolve_t *)calloc(1, sizeof(cups_dnssd_resolve_t))) == NULL) + return (NULL); + + resolve->dnssd = dnssd; + resolve->cb = resolve_cb; + resolve->cb_data = cb_data; + + cupsMutexLock(&dnssd->mutex); + + if (!dnssd->resolves) + { + // Create an array of queryrs... + if ((dnssd->resolves = cupsArrayNew(NULL, NULL, NULL, 0, NULL, (cups_afree_cb_t)delete_resolve)) == NULL) + { + // Unable to create... + free(resolve); + resolve = NULL; + goto done; + } + } + +#ifdef HAVE_MDNSRESPONDER + DNSServiceErrorType error; // Error, if any + + resolve->ref = dnssd->ref; + if ((error = DNSServiceResolve(&resolve->ref, kDNSServiceFlagsShareConnection, if_index, name, type, domain, (DNSServiceResolveReply)mdns_resolve_cb, resolve)) != kDNSServiceErr_NoError) + { + report_error(dnssd, "Unable to create DNS-SD query request: %s", mdns_strerror(error)); + free(resolve); + resolve = NULL; + goto done; + } + +#elif _WIN32 + +#else // HAVE_AVAHI + resolve->resolver = avahi_service_resolver_new(dnssd->client, if_index, AVAHI_PROTO_UNSPEC, name, type, domain, AVAHI_PROTO_UNSPEC, /*flags*/0, (AvahiServiceResolverCallback)avahi_resolve_cb, resolve); + + if (!resolve->resolver) + { + report_error(dnssd, "Unable to create DNS-SD resolve request: %s", avahi_strerror(avahi_client_errno(dnssd->client))); + free(resolve); + resolve = NULL; + goto done; + } +#endif // HAVE_MDNSRESPONDER + + cupsArrayAdd(dnssd->resolves, resolve); + + done: + + cupsMutexUnlock(&dnssd->mutex); + + return (resolve); +} + + +// +// 'cupsDNSSDServiceAdd()' - Add a service instance. +// +// This function adds a service instance for the specified service types, +// domain, host, and port. The "types" argument can be a single service type +// ("_ipp._tcp") or a service type and comma-delimited list of sub-types +// ("_ipp._tcp,_print,_universal"). +// +// Call the @link cupsDNSSDServicePublish@ function after all service instances +// have been added. +// + +bool // O - `true` on success, `false` on failure +cupsDNSSDServiceAdd( + cups_dnssd_service_t *service, // I - Service + const char *types, // I - Service types + const char *domain, // I - Domain name or `NULL` for default + const char *host, // I - Host name or `NULL` for default + uint16_t port, // I - Port number or `0` for none + size_t num_txt, // I - Number of TXT record values + cups_option_t *txt) // I - TXT record values +{ + bool ret = true; // Return value + size_t i; // Looping var + + + // Range check input... + if (!service || !types) + return (false); + +#ifdef HAVE_MDNSRESPONDER + DNSServiceErrorType error; // Error, if any + TXTRecordRef txtrec, // TXT record + *txtptr = NULL; // Pointer to TXT record, if any + + // Limit number of services with this name... + if (service->num_refs >= (sizeof(service->refs) / sizeof(service->refs[0]))) + { + report_error(service->dnssd, "Unable to create DNS-SD service registration: Too many services with this name."); + ret = false; + goto done; + } + + // Create the TXT record as needed... + if (num_txt) + { + TXTRecordCreate(&txtrec, 1024, NULL); + for (i = 0; i < num_txt; i ++) + TXTRecordSetValue(&txtrec, txt[i].name, (uint8_t)strlen(txt[i].value), txt[i].value); + + txtptr = &txtrec; + } + + service->refs[service->num_refs] = service->dnssd->ref; + if ((error = DNSServiceRegister(service->refs + service->num_refs, kDNSServiceFlagsShareConnection | kDNSServiceFlagsNoAutoRename, service->if_index, service->name, types, domain, host, htons(port), txtptr ? TXTRecordGetLength(txtptr) : 0, txtptr ? TXTRecordGetBytesPtr(txtptr) : NULL, (DNSServiceRegisterReply)mdns_service_cb, service)) != kDNSServiceErr_NoError) + { + if (txtptr) + TXTRecordDeallocate(txtptr); + + report_error(service->dnssd, "Unable to create DNS-SD service registration: %s", mdns_strerror(error)); + ret = false; + goto done; + } + + if (txtptr) + TXTRecordDeallocate(txtptr); + + if (service->loc_set) + { + if ((error = DNSServiceAddRecord(service->refs[service->num_refs], service->loc_refs + service->num_refs, 0, kDNSServiceType_LOC, sizeof(service->loc), service->loc, 0)) != kDNSServiceErr_NoError) + { + report_error(service->dnssd, "Unable to add DNS-SD service location data: %s", mdns_strerror(error)); + } + } + + service->num_refs ++; + +#elif _WIN32 + +#else // HAVE_AVAHI + int error; // Error code + AvahiStringList *txtrec = NULL; // TXT record string list + char *regtype, // Registration type + *subtypes; // Subtypes (if any) + + // Build the string list from the TXT array... + for (i = 0; i < num_txt; i ++) + txtrec = avahi_string_list_add_printf(txtrec, "%s=%s", txt[i].name, txt[i].value); + + // Copy the registration type... + if ((regtype = strdup(types)) == NULL) + { + report_error(service->dnssd, "Unable to duplicate registration types: %s", strerror(errno)); + ret = false; + goto done; + } + + if ((subtypes = strchr(regtype, ',')) != NULL) + *subtypes++ = '\0'; + + // Add the service entry... + if ((error = avahi_entry_group_add_service_strlst(service->group, service->if_index, AVAHI_PROTO_UNSPEC, /*flags*/0, service->name, regtype, domain, host, port, txtrec)) < 0) + { + report_error(service->dnssd, "Unable to register '%s.%s': %s", service->name, regtype, avahi_strerror(error)); + ret = false; + } + else if (subtypes) + { + char subtype[256]; // Subtype string + char *start, *end; // Pointers into sub-types... + + for (start = subtypes; ret && start && *start; start = end) + { + if ((end = strchr(start, ',')) != NULL) + *end++ = '\0'; + else + end = start + strlen(start); + + snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, regtype); + if ((error = avahi_entry_group_add_service_subtype(service->group, service->if_index, AVAHI_PROTO_UNSPEC, /*flags*/0, service->name, regtype, domain, subtype)) < 0) + { + report_error(service->dnssd, "Unable to register '%s.%s': %s", service->name, subtype, avahi_strerror(error)); + ret = false; + } + } + } + + free(regtype); + + if (txtrec) + avahi_string_list_free(txtrec); +#endif // HAVE_MDNSRESPONDER + + done: + + return (ret); +} + + +// +// 'cupsDNSSDServiceDelete()' - Cancel and free a service registration. +// + +void +cupsDNSSDServiceDelete( + cups_dnssd_service_t *service) // I - Service +{ + if (service) + { + cups_dnssd_t *dnssd = service->dnssd; + + cupsMutexLock(&dnssd->mutex); + cupsArrayRemove(dnssd->services, service); + cupsMutexUnlock(&dnssd->mutex); + } +} + + +// +// 'cupsDNSSDServiceGetContext()' - Get the DNS-SD context for the service +// registration. +// + +cups_dnssd_t * // O - DNS-SD context or `NULL` +cupsDNSSDServiceGetContext( + cups_dnssd_service_t *service) // I - Service registration +{ + return (service ? service->dnssd : NULL); +} + + +// +// 'cupsDNSSDServiceGetName()' - Get the service instance name for the service registration. +// + +const char * // O - Service instance name +cupsDNSSDServiceGetName( + cups_dnssd_service_t *service) // I - Service registration +{ + return (service ? service->name : NULL); +} + + +// +// 'cupsDNSSDServiceNew()' - Create a new named service. +// +// This function creates a new DNS-SD service registration for the given service +// instance name and interface. Specific services using the name are added +// using the @link cupsDNSSDServiceAdd@ function. +// +// The required service callback is called for select events, with the "flags" +// argument set to `CUPS_DNSSD_FLAGS_NONE` for a successful registration, +// `CUPS_DNSSD_FLAGS_COLLISION` when there is a name collision, or +// `CUPS_DNSSD_FLAGS_ERROR` when there is a problem completing the service +// registration. +// + +cups_dnssd_service_t * // O - Service or `NULL` on error +cupsDNSSDServiceNew( + cups_dnssd_t *dnssd, // I - DNS-SD context + uint32_t if_index, // I - Interface index, `CUPS_DNSSD_IF_ANY`, or `CUPS_DNSSD_IF_LOCAL` + const char *name, // I - Name of service + cups_dnssd_service_cb_t cb, // I - Service registration callback function + void *cb_data) // I - Service registration callback data +{ + cups_dnssd_service_t *service; // Service registration + + + // Range check input... + if (!dnssd || !name || !cb) + return (NULL); + + // Allocate memory for the service... + if ((service = (cups_dnssd_service_t *)calloc(1, sizeof(cups_dnssd_service_t))) == NULL) + return (NULL); + + service->dnssd = dnssd; + service->cb = cb; + service->cb_data = cb_data; + service->name = strdup(name); + service->if_index = if_index; + +#ifdef HAVE_MDNSRESPONDER +#elif _WIN32 +#else // HAVE_AVAHI + service->group = avahi_entry_group_new(dnssd->client, (AvahiEntryGroupCallback)avahi_service_cb, service); + + if (!service->group) + { + report_error(dnssd, "Unable to create DNS-SD service registration: %s", avahi_strerror(avahi_client_errno(dnssd->client))); + free(service); + service = NULL; + goto done; + } +#endif // HAVE_MDNSRESPONDER + + cupsMutexLock(&dnssd->mutex); + + if (!dnssd->services) + { + // Create an array of queryrs... + if ((dnssd->services = cupsArrayNew(NULL, NULL, NULL, 0, NULL, (cups_afree_cb_t)delete_service)) == NULL) + { + // Unable to create... + free(service); + service = NULL; + goto done; + } + } + + cupsArrayAdd(dnssd->services, service); + + done: + + cupsMutexUnlock(&dnssd->mutex); + + return (service); +} + + +// +// 'cupsDNSSDServicePublish()' - Publish a service. +// +// This function publishes the DNS-SD services added using the +// @link cupsDNSSDServiceAdd@ function. +// + +bool // O - `true` on success, `false` on failure +cupsDNSSDServicePublish( + cups_dnssd_service_t *service) // I - Service +{ + bool ret = true; // Return value + + +#if _WIN32 + (void)service; +#elif defined(HAVE_MDNSRESPONDER) + (void)service; +#else // HAVE_AVAHI + avahi_entry_group_commit(service->group); +#endif // _WIN32 + + return (ret); +} + + +// +// 'cupsDNSSDServiceSetLocation()' - Set the geolocation (LOC record) of a +// service. +// +// This function sets the geolocation of a service using a 'geo:' URI (RFC 5870) +// of the form +// 'geo:LATITUDE,LONGITUDE[,ALTITUDE][;crs=CRSLABEL][;u=UNCERTAINTY]'. The +// specified coordinates and uncertainty are converted into a DNS LOC record +// for the service name label. Only the "wgs84" CRSLABEL string is supported. +// +// You must call this function prior to @link cupsDNSSDServiceAdd@. +// + +bool // O - `true` on success, `false` on failure +cupsDNSSDServiceSetLocation( + cups_dnssd_service_t *service, // I - Service + const char *geo_uri) // I - Geolocation as a 'geo:' URI +{ + bool ret = true; // Return value + const char *geo_ptr; // Pointer into 'geo;' URI + double lat = 0.0, lon = 0.0; // Latitude and longitude in degrees + double alt = 0.0; // Altitude in meters + double u = 5.0; // Uncertainty in meters + unsigned int lat_ksec, lon_ksec; // Latitude and longitude in thousandths of arc seconds, biased by 2^31 + unsigned int alt_cm; // Altitude in centimeters, biased by 10,000,000cm + unsigned char prec; // Precision value + + + // Range check input... + if (!service || !geo_uri) + return (false); + + // See if this is a WGS-84 coordinate... + if ((geo_ptr = strstr(geo_uri, ";crs=")) != NULL && strncmp(geo_ptr + 5, "wgs84", 5)) + { + // Not WGS-84... + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Only WGS-84 coordinates are supported."), true); + return (false); + } + + // Pull apart the "geo:" URI and convert to the integer representation for + // the LOC record... + sscanf(geo_uri, "geo:%lf,%lf,%lf", &lat, &lon, &alt); + lat_ksec = (unsigned)((int)(lat * 3600000.0) + 0x40000000 + 0x40000000); + lon_ksec = (unsigned)((int)(lon * 3600000.0) + 0x40000000 + 0x40000000); + alt_cm = (unsigned)((int)(alt * 100.0) + 10000000); + + if ((geo_ptr = strstr(geo_uri, ";u=")) != NULL) + u = strtod(geo_ptr + 3, NULL); + + if (u < 0.0) + u = 0.0; + + for (prec = 0, u = u * 100.0; u >= 10.0 && prec < 15; u = u * 0.01) + prec ++; + + if (u < 10.0) + prec |= (unsigned char)((int)u << 4); + else + prec |= (unsigned char)0x90; + + // Build the LOC record... + service->loc[0] = 0x00; // Version + service->loc[1] = 0x51; // Size (50cm) + service->loc[2] = prec; // Horizontal precision + service->loc[3] = prec; // Vertical precision + + service->loc[4] = (unsigned char)(lat_ksec >> 24); + // Latitude (32-bit big-endian) + service->loc[5] = (unsigned char)(lat_ksec >> 16); + service->loc[6] = (unsigned char)(lat_ksec >> 8); + service->loc[7] = (unsigned char)(lat_ksec); + + service->loc[8] = (unsigned char)(lon_ksec >> 24); + // Latitude (32-bit big-endian) + service->loc[9] = (unsigned char)(lon_ksec >> 16); + service->loc[10] = (unsigned char)(lon_ksec >> 8); + service->loc[11] = (unsigned char)(lon_ksec); + + service->loc[12] = (unsigned char)(alt_cm >> 24); + // Altitude (32-bit big-endian) + service->loc[13] = (unsigned char)(alt_cm >> 16); + service->loc[14] = (unsigned char)(alt_cm >> 8); + service->loc[15] = (unsigned char)(alt_cm); + + service->loc_set = true; + +#ifdef HAVE_MDNSRESPONDER + // Add LOC record in cupsDNSSDServiceAdd() + +#elif _WIN32 + // Add LOC record in cupsDNSSDServiceAdd() + +#else // HAVE_AVAHI + // Add LOC record now... + int error; // Error code + + if ((error = avahi_entry_group_add_record(service->group, service->if_index, AVAHI_PROTO_UNSPEC, /*flags*/0, service->name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_LOC, /*ttl*/75 * 60, service->loc, sizeof(service->loc))) < 0) + { + report_error(service->dnssd, "Unable to register LOC record for '%s': %s", service->name, avahi_strerror(error)); + ret = false; + } +#endif // HAVE_MDNSRESPONDER + + return (ret); +} + + +// +// 'delete_browse()' - Delete a browse request. +// + +static void +delete_browse( + cups_dnssd_browse_t *browse) // I - Browse request +{ +#ifdef HAVE_MDNSRESPONDER + DNSServiceRefDeallocate(browse->ref); + +#elif _WIN32 + +#else // HAVE_AVAHI + avahi_service_browser_free(browse->browser); +#endif // HAVE_MDNSRESPONDER + + free(browse); +} + + +// +// 'delete_query()' - Delete a query request. +// + +static void +delete_query( + cups_dnssd_query_t *query) // I - Query request +{ +#ifdef HAVE_MDNSRESPONDER + DNSServiceRefDeallocate(query->ref); + +#elif _WIN32 + +#else // HAVE_AVAHI + avahi_record_browser_free(query->browser); +#endif // HAVE_MDNSRESPONDER +} + + +// +// 'delete_resolve()' - Delete a resolve request. +// + +static void +delete_resolve( + cups_dnssd_resolve_t *resolve) // I - Resolve request +{ +#ifdef HAVE_MDNSRESPONDER + DNSServiceRefDeallocate(resolve->ref); + +#elif _WIN32 + +#else // HAVE_AVAHI + avahi_service_resolver_free(resolve->resolver); +#endif // HAVE_MDNSRESPONDER + +} + + +// +// 'delete_service()' - Delete a service registration. +// + +static void +delete_service( + cups_dnssd_service_t *service) // I - Service +{ + free(service->name); + +#ifdef HAVE_MDNSRESPONDER + size_t i; // Looping var + + for (i = 0; i < service->num_refs; i ++) + DNSServiceRefDeallocate(service->refs[i]); + +#elif _WIN32 + +#else // HAVE_AVAHI + avahi_entry_group_free(service->group); +#endif // HAVE_MDNSRESPONDER + + free(service); +} + + +// +// 'record_config_change()' - Record that the local hostname or network has +// changed and notify any service callbacks. +// + +static void +record_config_change(cups_dnssd_t *dnssd, // I - DNS-SD context + cups_dnssd_flags_t flags) // I - Flags for what changed +{ + cups_dnssd_service_t *service; // Current service + + + cupsMutexLock(&dnssd->mutex); + + dnssd->config_changes ++; + + for (service = (cups_dnssd_service_t *)cupsArrayGetFirst(dnssd->services); service; service = (cups_dnssd_service_t *)cupsArrayGetNext(dnssd->services)) + (service->cb)(service, service->cb_data, flags); + + cupsMutexUnlock(&dnssd->mutex); +} + +// +// 'report_error()' - Report an error. +// + +static void +report_error(cups_dnssd_t *dnssd, // I - DNS-SD context + const char *message, // I - printf-style message string + ...) // I - Additional arguments as needed +{ + va_list ap; // Pointer to arguments + char buffer[8192]; // Formatted message + + + // Format the message... + va_start(ap, message); + vsnprintf(buffer, sizeof(buffer), message, ap); + va_end(ap); + + // Send it... + if (dnssd->cb) + (dnssd->cb)(dnssd->cb_data, buffer); + else + fprintf(stderr, "%s\n", buffer); +} + + +#ifdef __APPLE__ +// +// 'apple_sc_cb()' - Track host name changes. +// + +static void +apple_sc_cb(SCDynamicStoreRef sc, // I - Dynamic store context + CFArrayRef changed, // I - Changed keys + cups_dnssd_t *dnssd) // I - DNS-SD context +{ + cups_dnssd_flags_t flags = CUPS_DNSSD_FLAGS_NETWORK_CHANGE; + // Change flags + CFIndex i, // Looping var + count; // Number of values + + + (void)sc; + + // See if we had a local hostname change - anything else will be a network + // change... + for (i = 0, count = CFArrayGetCount(changed); i < count; i ++) + { + if (CFArrayGetValueAtIndex(changed, i) == kSCPropNetLocalHostName) + { + flags = CUPS_DNSSD_FLAGS_HOST_CHANGE; + break; + } + } + + // Record the change and do any callbacks as needed... + record_config_change(dnssd, flags); +} +#endif // __APPLE__ + + +#ifdef HAVE_MDNSRESPONDER +// +// 'mdns_browse_cb()' - Handle DNS-SD browse callbacks from mDNSResponder. +// + +static void +mdns_browse_cb( + DNSServiceRef ref, // I - Service reference + DNSServiceFlags flags, // I - Browse flags + uint32_t if_index, // I - Interface index + DNSServiceErrorType error, // I - Error code, if any + const char *name, // I - Service name + const char *regtype, // I - Registration type + const char *domain, // I - Domain + cups_dnssd_browse_t *browse) // I - Browse request +{ + (void)ref; + + if (error != kDNSServiceErr_NoError) + report_error(browse->dnssd, "DNS-SD browse error: %s", mdns_strerror(error)); + + (browse->cb)(browse, browse->cb_data, mdns_to_cups(flags, error), if_index, name, regtype, domain); +} + + +// +// 'mdns_monitor()' - Monitor DNS-SD messages from mDNSResponder. +// + +static void * // O - Return value (always `NULL`) +mdns_monitor(cups_dnssd_t *dnssd) // I - DNS-SD context +{ + DNSServiceErrorType error; // Current error + + for (;;) + { + if ((error = DNSServiceProcessResult(dnssd->ref)) != kDNSServiceErr_NoError) + { + report_error(dnssd, "Unable to read response from DNS-SD service: %s", mdns_strerror(error)); + break; + } + } + + return (NULL); +} + + +// +// 'mdns_query_cb()' - Handle DNS-SD query callbacks from mDNSResponder. +// + +static void +mdns_query_cb( + DNSServiceRef ref, // I - Service reference + DNSServiceFlags flags, // I - Query flags + uint32_t if_index, // I - Interface index + DNSServiceErrorType error, // I - Error code, if any + const char *name, // I - Service name + uint16_t rrtype, // I - Record type + uint16_t rrclass, // I - Record class + uint16_t rdlen, // I - Response length + const void *rdata, // I - Response data + uint32_t ttl, // I - Time-to-live value + cups_dnssd_query_t *query) // I - Query request +{ + (void)ref; + (void)rrclass; + (void)ttl; + + if (error != kDNSServiceErr_NoError) + report_error(query->dnssd, "DNS-SD query error: %s", mdns_strerror(error)); + + (query->cb)(query, query->cb_data, mdns_to_cups(flags, error), if_index, name, rrtype, rdata, rdlen); +} + + +// +// 'mdns_resolve_cb()' - Handle DNS-SD resolution callbacks from mDNSResponder. +// + +static void +mdns_resolve_cb( + DNSServiceRef ref, // I - Service reference + DNSServiceFlags flags, // I - Registration flags + uint32_t if_index, // I - Interface index + DNSServiceErrorType error, // I - Error code, if any + const char *fullname, // I - Full name of service + const char *host, // I - Hostname of service + uint16_t port, // I - Port number in network byte order + uint16_t txtlen, // I - Length of TXT record + const unsigned char *txtrec, // I - TXT record + cups_dnssd_resolve_t *resolve) // I - Resolve request +{ + size_t num_txt; // Number of TXT key/value pairs + cups_option_t *txt; // TXT key/value pairs + + + (void)ref; + + if (error != kDNSServiceErr_NoError) + report_error(resolve->dnssd, "DNS-SD resolve error: %s", mdns_strerror(error)); + + num_txt = cupsDNSSDDecodeTXT(txtrec, txtlen, &txt); + + (resolve->cb)(resolve, resolve->cb_data, mdns_to_cups(flags, error), if_index, fullname, host, ntohs(port), num_txt, txt); + + cupsFreeOptions(num_txt, txt); +} + + +// +// 'mdns_service_cb()' - Handle DNS-SD service registration callbacks from +// mDNSResponder. +// + +static void +mdns_service_cb( + DNSServiceRef ref, // I - Service reference + DNSServiceFlags flags, // I - Registration flags + DNSServiceErrorType error, // I - Error code, if any + const char *name, // I - Service name + const char *regtype, // I - Registration type + const char *domain, // I - Domain + cups_dnssd_service_t *service) // I - Service registration +{ + (void)ref; + (void)name; + (void)regtype; + (void)domain; + + if (error != kDNSServiceErr_NoError) + report_error(service->dnssd, "DNS-SD service registration error: %s", mdns_strerror(error)); + + (service->cb)(service, service->cb_data, mdns_to_cups(flags, error)); +} + + +// +// 'mdns_strerror()' - Convert an error code to a string. +// + +static const char * // O - Error message +mdns_strerror( + DNSServiceErrorType errorCode) // I - Error code +{ + switch (errorCode) + { + case kDNSServiceErr_NoError : + return ("No error"); + + case kDNSServiceErr_Unknown : + default : + return ("Unknown error"); + + case kDNSServiceErr_NoSuchName : + return ("Name not found"); + + case kDNSServiceErr_NoMemory : + return ("Out of memory"); + + case kDNSServiceErr_BadParam : + return ("Bad parameter"); + + case kDNSServiceErr_BadReference : + return ("Bad service reference"); + + case kDNSServiceErr_BadState : + return ("Bad state"); + + case kDNSServiceErr_BadFlags : + return ("Bad flags argument"); + + case kDNSServiceErr_Unsupported : + return ("Unsupported feature"); + + case kDNSServiceErr_NotInitialized : + return ("Not initialized"); + + case kDNSServiceErr_AlreadyRegistered : + return ("Name already registered"); + + case kDNSServiceErr_NameConflict : + return ("Name conflicts"); + + case kDNSServiceErr_Invalid : + return ("Invalid argument"); + + case kDNSServiceErr_Firewall : + return ("Firewall prevents access"); + + case kDNSServiceErr_Incompatible : + return ("Client library incompatible with background daemon"); + + case kDNSServiceErr_BadInterfaceIndex : + return ("Bad interface index"); + + case kDNSServiceErr_Refused : + return ("Connection refused"); + + case kDNSServiceErr_NoSuchRecord : + return ("DNS record not found"); + + case kDNSServiceErr_NoAuth : + return ("No authoritative answer"); + + case kDNSServiceErr_NoSuchKey : + return ("TXT record key not found"); + + case kDNSServiceErr_NATTraversal : + return ("Unable to traverse via NAT"); + + case kDNSServiceErr_DoubleNAT : + return ("Double NAT is in use"); + + case kDNSServiceErr_BadTime : + return ("Bad time value"); + + case kDNSServiceErr_BadSig : + return ("Bad signal"); + + case kDNSServiceErr_BadKey : + return ("Bad TXT record key"); + + case kDNSServiceErr_Transient : + return ("Transient error"); + + case kDNSServiceErr_ServiceNotRunning : + return ("Background daemon not running"); + + case kDNSServiceErr_NATPortMappingUnsupported : + return ("NAT doesn't support PCP, NAT-PMP or UPnP"); + + case kDNSServiceErr_NATPortMappingDisabled : + return ("NAT supports PCP, NAT-PMP or UPnP, but it's disabled by the administrator"); + + case kDNSServiceErr_NoRouter : + return ("No router configured, probably no network connectivity"); + + case kDNSServiceErr_PollingMode : + return ("Polling error"); + + case kDNSServiceErr_Timeout : + return ("Timeout"); + + case kDNSServiceErr_DefunctConnection : + return ("Connection lost"); + } +} + + +// +// 'mdns_to_cups()' - Convert mDNSResponder flags to CUPS DNS-SD flags... +// + +static cups_dnssd_flags_t // O - CUPS DNS-SD flags +mdns_to_cups( + DNSServiceFlags flags, // I - mDNSResponder flags + DNSServiceErrorType error) // I - mDNSResponder error code +{ + cups_dnssd_flags_t cups_flags = CUPS_DNSSD_FLAGS_NONE; + // CUPS DNS-SD flags + + + if (flags & kDNSServiceFlagsAdd) + cups_flags |= CUPS_DNSSD_FLAGS_ADD; + if (flags & kDNSServiceFlagsMoreComing) + cups_flags |= CUPS_DNSSD_FLAGS_MORE; + if (error != kDNSServiceErr_NoError) + cups_flags |= CUPS_DNSSD_FLAGS_ERROR; + + return (cups_flags); +} + + +#elif _WIN32 + + +#else // HAVE_AVAHI +// +// 'avahi_browse_cb()' - Handle browse callbacks from Avahi. +// + +static void +avahi_browse_cb( + AvahiServiceBrowser *browser, // I - Avahi browser + AvahiIfIndex if_index, // I - Interface index + AvahiProtocol protocol, // I - Network protocol (unused) + AvahiBrowserEvent event, // I - What happened + const char *name, // I - Service name + const char *type, // I - Service type + const char *domain, // I - Domain + AvahiLookupResultFlags flags, // I - Flags + cups_dnssd_browse_t *browse) // I - CUPS browse request +{ + cups_dnssd_flags_t cups_flags; // CUPS DNS-SD flags + + + (void)protocol; + (void)flags; + + switch (event) + { + case AVAHI_BROWSER_NEW : + cups_flags = CUPS_DNSSD_FLAGS_ADD; + break; + case AVAHI_BROWSER_REMOVE : + cups_flags = CUPS_DNSSD_FLAGS_NONE; + break; + case AVAHI_BROWSER_FAILURE : + cups_flags = CUPS_DNSSD_FLAGS_ERROR; + break; + + default : + // Other events don't get passed through... + return; + } + + (browse->cb)(browse, browse->cb_data, cups_flags, if_index, name, type, domain); +} + + +// +// 'avahi_client_cb()' - Client callback for Avahi. +// +// Called whenever the client or server state changes... +// + +static void +avahi_client_cb( + AvahiClient *c, // I - Client + AvahiClientState state, // I - Current state + cups_dnssd_t *dnssd) // I - DNS-SD context +{ + if (!c) + return; + + if (state == AVAHI_CLIENT_FAILURE) + { + if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) + report_error(dnssd, "Avahi server crashed."); + } + else if (state == AVAHI_CLIENT_S_RUNNING) + { + record_config_change(dnssd, CUPS_DNSSD_FLAGS_HOST_CHANGE); + } +} + + +// +// 'avahi_monitor()' - Background thread for Avahi. +// + +static void * // O - Exit status +avahi_monitor(cups_dnssd_t *dnssd) // I - DNS-SD context +{ + avahi_simple_poll_loop(dnssd->poll); + + return (NULL); +} + + +// +// 'avahi_query_cb()' - Query callback for Avahi. +// + +static void +avahi_query_cb( + AvahiRecordBrowser *browser, // I - Browser + AvahiIfIndex if_index, // I - Interface index + AvahiProtocol protocol, // I - Network protocol (not used) + AvahiBrowserEvent event, // I - What happened + const char *fullname, // I - Full service name + uint16_t rrclass, // I - Record class (not used) + uint16_t rrtype, // I - Record type + const void *rdata, // I - Record data + size_t rdlen, // I - Size of record data + AvahiLookupResultFlags flags, // I - Flags + cups_dnssd_query_t *query) // I - Query request +{ + (void)browser; + (void)protocol; + (void)rrclass; + + (query->cb)(query, query->cb_data, event == AVAHI_BROWSER_NEW ? CUPS_DNSSD_FLAGS_NONE : CUPS_DNSSD_FLAGS_ERROR, if_index, fullname, rrtype, rdata, rdlen); +} + + +// +// 'avahi_resolve_cb()' - Resolver callback for Avahi. +// + +static void +avahi_resolve_cb( + AvahiServiceResolver *resolver, // I - Service resolver + AvahiIfIndex if_index, // I - Interface index + AvahiProtocol protocol, // I - Network protocol (not used) + AvahiResolverEvent event, // I - What happened + const char *name, // I - Service name + const char *type, // I - Service type + const char *domain, // I - Domain + const char *host, // I - Host name + const AvahiAddress *address, // I - Address + uint16_t port, // I - Port number + AvahiStringList *txtrec, // I - TXT record + AvahiLookupResultFlags flags, // I - Flags + cups_dnssd_resolve_t *resolve) // I - Resolve request +{ + AvahiStringList *txtpair; // Current pair + size_t num_txt = 0; // Number of TXT key/value pairs + cups_option_t *txt = NULL; // TXT key/value pairs + char fullname[1024]; // Full service name + + + if (!resolver) + return; + + (void)resolver; + (void)protocol; + (void)address; + (void)flags; + + // Convert TXT key/value pairs into CUPS option array... + for (txtpair = txtrec; txtpair; txtpair = avahi_string_list_get_next(txtpair)) + { + char *key, *value; // Key and value + + avahi_string_list_get_pair(txtpair, &key, &value, NULL); + + num_txt = cupsAddOption(key, value, num_txt, &txt); + + avahi_free(key); + avahi_free(value); + } + + // Create a full name for the service... + cupsDNSSDAssembleFullName(fullname, sizeof(fullname), name, type, domain); + + // Do the resolve callback and free the TXT record stuff... + (resolve->cb)(resolve, resolve->cb_data, event == AVAHI_RESOLVER_FOUND ? CUPS_DNSSD_FLAGS_NONE : CUPS_DNSSD_FLAGS_ERROR, if_index, fullname, host, ntohs(port), num_txt, txt); + + cupsFreeOptions(num_txt, txt); +} + + +// +// 'avahi_service_cb()' - Service callback for Avahi. +// + +static void +avahi_service_cb( + AvahiEntryGroup *srv, // I - Service + AvahiEntryGroupState state, // I - Registration state + cups_dnssd_service_t *service) // I - Service registration +{ + (void)srv; + + (service->cb)(service, service->cb_data, state == AVAHI_ENTRY_GROUP_COLLISION ? CUPS_DNSSD_FLAGS_COLLISION : CUPS_DNSSD_FLAGS_NONE); +} +#endif // HAVE_MDNSRESPONDER diff --git a/cups/dnssd.h b/cups/dnssd.h new file mode 100644 index 000000000..c9ac37df4 --- /dev/null +++ b/cups/dnssd.h @@ -0,0 +1,124 @@ +// +// DNS-SD API definitions for CUPS. +// +// Copyright © 2022 by OpenPrinting. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#ifndef _CUPS_DNSSD_H_ +# define _CUPS_DNSSD_H_ +# include "cups.h" +# ifdef __cplusplus +extern "C" { +# endif // __cplusplus + + +// +// Types and constants... +// + +# define CUPS_DNSSD_IF_INDEX_ANY 0 +# define CUPS_DNSSD_IF_INDEX_LOCAL ((uint32_t)-1) + +typedef struct _cups_dnssd_s cups_dnssd_t; + // DNS-SD context + +enum cups_dnssd_flags_e // DNS-SD callback flag values +{ + CUPS_DNSSD_FLAGS_NONE = 0, // No flags + CUPS_DNSSD_FLAGS_ADD = 1, // Added (removed if not set) + CUPS_DNSSD_FLAGS_ERROR = 2, // Error occurred + CUPS_DNSSD_FLAGS_COLLISION = 4, // Collision occurred + CUPS_DNSSD_FLAGS_HOST_CHANGE = 8, // Host name changed + CUPS_DNSSD_FLAGS_NETWORK_CHANGE = 16, // Network connection changed + CUPS_DNSSD_FLAGS_MORE = 128 // More coming +}; +typedef unsigned cups_dnssd_flags_t; // DNS-SD callback flag bitmask + +typedef enum cups_dnssd_rrtype_e // DNS record type values +{ + CUPS_DNSSD_RRTYPE_A = 1, // Host address + CUPS_DNSSD_RRTYPE_NS, // Name server + CUPS_DNSSD_RRTYPE_CNAME = 5, // Canonical name + CUPS_DNSSD_RRTYPE_WKS = 11, // Well known service + CUPS_DNSSD_RRTYPE_PTR, // Domain name pointer + CUPS_DNSSD_RRTYPE_TXT = 16, // One or more text strings + CUPS_DNSSD_RRTYPE_RT = 21, // Router + CUPS_DNSSD_RRTYPE_SIG = 24, // Security signature + CUPS_DNSSD_RRTYPE_KEY, // Security key + CUPS_DNSSD_RRTYPE_AAAA = 28, // IPv6 Address. + CUPS_DNSSD_RRTYPE_LOC, // Location Information. + CUPS_DNSSD_RRTYPE_KX = 36, // Key Exchange + CUPS_DNSSD_RRTYPE_CERT, // Certification record + CUPS_DNSSD_RRTYPE_RRSIG = 46, // RRSIG + CUPS_DNSSD_RRTYPE_DNSKEY = 48, // DNSKEY + CUPS_DNSSD_RRTYPE_DHCID, // DHCP Client Identifier + CUPS_DNSSD_RRTYPE_HTTPS = 65, // HTTPS Service Binding + CUPS_DNSSD_RRTYPE_SPF = 99, // Sender Policy Framework for E-Mail + CUPS_DNSSD_RRTYPE_ANY = 255 // Wildcard match +} cups_dnssd_rrtype_t; + +typedef struct _cups_dnssd_browse_s cups_dnssd_browse_t; + // DNS browse request +typedef void (*cups_dnssd_browse_cb_t)(cups_dnssd_browse_t *browse, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *name, const char *regtype, const char *domain); + // DNS-SD browse callback + +typedef void (*cups_dnssd_error_cb_t)(void *cb_data, const char *message); + // DNS-SD error callback + +typedef struct _cups_dnssd_query_s cups_dnssd_query_t; + // DNS query request +typedef void (*cups_dnssd_query_cb_t)(cups_dnssd_query_t *query, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, uint16_t rrtype, const void *qdata, uint16_t qlen); + // DNS-SD query callback + +typedef struct _cups_dnssd_resolve_s cups_dnssd_resolve_t; + // DNS resolve request +typedef void (*cups_dnssd_resolve_cb_t)(cups_dnssd_resolve_t *res, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt); + // DNS-SD resolve callback + +typedef struct _cups_dnssd_service_s cups_dnssd_service_t; + // DNS service registration +typedef void (*cups_dnssd_service_cb_t)(cups_dnssd_service_t *service, void *cb_data, cups_dnssd_flags_t flags); + // DNS-SD service registration callback + + +// +// Functions... +// + +extern void cupsDNSSDDelete(cups_dnssd_t *dnssd) _CUPS_PUBLIC; +extern size_t cupsDNSSDGetConfigChanges(cups_dnssd_t *dnssd) _CUPS_PUBLIC; +extern const char *cupsDNSSDGetHostName(cups_dnssd_t *dnssd, char *buffer, size_t bufsize) _CUPS_PUBLIC; +extern cups_dnssd_t *cupsDNSSDNew(cups_dnssd_error_cb_t error_cb, void *cb_data) _CUPS_PUBLIC; + +extern void cupsDNSSDBrowseDelete(cups_dnssd_browse_t *browser) _CUPS_PUBLIC; +extern cups_dnssd_t *cupsDNSSDBrowseGetContext(cups_dnssd_browse_t *browser) _CUPS_PUBLIC; +extern cups_dnssd_browse_t *cupsDNSSDBrowseNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *types, const char *domain, cups_dnssd_browse_cb_t browse_cb, void *cb_data) _CUPS_PUBLIC; + +extern void cupsDNSSDQueryDelete(cups_dnssd_query_t *query) _CUPS_PUBLIC; +extern cups_dnssd_t *cupsDNSSDQueryGetContext(cups_dnssd_query_t *query) _CUPS_PUBLIC; +extern cups_dnssd_query_t *cupsDNSSDQueryNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *fullname, uint16_t rrtype, cups_dnssd_query_cb_t query_cb, void *cb_data) _CUPS_PUBLIC; + +extern void cupsDNSSDResolveDelete(cups_dnssd_resolve_t *res) _CUPS_PUBLIC; +extern cups_dnssd_t *cupsDNSSDResolveGetContext(cups_dnssd_resolve_t *res) _CUPS_PUBLIC; +extern cups_dnssd_resolve_t *cupsDNSSDResolveNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *name, const char *type, const char *domain, cups_dnssd_resolve_cb_t resolve_cb, void *cb_data) _CUPS_PUBLIC; + +extern bool cupsDNSSDServiceAdd(cups_dnssd_service_t *service, const char *types, const char *domain, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt) _CUPS_PUBLIC; +extern void cupsDNSSDServiceDelete(cups_dnssd_service_t *service) _CUPS_PUBLIC; +extern cups_dnssd_t *cupsDNSSDServiceGetContext(cups_dnssd_service_t *service) _CUPS_PUBLIC; +extern const char *cupsDNSSDServiceGetName(cups_dnssd_service_t *service) _CUPS_PUBLIC; +extern cups_dnssd_service_t *cupsDNSSDServiceNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *name, cups_dnssd_service_cb_t cb, void *cb_data) _CUPS_PUBLIC; +extern bool cupsDNSSDServicePublish(cups_dnssd_service_t *service) _CUPS_PUBLIC; +extern bool cupsDNSSDServiceSetLocation(cups_dnssd_service_t *service, const char *geo_uri) _CUPS_PUBLIC; + +extern bool cupsDNSSDAssembleFullName(char *fullname, size_t fullsize, const char *name, const char *type, const char *domain); +extern size_t cupsDNSSDDecodeTXT(const unsigned char *txtrec, uint16_t txtlen, cups_option_t **txt) _CUPS_PUBLIC; +extern bool cupsDNSSDSeparateFullName(const char *fullname, char *name, size_t namesize, char *type, size_t typesize, char *domain, size_t domainsize); + + +# ifdef __cplusplus +} +# endif // __cplusplus +#endif // !_CUPS_DNSSD_H_ diff --git a/cups/http-support.c b/cups/http-support.c index 4a3a73a4c..e048899e5 100644 --- a/cups/http-support.c +++ b/cups/http-support.c @@ -11,19 +11,7 @@ #include "cups-private.h" #include "debug-internal.h" -#ifdef HAVE_MDNSRESPONDER -# include -# ifdef _WIN32 -# include -# else -# include -# endif // _WIN32 -#elif defined(HAVE_AVAHI) -# include -# include -# include -# include -#endif // HAVE_MDNSRESPONDER +#include "dnssd.h" // @@ -32,9 +20,7 @@ typedef struct _http_uribuf_s // URI buffer { -#ifdef HAVE_AVAHI - AvahiSimplePoll *poll; // Poll state -#endif // HAVE_AVAHI + cups_dnssd_t *dnssd; // DNS-SD context char *buffer; // Pointer to buffer size_t bufsize; // Size of buffer http_resolve_t options; // Options passed to httpResolveURI @@ -116,15 +102,7 @@ static const char * const http_states[] = static const char *http_copy_decode(char *dst, const char *src, size_t dstsize, const char *term, bool decode); static char *http_copy_encode(char *dst, const char *src, char *dstend, const char *reserved, const char *term, bool encode); -#ifdef HAVE_MDNSRESPONDER -static void DNSSD_API http_resolve_cb(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullName, const char *hostTarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context); -#endif // HAVE_MDNSRESPONDER - -#ifdef HAVE_AVAHI -static void http_client_cb(AvahiClient *client, AvahiClientState state, void *simple_poll); -static int http_poll_cb(struct pollfd *pollfds, unsigned int num_pollfds, int timeout, void *context); -static void http_resolve_cb(AvahiServiceResolver *resolver, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *name, const char *type, const char *domain, const char *host_name, const AvahiAddress *address, uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *context); -#endif // HAVE_AVAHI +static void http_resolve_cb(cups_dnssd_resolve_t *res, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt); // @@ -1511,51 +1489,24 @@ httpResolveURI( // Resolve it as needed... if (strstr(hostname, "._tcp")) { -#ifdef HAVE_DNSSD - char *regtype, // Pointer to type in hostname - *domain, // Pointer to domain in hostname + time_t domain_time, // Domain lookup time, if any + end_time; // End time for resolve + cups_dnssd_t *dnssd; // DNS-SD context + uint32_t if_index; // Interface index + char name[256], // Service instance name + regtype[256], // Registration type + domain[256], // Domain name *uuid, // Pointer to UUID in URI *uuidend; // Pointer to end of UUID in URI _http_uribuf_t uribuf; // URI buffer -# ifdef HAVE_MDNSRESPONDER - DNSServiceRef ref, // DNS-SD master service reference - domainref = NULL,// DNS-SD service reference for domain - ippref = NULL, // DNS-SD service reference for network IPP - ippsref = NULL, // DNS-SD service reference for network IPPS - localref; // DNS-SD service reference for .local - int extrasent = 0; // Send the domain/IPP/IPPS resolves? - struct pollfd polldata; // Polling data -# elif defined(HAVE_AVAHI) - AvahiClient *client; // Client information - int error; // Status -# endif // HAVE_MDNSRESPONDER // Separate the hostname into service name, registration type, and domain... - for (regtype = strstr(hostname, "._tcp") - 2; regtype > hostname; regtype --) - { - if (regtype[0] == '.' && regtype[1] == '_') - { - // Found ._servicetype in front of ._tcp... - *regtype++ = '\0'; - break; - } - } - - if (regtype <= hostname) + if (!cupsDNSSDSeparateFullName(hostname, name, sizeof(name), regtype, sizeof(regtype), domain, sizeof(domain))) { DEBUG_puts("2httpResolveURI: Bad hostname, returning NULL"); return (NULL); } - for (domain = strchr(regtype, '.'); domain; domain = strchr(domain + 1, '.')) - { - if (domain[1] != '_') - break; - } - - if (domain) - *domain++ = '\0'; - if ((uuid = strstr(resource, "?uuid=")) != NULL) { *uuid = '\0'; @@ -1572,144 +1523,46 @@ httpResolveURI( uribuf.resource = resource; uribuf.uuid = uuid; - DEBUG_printf(("2httpResolveURI: Resolving hostname=\"%s\", regtype=\"%s\", domain=\"%s\"\n", hostname, regtype, domain)); + DEBUG_printf(("2httpResolveURI: Resolving name=\"%s\", regtype=\"%s\", domain=\"%s\"\n", name, regtype, domain)); uri = NULL; -# ifdef HAVE_MDNSRESPONDER - if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError) - { - uint32_t myinterface = kDNSServiceInterfaceIndexAny; - // Lookup on any interface - - if (!strcmp(scheme, "ippusb")) - myinterface = kDNSServiceInterfaceIndexLocalOnly; - - localref = ref; - if (DNSServiceResolve(&localref, kDNSServiceFlagsShareConnection, myinterface, hostname, regtype, "local.", http_resolve_cb, &uribuf) == kDNSServiceErr_NoError) - { - int fds; // Number of ready descriptors - time_t timeout, // Poll timeout - start_time = time(NULL),// Start time - end_time = start_time + 90; - // End time - - while (time(NULL) < end_time) - { - if (cb && !(*cb)(cb_data)) - { - DEBUG_puts("2httpResolveURI: callback returned 0 (stop)"); - break; - } - - // Wakeup every 2 seconds to emit a "looking for printer" message... - if ((timeout = end_time - time(NULL)) > 2) - timeout = 2; + if (!strcmp(scheme, "ippusb")) + if_index = CUPS_DNSSD_IF_INDEX_LOCAL; + else + if_index = CUPS_DNSSD_IF_INDEX_ANY; - polldata.fd = DNSServiceRefSockFD(ref); - polldata.events = POLLIN; + dnssd = cupsDNSSDNew(NULL, NULL); - if ((fds = poll(&polldata, 1, (int)(1000 * timeout))) < 0) - { - if (errno != EINTR && errno != EAGAIN) - { - DEBUG_printf(("2httpResolveURI: poll error: %s", strerror(errno))); - break; - } - } - else if (fds == 0) - { - // Wait 2 seconds for a response to the local resolve; if nothing - // comes in, do an additional domain resolution... - if (extrasent == 0 && domain && _cups_strcasecmp(domain, "local.")) - { - domainref = ref; - if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection, myinterface, hostname, regtype, domain, http_resolve_cb, &uribuf) == kDNSServiceErr_NoError) - extrasent = 1; - } - else if (extrasent == 0 && !strcmp(scheme, "ippusb")) - { - ippsref = ref; - if (DNSServiceResolve(&ippsref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexAny, hostname, "_ipps._tcp", domain, http_resolve_cb, &uribuf) == kDNSServiceErr_NoError) - extrasent = 1; - } - else if (extrasent == 1 && !strcmp(scheme, "ippusb")) - { - ippref = ref; - if (DNSServiceResolve(&ippref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexAny, hostname, "_ipp._tcp", domain, http_resolve_cb, &uribuf) == kDNSServiceErr_NoError) - extrasent = 2; - } - } - else - { - if (DNSServiceProcessResult(ref) == kDNSServiceErr_NoError && resolved_uri[0]) - { - uri = resolved_uri; - break; - } - } - } - - if (extrasent) - { - if (domainref) - DNSServiceRefDeallocate(domainref); - if (ippref) - DNSServiceRefDeallocate(ippref); - if (ippsref) - DNSServiceRefDeallocate(ippsref); - } + if (!cupsDNSSDResolveNew(dnssd, if_index, name, regtype, "local.", http_resolve_cb, &uribuf)) + { + cupsDNSSDDelete(dnssd); + return (NULL); + } - DNSServiceRefDeallocate(localref); - } + domain_time = time(NULL) + 2; + end_time = time(NULL) + 90; - DNSServiceRefDeallocate(ref); - } -# else // HAVE_AVAHI - if ((uribuf.poll = avahi_simple_poll_new()) != NULL) + while (!resolved_uri[0] && time(NULL) < end_time) { - avahi_simple_poll_set_func(uribuf.poll, http_poll_cb, NULL); - - if ((client = avahi_client_new(avahi_simple_poll_get(uribuf.poll), 0, http_client_cb, &uribuf, &error)) != NULL) + // Start the domain resolve as needed... + if (time(NULL) >= domain_time && _cups_strcasecmp(domain, "local.")) { - if (avahi_service_resolver_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, hostname, regtype, "local.", AVAHI_PROTO_UNSPEC, 0, http_resolve_cb, &uribuf) != NULL) - { - time_t start_time = time(NULL), - // Start time - end_time = start_time + 90; - // End time - int pstatus; // Poll status - - pstatus = avahi_simple_poll_iterate(uribuf.poll, 2000); - - if (pstatus == 0 && !resolved_uri[0] && domain && _cups_strcasecmp(domain, "local.")) - { - // Resolve for .local hasn't returned anything, try the listed - // domain... - avahi_service_resolver_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, hostname, regtype, domain, AVAHI_PROTO_UNSPEC, 0, http_resolve_cb, &uribuf); - } + cupsDNSSDResolveNew(dnssd, if_index, name, regtype, domain, http_resolve_cb, &uribuf); + domain_time = end_time; + } - while (!pstatus && !resolved_uri[0] && time(NULL) < end_time) - { - if ((pstatus = avahi_simple_poll_iterate(uribuf.poll, 2000)) != 0) - break; - } + // Sleep 1/4 second to allow time for resolve... + usleep(250000); - // Collect the result (if we got one). - if (resolved_uri[0]) - uri = resolved_uri; - } + if (resolved_uri[0]) + break; + } - avahi_client_free(client); - } + cupsDNSSDDelete(dnssd); - avahi_simple_poll_free(uribuf.poll); - } -# endif // HAVE_MDNSRESPONDER -#else // !HAVE_DNSSD - // No DNS-SD support... - uri = NULL; -#endif // HAVE_DNSSD + // Save the results of the resolve... + uri = *resolved_uri ? resolved_uri : NULL; } else { @@ -1724,35 +1577,6 @@ httpResolveURI( } -#ifdef HAVE_AVAHI -/* - * 'http_client_cb()' - Client callback for resolving URI. - */ - -static void -http_client_cb( - AvahiClient *client, // I - Client information - AvahiClientState state, // I - Current state - void *context) // I - Pointer to URI buffer -{ - DEBUG_printf(("7http_client_cb(client=%p, state=%d, context=%p)", client, - state, context)); - - /* - * If the connection drops, quit. - */ - - if (state == AVAHI_CLIENT_FAILURE) - { - _http_uribuf_t *uribuf = (_http_uribuf_t *)context; - // URI buffer - - avahi_simple_poll_quit(uribuf->poll); - } -} -#endif // HAVE_AVAHI - - /* * 'http_copy_decode()' - Copy and decode a URI. */ @@ -1875,147 +1699,100 @@ http_copy_encode(char *dst, // O - Destination buffer } -#ifdef HAVE_MDNSRESPONDER -/* - * 'http_resolve_cb()' - Build a device URI for the given service name. - */ +// +// 'http_resolve_cb()' - Build a device URI for the given service name. +// -static void DNSSD_API +static void http_resolve_cb( - DNSServiceRef sdRef, // I - Service reference - DNSServiceFlags flags, // I - Results flags - uint32_t interfaceIndex, // I - Interface number - DNSServiceErrorType errorCode, // I - Error, if any - const char *fullName, // I - Full service name - const char *hostTarget, // I - Hostname - uint16_t port, // I - Port number - uint16_t txtLen, // I - Length of TXT record - const unsigned char *txtRecord, // I - TXT record data - void *context) // I - Pointer to URI buffer + cups_dnssd_resolve_t *res, // I - Resolver + void *cb_data, // I - Pointer to URI buffer + cups_dnssd_flags_t flags, // I - Results flags + uint32_t if_index, // I - Interface index + const char *fullname, // I - Full service name + const char *host, // I - Hostname + uint16_t port, // I - Port number + size_t num_txt, // I - Number of TXT key/value pairs + cups_option_t *txt) // I - TXT key/value pairs { - _http_uribuf_t *uribuf = (_http_uribuf_t *)context; + _http_uribuf_t *uribuf = (_http_uribuf_t *)cb_data; // URI buffer const char *scheme, // URI scheme *hostptr, // Pointer into hostTarget *reskey, // "rp" or "rfo" *resdefault; // Default path - char resource[257], // Remote path - fqdn[256]; // FQDN of the .local name - const void *value; // Value from TXT record - uint8_t valueLen; // Length of value + char fqdn[256]; // FQDN of the .local name + const char *value, // Value from TXT record + *resource; // Resource path - DEBUG_printf(("4http_resolve_cb(sdRef=%p, flags=%x, interfaceIndex=%u, errorCode=%d, fullName=\"%s\", hostTarget=\"%s\", port=%u, txtLen=%u, txtRecord=%p, context=%p)", (void *)sdRef, flags, interfaceIndex, errorCode, fullName, hostTarget, port, txtLen, (void *)txtRecord, context)); - - /* - * If we have a UUID, compare it... - */ + DEBUG_printf(("4http_resolve_cb(res=%p, cb_data=%p, flags=%x, if_index=%u, fullname=\"%s\", host=\"%s\", port=%u, num_txt=%u, txt=%p)", (void *)res, cb_data, flags, if_index, fullname, host, port, (unsigned)num_txt, (void *)txt)); - if (uribuf->uuid && - (value = TXTRecordGetValuePtr(txtLen, txtRecord, "UUID", - &valueLen)) != NULL) + // If we have a UUID, compare it... + if (uribuf->uuid && (value = cupsGetOption("UUID", num_txt, txt)) != NULL) { - char uuid[256]; // UUID value - - memcpy(uuid, value, valueLen); - uuid[valueLen] = '\0'; - - if (_cups_strcasecmp(uuid, uribuf->uuid)) + if (_cups_strcasecmp(value, uribuf->uuid)) { - DEBUG_printf(("5http_resolve_cb: Found UUID %s, looking for %s.", uuid, - uribuf->uuid)); + DEBUG_printf(("5http_resolve_cb: Found UUID %s, looking for %s.", value, uribuf->uuid)); return; } } - /* - * Figure out the scheme from the full name... - */ - - if (strstr(fullName, "._ipps") || strstr(fullName, "._ipp-tls")) + // Figure out the scheme from the full name... + if (strstr(fullname, "._ipps") || strstr(fullname, "._ipp-tls")) scheme = "ipps"; - else if (strstr(fullName, "._ipp") || strstr(fullName, "._fax-ipp")) + else if (strstr(fullname, "._ipp") || strstr(fullname, "._fax-ipp")) scheme = "ipp"; - else if (strstr(fullName, "._http.")) + else if (strstr(fullname, "._http.")) scheme = "http"; - else if (strstr(fullName, "._https.")) + else if (strstr(fullname, "._https.")) scheme = "https"; - else if (strstr(fullName, "._printer.")) + else if (strstr(fullname, "._printer.")) scheme = "lpd"; - else if (strstr(fullName, "._pdl-datastream.")) + else if (strstr(fullname, "._pdl-datastream.")) scheme = "socket"; else scheme = "riousbprint"; - /* - * Extract the "remote printer" key from the TXT record... - */ - - if ((uribuf->options & HTTP_RESOLVE_FAXOUT) && - (!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps")) && - !TXTRecordGetValuePtr(txtLen, txtRecord, "printer-type", &valueLen)) + // Extract the "remote printer" key from the TXT record... + if ((uribuf->options & HTTP_RESOLVE_FAXOUT) && (!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps")) && !cupsGetOption("printer-type", num_txt, txt)) { reskey = "rfo"; - resdefault = "/ipp/faxout"; + resdefault = "ipp/faxout"; } else { reskey = "rp"; - resdefault = "/"; + resdefault = ""; } - if ((value = TXTRecordGetValuePtr(txtLen, txtRecord, reskey, - &valueLen)) != NULL) + if ((resource = cupsGetOption(reskey, num_txt, txt)) != NULL) { - if (((char *)value)[0] == '/') - { - /* - * Value (incorrectly) has a leading slash already... - */ - - memcpy(resource, value, valueLen); - resource[valueLen] = '\0'; - } - else + // Use the resource path from the TXT record... + if (*resource == '/') { - /* - * Convert to resource by concatenating with a leading "/"... - */ - - resource[0] = '/'; - memcpy(resource + 1, value, valueLen); - resource[valueLen + 1] = '\0'; + // Value (incorrectly) has a leading slash already... + resource ++; } } else { - /* - * Use the default value... - */ - - cupsCopyString(resource, resdefault, sizeof(resource)); + // Use the default resource path... + resource = resdefault; } - /* - * Lookup the FQDN if needed... - */ - - if ((uribuf->options & HTTP_RESOLVE_FQDN) && - (hostptr = hostTarget + strlen(hostTarget) - 7) > hostTarget && - !_cups_strcasecmp(hostptr, ".local.")) + // Lookup the FQDN if needed... + if ((uribuf->options & HTTP_RESOLVE_FQDN) && (hostptr = host + strlen(host) - 7) > host && !_cups_strcasecmp(hostptr, ".local.")) { - /* - * OK, we got a .local name but the caller needs a real domain. Start by - * getting the IP address of the .local name and then do reverse-lookups... - */ - + // OK, we got a .local name but the caller needs a real domain. Start by + // getting the IP address of the .local name and then do reverse-lookups... http_addrlist_t *addrlist, // List of addresses *addr; // Current address - DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", hostTarget)); + DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", host)); snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port)); - if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL) + if ((addrlist = httpAddrGetList(host, AF_UNSPEC, fqdn)) != NULL) { for (addr = addrlist; addr; addr = addr->next) { @@ -2025,18 +1802,15 @@ http_resolve_cb( { DEBUG_printf(("5http_resolve_cb: Found \"%s\".", fqdn)); - if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn || - _cups_strcasecmp(hostptr, ".local")) + if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn || _cups_strcasecmp(hostptr, ".local")) { - hostTarget = fqdn; + host = fqdn; break; } } #ifdef DEBUG else - DEBUG_printf(("5http_resolve_cb: \"%s\" did not resolve: %d", - httpAddrGetString(&(addr->addr), fqdn, sizeof(fqdn)), - error)); + DEBUG_printf(("5http_resolve_cb: \"%s\" did not resolve: %d", httpAddrGetString(&(addr->addr), fqdn, sizeof(fqdn)), error)); #endif // DEBUG } @@ -2044,262 +1818,11 @@ http_resolve_cb( } } - /* - * Assemble the final device URI... - */ - - if ((!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps")) && - !strcmp(uribuf->resource, "/cups")) - httpAssembleURIf(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme, NULL, hostTarget, ntohs(port), "%s?snmp=false", resource); + // Assemble the final URI... + if ((!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps")) && !strcmp(uribuf->resource, "/cups")) + httpAssembleURIf(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme, NULL, host, port, "/%s?snmp=false", resource); else - httpAssembleURI(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme, NULL, hostTarget, ntohs(port), resource); + httpAssembleURIf(HTTP_URI_CODING_ALL, uribuf->buffer, uribuf->bufsize, scheme, NULL, host, port, "/%s", resource); DEBUG_printf(("5http_resolve_cb: Resolved URI is \"%s\"...", uribuf->buffer)); } - -#elif defined(HAVE_AVAHI) -/* - * 'http_poll_cb()' - Wait for input on the specified file descriptors. - * - * Note: This function is needed because avahi_simple_poll_iterate is broken - * and always uses a timeout of 0 (!) milliseconds. - * (Avahi Ticket #364) - * - * @private@ - */ - -static int // O - Number of file descriptors matching -http_poll_cb( - struct pollfd *pollfds, // I - File descriptors - unsigned int num_pollfds, // I - Number of file descriptors - int timeout, // I - Timeout in milliseconds (used) - void *context) // I - User data (unused) -{ - (void)timeout; - (void)context; - - return (poll(pollfds, num_pollfds, 2000)); -} - - -/* - * 'http_resolve_cb()' - Build a device URI for the given service name. - */ - -static void -http_resolve_cb( - AvahiServiceResolver *resolver, // I - Resolver (unused) - AvahiIfIndex interface, // I - Interface index - AvahiProtocol protocol, // I - Network protocol (unused) - AvahiResolverEvent event, // I - Event (found, etc.) - const char *name, // I - Service name - const char *type, // I - Registration type - const char *domain, // I - Domain (unused) - const char *hostTarget, // I - Hostname - const AvahiAddress *address, // I - Address (unused) - uint16_t port, // I - Port number - AvahiStringList *txt, // I - TXT record - AvahiLookupResultFlags flags, // I - Lookup flags (unused) - void *context) // I - Pointer to URI buffer -{ - _http_uribuf_t *uribuf = (_http_uribuf_t *)context; - // URI buffer - const char *scheme, // URI scheme - *hostptr, // Pointer into hostTarget - *reskey, // "rp" or "rfo" - *resdefault; // Default path - char resource[257], // Remote path - fqdn[256]; // FQDN of the .local name - char ifname[IF_NAMESIZE]; - // Interface name - AvahiStringList *pair; // Current TXT record key/value pair - char *value; // Value for "rp" key - size_t valueLen = 0; // Length of "rp" key - - - DEBUG_printf(("4http_resolve_cb(resolver=%p, " - "interface=%d, protocol=%d, event=%d, name=\"%s\", " - "type=\"%s\", domain=\"%s\", hostTarget=\"%s\", address=%p, " - "port=%d, txt=%p, flags=%d, context=%p)", - resolver, interface, protocol, event, name, type, domain, - hostTarget, address, port, txt, flags, context)); - - if (event != AVAHI_RESOLVER_FOUND) - { - avahi_service_resolver_free(resolver); - avahi_simple_poll_quit(uribuf->poll); - return; - } - - /* - * If we have a UUID, compare it... - */ - - if (uribuf->uuid && (pair = avahi_string_list_find(txt, "UUID")) != NULL) - { - char uuid[256]; // UUID value - - avahi_string_list_get_pair(pair, NULL, &value, &valueLen); - - memcpy(uuid, value, valueLen); - uuid[valueLen] = '\0'; - - avahi_free(value); - - if (_cups_strcasecmp(uuid, uribuf->uuid)) - { - DEBUG_printf(("5http_resolve_cb: Found UUID %s, looking for %s.", uuid, - uribuf->uuid)); - return; - } - } - - /* - * Figure out the scheme from the full name... - */ - - if (!strncmp(type, "_ipps.", 6) || !strncmp(type, "_ipp-tls.", 9)) - scheme = "ipps"; - else if (!strncmp(type, "_ipp.", 5) || !strncmp(type, "_fax-ipp.", 9)) - scheme = "ipp"; - else if (!strncmp(type, "_http.", 6)) - scheme = "http"; - else if (!strncmp(type, "_https.", 7)) - scheme = "https"; - else if (!strncmp(type, "_printer.", 9)) - scheme = "lpd"; - else if (!strncmp(type, "_pdl-datastream.", 16)) - scheme = "socket"; - else - { - avahi_service_resolver_free(resolver); - avahi_simple_poll_quit(uribuf->poll); - return; - } - - /* - * Extract the remote resource key from the TXT record... - */ - - if ((uribuf->options & HTTP_RESOLVE_FAXOUT) && - (!strcmp(scheme, "ipp") || !strcmp(scheme, "ipps")) && - !avahi_string_list_find(txt, "printer-type")) - { - reskey = "rfo"; - resdefault = "/ipp/faxout"; - } - else - { - reskey = "rp"; - resdefault = "/"; - } - - if ((pair = avahi_string_list_find(txt, reskey)) != NULL) - { - avahi_string_list_get_pair(pair, NULL, &value, &valueLen); - - if (value[0] == '/') - { - /* - * Value (incorrectly) has a leading slash already... - */ - - memcpy(resource, value, valueLen); - resource[valueLen] = '\0'; - } - else - { - /* - * Convert to resource by concatenating with a leading "/"... - */ - - resource[0] = '/'; - memcpy(resource + 1, value, valueLen); - resource[valueLen + 1] = '\0'; - } - - avahi_free(value); - } - else - { - /* - * Use the default value... - */ - - cupsCopyString(resource, resdefault, sizeof(resource)); - } - - /* - * Get the name of the interface this is coming from... - */ - - if (!if_indextoname((unsigned int)interface, ifname)) - { - DEBUG_printf(("Unable to find interface name for interface %d: %s\n", interface, strerror(errno))); - ifname[0] = '\0'; - } - - if (!strcmp(ifname, "lo")) - { - /* - * If this service is registered on loopback interface ("lo"), force the host - * name to "localhost"... - */ - - DEBUG_puts("Service comes from loopback interface \"lo\", setting \"localhost\" as host name."); - hostTarget = "localhost"; - } - else if ((uribuf->options & HTTP_RESOLVE_FQDN) && - (hostptr = hostTarget + strlen(hostTarget) - 6) > hostTarget && - !_cups_strcasecmp(hostptr, ".local")) - { - /* - * OK, we got a .local name but the caller needs a real domain. Start by - * getting the IP address of the .local name and then do reverse-lookups... - */ - - http_addrlist_t *addrlist, // List of addresses - *addr; // Current address - - DEBUG_printf(("5http_resolve_cb: Looking up \"%s\".", hostTarget)); - - snprintf(fqdn, sizeof(fqdn), "%d", ntohs(port)); - if ((addrlist = httpAddrGetList(hostTarget, AF_UNSPEC, fqdn)) != NULL) - { - for (addr = addrlist; addr; addr = addr->next) - { - int error = getnameinfo(&(addr->addr.addr), (socklen_t)httpAddrGetLength(&(addr->addr)), fqdn, sizeof(fqdn), NULL, 0, NI_NAMEREQD); - - if (!error) - { - DEBUG_printf(("5http_resolve_cb: Found \"%s\".", fqdn)); - - if ((hostptr = fqdn + strlen(fqdn) - 6) <= fqdn || - _cups_strcasecmp(hostptr, ".local")) - { - hostTarget = fqdn; - break; - } - } -#ifdef DEBUG - else - DEBUG_printf(("5http_resolve_cb: \"%s\" did not resolve: %d", - httpAddrGetString(&(addr->addr), fqdn, sizeof(fqdn)), - error)); -#endif // DEBUG - } - - httpAddrFreeList(addrlist); - } - } - - /* - * Assemble the final device URI using the resolved hostname... - */ - - httpAssembleURI(HTTP_URI_CODING_ALL, uribuf->buffer, (int)uribuf->bufsize, scheme, NULL, hostTarget, port, resource); - DEBUG_printf(("5http_resolve_cb: Resolved URI is \"%s\".", uribuf->buffer)); - - avahi_simple_poll_quit(uribuf->poll); -} -#endif // HAVE_MDNSRESPONDER diff --git a/cups/testdnssd.c b/cups/testdnssd.c new file mode 100644 index 000000000..ecf6deeb6 --- /dev/null +++ b/cups/testdnssd.c @@ -0,0 +1,366 @@ +// +// DNS-SD API test program for CUPS. +// +// Copyright © 2022 by OpenPrinting. +// +// Licensed under Apache License v2.0. See the file "LICENSE" for more +// information. +// + +#include "test-internal.h" +#include "dnssd.h" +#include "thread.h" + + +// +// Local structures... +// + +typedef struct testdata_s // Test data structure +{ + cups_mutex_t mutex; // Mutex for access + cups_array_t *messages; // Messages from callbacks + size_t browse_count; // Number of browse callbacks + size_t error_count; // Number of error callbacks + size_t query_count; // Number of query callbacks + size_t resolve_count; // Number of resolve callbacks + size_t service_count; // Number of service callbacks +} testdata_t; + + +// +// Local functions... +// + +static void browse_cb(cups_dnssd_browse_t *browse, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *name, const char *regtype, const char *domain); +static void error_cb(void *cb_data, const char *message); +static void query_cb(cups_dnssd_query_t *query, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, uint16_t rrtype, const void *qdata, uint16_t qlen); +static void resolve_cb(cups_dnssd_resolve_t *res, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt); +static void service_cb(cups_dnssd_service_t *service, void *cb_data, cups_dnssd_flags_t flags); +static void usage(const char *arg); + + +// +// 'main()' - Main entry. +// + +int // O - Exit status +main(int argc, // I - Number of command-line arguments + char *argv[]) // I - Command-line arguments +{ + int i, // Looping var + ret = 0; // Return value + cups_dnssd_t *dnssd; // DNS-SD context + cups_dnssd_browse_t *browse; // DNS-SD browse request +// cups_dnssd_query_t *query; // DNS-SD query request + cups_dnssd_resolve_t *resolve; // DNS-SD resolve request + cups_dnssd_service_t *service; // DNS-SD service registration + size_t num_txt; // Number of TXT record key/value pairs + cups_option_t *txt; // TXT record key/value pairs + testdata_t testdata; // Test data + + + // Clear test data... + memset(&testdata, 0, sizeof(testdata)); + testdata.messages = cupsArrayNew(NULL, NULL, NULL, 0, (cups_acopy_cb_t)strdup, (cups_afree_cb_t)free); + + if (argc == 1) + { + // Do unit tests... + testBegin("cupsDNSSDNew"); + if ((dnssd = cupsDNSSDNew(error_cb, &testdata)) != NULL) + testEnd(true); + else + return (1); + + testBegin("cupsDNSSDBrowseNew(_ipp._tcp)"); + if ((browse = cupsDNSSDBrowseNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "_ipp._tcp", NULL, browse_cb, &testdata)) != NULL) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + testBegin("cupsDNSSDBrowseGetContext"); + testEnd(cupsDNSSDBrowseGetContext(browse) == dnssd); + + testBegin("cupsDNSSDBrowseNew(_http._tcp)"); + if ((browse = cupsDNSSDBrowseNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "_http._tcp", NULL, browse_cb, &testdata)) != NULL) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + testBegin("cupsDNSSDBrowseGetContext"); + testEnd(cupsDNSSDBrowseGetContext(browse) == dnssd); + + testBegin("cupsDNSSDServiceNew(Test Printer)"); + if ((service = cupsDNSSDServiceNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "Test Printer", service_cb, &testdata)) != NULL) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + num_txt = cupsAddOption("rp", "ipp/print", 0, &txt); + + testBegin("cupsDNSSDServiceAdd(_http._tcp)"); + if (cupsDNSSDServiceAdd(service, "_http._tcp,_printer", /*host*/NULL, /*domain*/NULL, 631, /*num_txt*/0, /*txt*/NULL)) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + testBegin("cupsDNSSDServiceAdd(_ipp._tcp)"); + if (cupsDNSSDServiceAdd(service, "_ipp._tcp,_print", /*host*/NULL, /*domain*/NULL, 631, num_txt, txt)) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + testBegin("cupsDNSSDServicePublish"); + testEnd(cupsDNSSDServicePublish(service)); + + testBegin("cupsDNSSDServiceGetContext"); + testEnd(cupsDNSSDServiceGetContext(service) == dnssd); + + cupsFreeOptions(num_txt, txt); + + testBegin("cupsDNSSDResolveNew(Test Printer._ipp._tcp.local.)"); + if ((resolve = cupsDNSSDResolveNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, "Test Printer", "_ipp._tcp", "local.", resolve_cb, &testdata)) != NULL) + { + testEnd(true); + } + else + { + ret = 1; + goto done; + } + + testBegin("cupsDNSSDResolveGetContext"); + testEnd(cupsDNSSDResolveGetContext(resolve) == dnssd); + + testBegin("Wait for callbacks"); + + for (i = 0; i < 30; i ++) + { + if (testdata.service_count != 0 && testdata.browse_count != 0 && testdata.resolve_count != 0) + break; + + testProgress(); + sleep(1); + } + + testEnd(i < 30); + + done: + + cupsDNSSDDelete(dnssd); + + const char *message; // Current message + + for (message = (const char *)cupsArrayGetFirst(testdata.messages); message; message = (const char *)cupsArrayGetNext(testdata.messages)) + puts(message); + + cupsArrayDelete(testdata.messages); + } + else + { + usage(argv[1]); + } + + return (ret); +} + + +// +// 'browse_cb()' - Record browse request callback usage. +// + +static void +browse_cb( + cups_dnssd_browse_t *browse, // I - Browse request + void *cb_data, // I - Callback data + cups_dnssd_flags_t flags, // I - Bit flags + uint32_t if_index, // I - Interface index + const char *name, // I - Service name + const char *regtype, // I - Registration type + const char *domain) // I - Domain +{ + testdata_t *data = (testdata_t *)cb_data; + // Test data + char message[1024]; // Message string + char fullname[1024]; // Full service name + + + snprintf(message, sizeof(message), "B flags=%02X if_index=%u name=\"%s\" regtype=\"%s\" domain=\"%s\"", flags, if_index, name, regtype, domain); + + cupsDNSSDResolveNew(cupsDNSSDBrowseGetContext(browse), CUPS_DNSSD_IF_INDEX_ANY, name, regtype, domain, resolve_cb, cb_data); + + cupsDNSSDAssembleFullName(fullname, sizeof(fullname), name, regtype, domain); + cupsDNSSDQueryNew(cupsDNSSDBrowseGetContext(browse), CUPS_DNSSD_IF_INDEX_ANY, fullname, CUPS_DNSSD_RRTYPE_TXT, query_cb, cb_data); + + cupsMutexLock(&data->mutex); + cupsArrayAdd(data->messages, message); + data->browse_count ++; + cupsMutexUnlock(&data->mutex); +} + + +// +// 'error_cb()' - Display an error. +// + +static void +error_cb(void *cb_data, // I - Callback data + const char *message) // I - Error message +{ + testdata_t *data = (testdata_t *)cb_data; + // Test data + + + testEndMessage(false, "%s", message); + + cupsMutexLock(&data->mutex); + data->error_count ++; + cupsMutexUnlock(&data->mutex); +} + + +// +// 'query_cb()' - Record query request callback usage. +// + +static void +query_cb( + cups_dnssd_query_t *query, // I - Query request + void *cb_data, // I - Callback data + cups_dnssd_flags_t flags, // I - Flags + uint32_t if_index, // I - Interface index + const char *fullname, // I - Full service name + uint16_t rrtype, // I - Record type + const void *qdata, // I - Record data + uint16_t qlen) // I - Length of record data +{ + testdata_t *data = (testdata_t *)cb_data; + // Test data + uint16_t i; // Looping var + char message[2048], // Message string + *mptr; // Pointer into message string + const unsigned char *qptr; // Pointer into record data + + + (void)query; + + snprintf(message, sizeof(message), "Q flags=%02X if_index=%u fullname=\"%s\" rrtype=%u qlen=%u qdata=<", flags, if_index, fullname, rrtype, qlen); + for (mptr = message + strlen(message), i = 0, qptr = (const unsigned char *)qdata; i < qlen; i ++, mptr += strlen(mptr), qptr ++) + snprintf(mptr, sizeof(message) - (size_t)(mptr - message), "%02X", *qptr); + if (mptr < (message + sizeof(message) - 1)) + { + *mptr++ = '>'; + *mptr = '\0'; + } + + cupsMutexLock(&data->mutex); + cupsArrayAdd(data->messages, message); + data->query_count ++; + cupsMutexUnlock(&data->mutex); +} + + +// +// 'resolve_cb()' - Record resolve request callback usage. +// + +static void +resolve_cb( + cups_dnssd_resolve_t *res, // I - Resolve request + void *cb_data, // I - Callback data + cups_dnssd_flags_t flags, // I - Flags + uint32_t if_index, // I - Interface index + const char *fullname, // I - Full service name + const char *host, // I - Hostname + uint16_t port, // I - Port number + size_t num_txt, // I - Number of key/value pairs in TXT record + cups_option_t *txt) // I - Key/value pairs +{ + testdata_t *data = (testdata_t *)cb_data; + // Test data + size_t i; // Looping var + char message[2048], // Message string + *mptr; // Pointer into message string + const char *prefix = " txt="; // Prefix string + + + (void)res; + + snprintf(message, sizeof(message), "R flags=%02X if_index=%u fullname=\"%s\" host=\"%s\" port=%u num_txt=%u", flags, if_index, fullname, host, port, (unsigned)num_txt); + for (mptr = message + strlen(message), i = 0; i < num_txt; i ++, mptr += strlen(mptr)) + { + snprintf(mptr, sizeof(message) - (size_t)(mptr - message), "%s\"%s=%s\"", prefix, txt[i].name, txt[i].value); + prefix = ","; + } + + cupsMutexLock(&data->mutex); + cupsArrayAdd(data->messages, message); + data->resolve_count ++; + cupsMutexUnlock(&data->mutex); +} + + +// +// 'service_cb()' - Record service registration callback usage. +// + +static void +service_cb( + cups_dnssd_service_t *service, // I - Service registration + void *cb_data, // I - Callback data + cups_dnssd_flags_t flags) // I - Flags +{ + testdata_t *data = (testdata_t *)cb_data; + // Test data + char message[1024]; // Message string + + + snprintf(message, sizeof(message), "S flags=%02X name=\"%s\"", flags, cupsDNSSDServiceGetName(service)); + + cupsMutexLock(&data->mutex); + cupsArrayAdd(data->messages, message); + data->service_count ++; + cupsMutexUnlock(&data->mutex); +} + + +// +// 'usage()' - Show program usage. +// + +static void +usage(const char *arg) // I - Argument for usage message +{ + if (arg) + printf("testdnssd: Unknown option \"%s\".\n", arg); + + puts("Usage:"); + + exit(arg != NULL); +} diff --git a/cups.pc.in b/cups3.pc.in similarity index 100% rename from cups.pc.in rename to cups3.pc.in diff --git a/doc/cupspm.epub b/doc/cupspm.epub index f8c0ea659..36d082898 100644 Binary files a/doc/cupspm.epub and b/doc/cupspm.epub differ diff --git a/doc/cupspm.html b/doc/cupspm.html index fa6b7cfc3..fe2165313 100644 --- a/doc/cupspm.html +++ b/doc/cupspm.html @@ -319,6 +319,29 @@

Contents

  • cupsCopyDestInfo
  • cupsCopyString
  • cupsCreateDestJob
  • +
  • cupsDNSSDAssembleFullName
  • +
  • cupsDNSSDBrowseDelete
  • +
  • cupsDNSSDBrowseGetContext
  • +
  • cupsDNSSDBrowseNew
  • +
  • cupsDNSSDDecodeTXT
  • +
  • cupsDNSSDDelete
  • +
  • cupsDNSSDGetConfigChanges
  • +
  • cupsDNSSDGetHostName
  • +
  • cupsDNSSDNew
  • +
  • cupsDNSSDQueryDelete
  • +
  • cupsDNSSDQueryGetContext
  • +
  • cupsDNSSDQueryNew
  • +
  • cupsDNSSDResolveDelete
  • +
  • cupsDNSSDResolveGetContext
  • +
  • cupsDNSSDResolveNew
  • +
  • cupsDNSSDSeparateFullName
  • +
  • cupsDNSSDServiceAdd
  • +
  • cupsDNSSDServiceDelete
  • +
  • cupsDNSSDServiceGetContext
  • +
  • cupsDNSSDServiceGetName
  • +
  • cupsDNSSDServiceNew
  • +
  • cupsDNSSDServicePublish
  • +
  • cupsDNSSDServiceSetLocation
  • cupsDirClose
  • cupsDirOpen
  • cupsDirRead
  • @@ -382,6 +405,7 @@

    Contents

  • cupsGetNamedDest
  • cupsGetOption
  • cupsGetPassword
  • +
  • cupsGetRand
  • cupsGetResponse
  • cupsGetServer
  • cupsGetUser
  • @@ -672,6 +696,17 @@

    Contents

  • cups_dest_t
  • cups_dinfo_t
  • cups_dir_t
  • +
  • cups_dnssd_browse_cb_t
  • +
  • cups_dnssd_error_cb_t
  • +
  • cups_dnssd_flags_t
  • +
  • cups_dnssd_query_cb_t
  • +
  • cups_dnssd_query_t
  • +
  • cups_dnssd_resolve_cb_t
  • +
  • cups_dnssd_resolve_t
  • +
  • cups_dnssd_browse_t
  • +
  • cups_dnssd_service_cb_t
  • +
  • cups_dnssd_service_t
  • +
  • cups_dnssd_t
  • cups_edge_t
  • cups_file_t
  • cups_job_t
  • @@ -686,7 +721,6 @@

    Contents

  • cups_page_header_t
  • cups_password_cb_t
  • cups_ptype_t
  • -
  • cups_raster_cb_t
  • cups_raster_mode_t
  • cups_raster_t
  • cups_rwlock_t
  • @@ -749,6 +783,8 @@

    Contents

  • cups_bool_e
  • cups_cspace_e
  • cups_cut_e
  • +
  • cups_dnssd_flags_e
  • +
  • cups_dnssd_rrtype_e
  • cups_edge_e
  • cups_jog_e
  • cups_mediapos_e
  • @@ -831,11 +867,11 @@

    Compiling Progra

    Compiling with Xcode

    In Xcode, choose New Project... from the File menu (or press SHIFT+CMD+N), then select the Command Line Tool under the macOS Application project type. Click Next and enter a name for the project, for example "firstcups". Click Next and choose a project directory. The click Next to create the project.

    -

    In the project window, click on the Build Phases group and expand the Link Binary with Libraries section. Click +, type "libcups" to show the library, and then double-click on libcups.tbd.

    +

    In the project window, click on the Build Phases group and expand the Link Binary with Libraries section. Click +, choose "Other...", and then find and choose the libcups3.dylib file in /usr/local/lib.

    Finally, click on the main.c file in the sidebar and copy the example program to the file. Build and run (CMD+R) to see the list of destinations.

    Compiling with GCC

    From the command-line, create a file called simple.c using your favorite editor, copy the example to this file, and save. Then run the following command to compile it with GCC and run it:

    -
    gcc -o simple `pkg-config --cflags cups` simple.c `pkg-config --libs cups`
    +
    gcc -o simple `pkg-config --cflags cups3` simple.c `pkg-config --libs cups3`
     ./simple
     

    The pkg-config command provides the compiler flags (pkg-config --cflags cups) and libraries (pkg-config --libs cups) needed for the local system.

    @@ -2070,9 +2106,10 @@

    Discussion

    int // Return -1 if a < b, 0 if a == b, and 1 if a > b compare_cb(void *a, void *b, void *d) { -... "a" and "b" are the elements, "d" is the user data pointer + ... "a" and "b" are the elements, "d" is the user data pointer }
    + The hash callback function ("hf") is used to implement cached lookups with the specified hash size ("hsize"). The function receives a pointer to an element and the user data pointer ("d") and returns an unsigned integer @@ -2083,9 +2120,10 @@

    Discussion

    size_t // Return hash value from 0 to (hashsize - 1) hash_cb(void *e, void *d) { -... "e" is the element, "d" is the user data pointer + ... "e" is the element, "d" is the user data pointer } + The copy callback function ("cf") is used to automatically copy/retain elements when added to the array or the array is copied with cupsArrayDup. The function receives a pointer to the element and the @@ -2095,9 +2133,10 @@

    Discussion

    void * // Return pointer to copied/retained element or NULL copy_cb(void *e, void *d) { -... "e" is the element, "d" is the user data pointer + ... "e" is the element, "d" is the user data pointer } + Finally, the free callback function ("cf") is used to automatically free/release elements when removed or the array is deleted. The function receives a pointer to the element and the user data pointer ("d"). @@ -2106,9 +2145,9 @@

    Discussion

    void free_cb(void *e, void *d) { -... "e" is the element, "d" is the user data pointer + ... "e" is the element, "d" is the user data pointer } -``` +

    cupsArrayNewStrings

    Create a new array of delimited strings.

    @@ -2216,7 +2255,7 @@

    Return Value

    Count or -1 on error

    cupsCheckDestSupported

    Check that the option and value are supported -by the destination.

    + by the destination.

    bool cupsCheckDestSupported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);

    Parameters

    @@ -2369,7 +2408,7 @@

    Discussion

    responsible for calling cupsFreeDests on the returned object(s).

    cupsCopyDestConflicts

    Get conflicts and resolutions for a new -option/value pair.

    + option/value pair.

    int cupsCopyDestConflicts(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, size_t num_options, cups_option_t *options, const char *new_option, const char *new_value, size_t *num_conflicts, cups_option_t **conflicts, size_t *num_resolved, cups_option_t **resolved);

    Parameters

    @@ -2416,7 +2455,7 @@

    Discussion

    to 0 and NULL, respectively, then the conflict cannot be resolved.

    cupsCopyDestInfo

    Get the supported values/capabilities for the -destination.

    + destination.

    cups_dinfo_t *cupsCopyDestInfo(http_t *http, cups_dest_t *dest);

    Parameters

    @@ -2472,6 +2511,467 @@

    Return Value

    Discussion

    Returns IPP_STATUS_OK or IPP_STATUS_OK_SUBST on success, saving the job ID in the variable pointed to by "job_id".

    +

    cupsDNSSDAssembleFullName

    +

    Create a full service name from the instance + name, registration type, and domain.

    +

    +bool cupsDNSSDAssembleFullName(char *fullname, size_t fullsize, const char *name, const char *type, const char *domain);

    +

    Parameters

    + + + + + + + + + + + +
    fullnameBuffer for full name
    fullsizeSize of buffer
    nameService instance name
    typeRegistration type
    domainDomain
    +

    Return Value

    +

    true on success, false on failure

    +

    Discussion

    +

    This function combines an instance name ("Example Name"), registration type +("_ipp._tcp"), and domain ("local.") to create a properly escaped full +service name ("Example032Name._ipp._tcp.local.").

    +

    cupsDNSSDBrowseDelete

    +

    Cancel and delete a browse request.

    +

    +void cupsDNSSDBrowseDelete(cups_dnssd_browse_t *browse);

    +

    Parameters

    + + + +
    browseBrowse request
    +

    cupsDNSSDBrowseGetContext

    +

    Get the DNS-SD context for the browse request.

    +

    +cups_dnssd_t *cupsDNSSDBrowseGetContext(cups_dnssd_browse_t *browse);

    +

    Parameters

    + + + +
    browseBrowse request
    +

    Return Value

    +

    Context or NULL

    +

    cupsDNSSDBrowseNew

    +

    Create a new DNS-SD browse request.

    +

    +cups_dnssd_browse_t *cupsDNSSDBrowseNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *types, const char *domain, cups_dnssd_browse_cb_t browse_cb, void *cb_data);

    +

    Parameters

    + + + + + + + + + + + + + +
    dnssdDNS-SD context
    if_indexInterface index, CUPS_DNSSD_IF_ANY, or CUPS_DNSSD_IF_LOCAL
    typesService types
    domainDomain name or NULL for default
    browse_cbBrowse callback function
    cb_dataBrowse callback data
    +

    Return Value

    +

    Browse request or NULL on error

    +

    Discussion

    +

    This function creates a new DNS-SD browse request for the specified service +types and optional domain and interface index. The "types" argument can be a +single service type ("_ipp._tcp") or a service type and comma-delimited list +of sub-types ("_ipp._tcp,_print,_universal").
    +
    +Newly discovered services are reported using the required browse callback +function, with the "flags" argument set to CUPS_DNSSD_FLAGS_ADD for newly +discovered services, CUPS_DNSSD_FLAGS_NONE for removed services, or +CUPS_DNSSD_FLAGS_ERROR on an error: + +

    +void
    +browse_cb(
    +    cups_dnssd_browse_t *browse,
    +    void                *cb_data,
    +    cups_dnssd_flags_t  flags,
    +    uint32_t            if_index,
    +    const char          *name,
    +    const char          *regtype,
    +    const char          *domain)
    +{
    +    // Process added/removed service
    +}
    +
    +

    +

    cupsDNSSDDecodeTXT

    +

    Decode a TXT record into key/value pairs.

    +

    +size_t cupsDNSSDDecodeTXT(const unsigned char *txtrec, uint16_t txtlen, cups_option_t **txt);

    +

    Parameters

    + + + + + + + +
    txtrecTXT record data
    txtlenTXT record length
    txtKey/value pairs
    +

    Return Value

    +

    Number of key/value pairs

    +

    Discussion

    +

    This function converts the DNS TXT record encoding of key/value pairs into +cups_option_t elements that can be accessed using the cupsGetOption +function and freed using the cupsFreeOptions function.

    +

    cupsDNSSDDelete

    +

    Delete a DNS-SD context and all its requests.

    +

    +void cupsDNSSDDelete(cups_dnssd_t *dnssd);

    +

    Parameters

    + + + +
    dnssdDNS-SD context
    +

    cupsDNSSDGetConfigChanges

    +

    Get the number of host name/network + configuration changes seen.

    +

    +size_t cupsDNSSDGetConfigChanges(cups_dnssd_t *dnssd);

    +

    Parameters

    + + + +
    dnssdDNS-SD context
    +

    Return Value

    +

    Number of host name changes

    +

    Discussion

    +

    This function returns the number of host name or network configuration +changes that have been seen since the context was created. The value can be +used to track when local services need to be updated. Registered services +will also get a callback with the CUPS_DNSSD_FLAGS_HOST_CHANGE bit set in +the "flags" argument for host name changes and/or +CUPS_DNSSD_FLAGS_NETWORK_CHANGE for network changes.

    +

    cupsDNSSDGetHostName

    +

    Get the current mDNS host name for the system.

    +

    +const char *cupsDNSSDGetHostName(cups_dnssd_t *dnssd, char *buffer, size_t bufsize);

    +

    Parameters

    + + + + + + + +
    dnssdDNS-SD context
    bufferHost name buffer
    bufsizeSize of host name buffer
    +

    Return Value

    +

    Local host name or NULL for none

    +

    Discussion

    +

    This function gets the current mDNS (".local") host name for the system.

    +

    cupsDNSSDNew

    +

    Create a new DNS-SD context.

    +

    +cups_dnssd_t *cupsDNSSDNew(cups_dnssd_error_cb_t error_cb, void *cb_data);

    +

    Parameters

    + + + + + +
    error_cbError callback function
    cb_dataError callback data
    +

    Return Value

    +

    DNS-SD context

    +

    Discussion

    +

    This function creates a new DNS-SD context for browsing, querying, resolving, +and/or registering services. Call cupsDNSSDDelete to stop any pending +browses, queries, or resolves, unregister any services, and free the DNS-SD +context.

    +

    cupsDNSSDQueryDelete

    +

    Cancel and delete a query request.

    +

    +void cupsDNSSDQueryDelete(cups_dnssd_query_t *query);

    +

    Parameters

    + + + +
    queryQuery request
    +

    cupsDNSSDQueryGetContext

    +

    Get the DNS-SD context for the query request.

    +

    +cups_dnssd_t *cupsDNSSDQueryGetContext(cups_dnssd_query_t *query);

    +

    Parameters

    + + + +
    queryQuery request
    +

    Return Value

    +

    DNS-SD context or NULL

    +

    cupsDNSSDQueryNew

    +

    Create a new query request.

    +

    +cups_dnssd_query_t *cupsDNSSDQueryNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *fullname, uint16_t rrtype, cups_dnssd_query_cb_t query_cb, void *cb_data);

    +

    Parameters

    + + + + + + + + + + + + + +
    dnssdDNS-SD context
    if_indexInterface index or CUPS_DNSSD_IF_ANY or CUPS_DNSSD_IF_LOCAL
    fullnameFull DNS name including types and domain
    rrtypeRecord type to query (CUPS_DNSSD_RRTYPE_TXT, etc.)
    query_cbQuery callback function
    cb_dataQuery callback data
    +

    Return Value

    +

    Query request or NULL on error

    +

    Discussion

    +

    This function creates a new DNS-SD query request for the specified full +service name and DNS record type. The "fullname" parameter specifies the +full DNS name of the service (instance name, type, and domain) being queried. +Responses to the query are reported using the required query callback +function with the "flags" argument set to CUPS_DNSSD_FLAGS_NONE on success +or CUPS_DNSSD_FLAGS_ERROR on error: + +

    +void
    +query_cb(
    +    cups_dnssd_query_t *query,
    +    void               *cb_data,
    +    cups_dnssd_flags_t flags,
    +    uint32_t           if_index,
    +    const char         *fullname,
    +    uint16_t           rrtype,
    +    const void         *qdata,
    +    uint16_t           qlen)
    +{
    +    // Process query record
    +}
    +
    +

    +

    cupsDNSSDResolveDelete

    +

    Cancel and free a resolve request.

    +

    +void cupsDNSSDResolveDelete(cups_dnssd_resolve_t *res);

    +

    Parameters

    + + + +
    resResolve request
    +

    cupsDNSSDResolveGetContext

    +

    Get the DNS-SD context for the resolve request.

    +

    +cups_dnssd_t *cupsDNSSDResolveGetContext(cups_dnssd_resolve_t *resolve);

    +

    Parameters

    + + + +
    resolveResolve request
    +

    Return Value

    +

    DNS-SD context or NULL

    +

    cupsDNSSDResolveNew

    +

    Create a new DNS-SD resolve request.

    +

    +cups_dnssd_resolve_t *cupsDNSSDResolveNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *name, const char *type, const char *domain, cups_dnssd_resolve_cb_t resolve_cb, void *cb_data);

    +

    Parameters

    + + + + + + + + + + + + + + + +
    dnssdDNS-SD context
    if_indexInterface index or CUPS_DNSSD_IF_ANY or CUPS_DNSSD_IF_LOCAL
    nameService name
    typeService type
    domainDomain name or NULL for default
    resolve_cbResolve callback function
    cb_dataResolve callback data
    +

    Return Value

    +

    Resolve request or NULL on error

    +

    Discussion

    +

    This function creates a new DNS-SD resolver for the specified instance name, +service type, and optional domain and interface index. Resikved services +are reported using the required resolve callback function, with the "flags" +argument set to CUPS_DNSSD_FLAGS_NONE on success or +CUPS_DNSSD_FLAGS_ERROR on error: + +

    +void
    +resolve_cb(
    +    cups_dnssd_resolve_t *resolve,
    +    void                 *cb_data,
    +    cups_dnssd_flags_t   flags,
    +    uint32_t             if_index,
    +    const char           *fullname,
    +    const char           *host,
    +    uint16_t             port,
    +    size_t               num_txt,
    +    cups_option_t        *txt)
    +{
    +    // Process resolved service
    +}
    +
    +

    +

    cupsDNSSDSeparateFullName

    +

    Separate a full service name into an instance + name, registration type, and domain.

    +

    +bool cupsDNSSDSeparateFullName(const char *fullname, char *name, size_t namesize, char *type, size_t typesize, char *domain, size_t domainsize);

    +

    Parameters

    + + + + + + + + + + + + + + + +
    fullnameFull service name
    nameInstance name buffer
    namesizeSize of instance name buffer
    typeRegistration type buffer
    typesizeSize of registration type buffer
    domainDomain name buffer
    domainsizeSize of domain name buffer
    +

    Return Value

    +

    true on success, false on error

    +

    Discussion

    +

    This function separates a full service name such as +"Example032Name._ipp._tcp.local.") into its instance name ("Example Name"), +registration type ("_ipp._tcp"), and domain ("local.").

    +

    cupsDNSSDServiceAdd

    +

    Add a service instance.

    +

    +bool cupsDNSSDServiceAdd(cups_dnssd_service_t *service, const char *types, const char *domain, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt);

    +

    Parameters

    + + + + + + + + + + + + + + + +
    serviceService
    typesService types
    domainDomain name or NULL for default
    hostHost name or NULL for default
    portPort number or 0 for none
    num_txtNumber of TXT record values
    txtTXT record values
    +

    Return Value

    +

    true on success, false on failure

    +

    Discussion

    +

    This function adds a service instance for the specified service types, +domain, host, and port. The "types" argument can be a single service type +("_ipp._tcp") or a service type and comma-delimited list of sub-types +("_ipp._tcp,_print,_universal").
    +
    +Call the cupsDNSSDServicePublish function after all service instances +have been added.

    +

    cupsDNSSDServiceDelete

    +

    Cancel and free a service registration.

    +

    +void cupsDNSSDServiceDelete(cups_dnssd_service_t *service);

    +

    Parameters

    + + + +
    serviceService
    +

    cupsDNSSDServiceGetContext

    +

    Get the DNS-SD context for the service + registration.

    +

    +cups_dnssd_t *cupsDNSSDServiceGetContext(cups_dnssd_service_t *service);

    +

    Parameters

    + + + +
    serviceService registration
    +

    Return Value

    +

    DNS-SD context or NULL

    +

    cupsDNSSDServiceGetName

    +

    Get the service instance name for the service registration.

    +

    +const char *cupsDNSSDServiceGetName(cups_dnssd_service_t *service);

    +

    Parameters

    + + + +
    serviceService registration
    +

    Return Value

    +

    Service instance name

    +

    cupsDNSSDServiceNew

    +

    Create a new named service.

    +

    +cups_dnssd_service_t *cupsDNSSDServiceNew(cups_dnssd_t *dnssd, uint32_t if_index, const char *name, cups_dnssd_service_cb_t cb, void *cb_data);

    +

    Parameters

    + + + + + + + + + + + +
    dnssdDNS-SD context
    if_indexInterface index, CUPS_DNSSD_IF_ANY, or CUPS_DNSSD_IF_LOCAL
    nameName of service
    cbService registration callback function
    cb_dataService registration callback data
    +

    Return Value

    +

    Service or NULL on error

    +

    Discussion

    +

    This function creates a new DNS-SD service registration for the given service +instance name and interface. Specific services using the name are added +using the cupsDNSSDServiceAdd function.
    +
    +The required service callback is called for select events, with the "flags" +argument set to CUPS_DNSSD_FLAGS_NONE for a successful registration, +CUPS_DNSSD_FLAGS_COLLISION when there is a name collision, or +CUPS_DNSSD_FLAGS_ERROR when there is a problem completing the service +registration.

    +

    cupsDNSSDServicePublish

    +

    Publish a service.

    +

    +bool cupsDNSSDServicePublish(cups_dnssd_service_t *service);

    +

    Parameters

    + + + +
    serviceService
    +

    Return Value

    +

    true on success, false on failure

    +

    Discussion

    +

    This function publishes the DNS-SD services added using the +cupsDNSSDServiceAdd function.

    +

    cupsDNSSDServiceSetLocation

    +

    Set the geolocation (LOC record) of a + service.

    +

    +bool cupsDNSSDServiceSetLocation(cups_dnssd_service_t *service, const char *geo_uri);

    +

    Parameters

    + + + + + +
    serviceService
    geo_uriGeolocation as a 'geo:' URI
    +

    Return Value

    +

    true on success, false on failure

    +

    Discussion

    +

    This function sets the geolocation of a service using a 'geo:' URI (RFC 5870) +of the form +'geo:LATITUDE,LONGITUDE[,ALTITUDE][;crs=CRSLABEL][;u=UNCERTAINTY]'. The +specified coordinates and uncertainty are converted into a DNS LOC record +for the service name label. Only the "wgs84" CRSLABEL string is supported.
    +
    +You must call this function prior to cupsDNSSDServiceAdd.

    cupsDirClose

    Close a directory.

    @@ -2762,7 +3262,7 @@

    Return Value

    Line read or NULL on end of file or error

    cupsFileGetLine

    Get a CR and/or LF-terminated line that may -contain binary data.

    + contain binary data.

    size_t cupsFileGetLine(cups_file_t *fp, char *buf, size_t buflen);

    Parameters

    @@ -3130,7 +3630,7 @@

    Discussion

    Returns IPP_STATUS_OK or IPP_STATUS_OK_SUBST on success.

    cupsFreeDestInfo

    Free destination information obtained using -cupsCopyDestInfo.

    + cupsCopyDestInfo.

    void cupsFreeDestInfo(cups_dinfo_t *dinfo);

    Parameters

    @@ -3212,7 +3712,7 @@

    Discussion

    supported destinations for the current user.

    cupsGetDestMediaByIndex

    Get a media name, dimension, and margins for a -specific size.

    + specific size.

    bool cupsGetDestMediaByIndex(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, size_t n, unsigned flags, cups_size_t *size);

    Parameters

    @@ -3271,7 +3771,7 @@

    Discussion

  • CUPS_MEDIA_FLAGS_EXACT: find an exact match for the size, and
  • CUPS_MEDIA_FLAGS_READY: if the printer supports media sensing, find the -size amongst the "ready" media.
  • + size amongst the "ready" media.

    The matching result (if any) is returned in the cups_size_t structure.

    @@ -3313,14 +3813,14 @@

    Discussion

  • CUPS_MEDIA_FLAGS_EXACT: find an exact match for the size, and
  • CUPS_MEDIA_FLAGS_READY: if the printer supports media sensing, find the -size amongst the "ready" media.
  • + size amongst the "ready" media.

    The matching result (if any) is returned in the cups_size_t structure.

    Returns true when there is a match and false if there is not a match.

    cupsGetDestMediaCount

    Get the number of sizes supported by a -destination.

    + destination.

    size_t cupsGetDestMediaCount(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags);

    Parameters

    @@ -3550,7 +4050,7 @@

    Return Value

    Option value or NULL

    cupsGetPassword

    Get a password from the user using the current -password callback.

    + password callback.

    const char *cupsGetPassword(const char *prompt, http_t *http, const char *method, const char *resource);

    Parameters

    @@ -3574,6 +4074,16 @@

    Discussion

    thread in a program. Multi-threaded programs that override the setting via the cupsSetPasswordCB function need to do so in each thread for the same function to be used.

    +

    cupsGetRand

    +

    Return a 32-bit pseudo-random number.

    +

    +unsigned cupsGetRand(void);

    +

    Return Value

    +

    Random number

    +

    Discussion

    +

    This function returns a 32-bit pseudo-random number suitable for use as +one-time identifiers or nonces. The random numbers are generated/seeded +using system entropy.

    cupsGetResponse

    Get a response to an IPP request.

    @@ -3683,7 +4193,7 @@

    Return Value

    Language data

    cupsLangEncoding

    Return the character encoding (us-ascii, etc.) -for the given language.

    + for the given language.

    const char *cupsLangEncoding(cups_lang_t *lang);

    Parameters

    @@ -3721,21 +4231,21 @@

    Return Value

    Language data

    cupsLastError

    Return the last IPP status code received on the current -thread.

    + thread.

    ipp_status_t cupsLastError(void);

    Return Value

    IPP status code from last request

    cupsLastErrorString

    Return the last IPP status-message received on the -current thread.

    + current thread.

    const char *cupsLastErrorString(void);

    Return Value

    "status-message" text from last request

    cupsLocalizeDestMedia

    Get the localized string for a destination media -size.

    + size.

    const char *cupsLocalizeDestMedia(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, unsigned flags, cups_size_t *size);

    Parameters

    @@ -3758,7 +4268,7 @@

    Discussion

    invalid if the destination information is deleted.

    cupsLocalizeDestOption

    Get the localized string for a destination -option.

    + option.

    const char *cupsLocalizeDestOption(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option);

    Parameters

    @@ -3779,7 +4289,7 @@

    Discussion

    invalid if the destination information is deleted.

    cupsLocalizeDestValue

    Get the localized string for a destination -option+value pair.

    + option+value pair.

    const char *cupsLocalizeDestValue(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);

    Parameters

    @@ -4281,7 +4791,7 @@

    Discussion

    so in each thread for the same callback to be used.

    cupsSetCredentials

    Set the default credentials to be used for SSL/TLS -connections.

    + connections.

    bool cupsSetCredentials(cups_array_t *credentials);

    Parameters

    @@ -4649,7 +5159,7 @@

    Discussion

    after cupsStartDocument to provide a document file.

    httpAcceptConnection

    Accept a new HTTP client connection from the -specified listening socket.

    + specified listening socket.

    http_t *httpAcceptConnection(int fd, bool blocking);

    Parameters

    @@ -4680,7 +5190,7 @@

    Discussion

    Use httpCreateCredentials to create a credentials array.

    httpAddrClose

    Close a socket created by httpAddrConnect or -httpAddrListen.

    + httpAddrListen.

    bool httpAddrClose(http_addr_t *addr, int fd);

    Parameters

    @@ -4698,7 +5208,7 @@

    Discussion

    ensures that domain sockets are removed when closed.

    httpAddrConnect

    Connect to any of the addresses in the list with a -timeout and optional cancel.

    + timeout and optional cancel.

    http_addrlist_t *httpAddrConnect(http_addrlist_t *addrlist, int *sock, int msec, int *cancel);

    Parameters

    @@ -4873,7 +5383,7 @@

    Parameters

    httpAssembleURI

    Assemble a uniform resource identifier from its -components.

    + components.

    http_uri_status_t httpAssembleURI(http_uri_coding_t encoding, char *uri, size_t urilen, const char *scheme, const char *username, const char *host, int port, const char *resource);

    Parameters

    @@ -4904,7 +5414,7 @@

    Discussion

    URI string.

    httpAssembleURIf

    Assemble a uniform resource identifier from its -components with a formatted resource.

    + components with a formatted resource.

    http_uri_status_t httpAssembleURIf(http_uri_coding_t encoding, char *uri, size_t urilen, const char *scheme, const char *username, const char *host, int port, const char *resourcef, ...);

    Parameters

    @@ -5104,7 +5614,7 @@

    Return Value

    Error code (errno) value

    httpFieldValue

    Return the HTTP field enumeration value for a field -name.

    + name.

    http_field_t httpFieldValue(const char *name);

    Parameters

    @@ -5202,7 +5712,7 @@

    Return Value

    true if blocking, false if non-blocking

    httpGetContentEncoding

    Get a common content encoding, if any, between -the client and server.

    + the client and server.

    const char *httpGetContentEncoding(http_t *http);

    Parameters

    @@ -5343,7 +5853,7 @@

    Return Value

    Keep-Alive state

    httpGetLength

    Get the amount of data remaining from the content-length -or transfer-encoding fields.

    + or transfer-encoding fields.

    off_t httpGetLength(http_t *http);

    Parameters

    @@ -5380,7 +5890,7 @@

    Return Value

    Number of bytes available

    httpGetRemaining

    Get the number of remaining bytes in the message -body or current chunk.

    + body or current chunk.

    size_t httpGetRemaining(http_t *http);

    Parameters

    @@ -5462,7 +5972,7 @@

    Return Value

    Line or NULL

    httpInitialize

    Initialize the HTTP interface library and set the -default HTTP proxy (if any).

    + default HTTP proxy (if any).

    void httpInitialize(void);

    httpIsChunked

    @@ -5560,7 +6070,7 @@

    Return Value

    true on success, false on failure

    httpResolveHostname

    Resolve the hostname of the HTTP connection -address.

    + address.

    const char *httpResolveHostname(http_t *http, char *buffer, size_t bufsize);

    Parameters

    @@ -5614,7 +6124,7 @@

    Discussion

    to resolve the specified URI.

    httpSeparateURI

    Separate a Universal Resource Identifier into its -components.

    + components.

    http_uri_status_t httpSeparateURI(http_uri_coding_t decoding, const char *uri, char *scheme, size_t schemelen, char *username, size_t usernamelen, char *host, size_t hostlen, int *port, char *resource, size_t resourcelen);

    Parameters

    @@ -5686,7 +6196,7 @@

    Parameters

    httpSetCredentials

    Set the credentials associated with an encrypted -connection.

    + connection.

    bool httpSetCredentials(http_t *http, cups_array_t *credentials);

    Parameters

    @@ -5809,12 +6319,10 @@

    Discussion

    bool // true to continue, false to stop timeout_cb(http_t *http, void *user_data) { -... "http" contains the HTTP connection, "user_data" contains the callback pointer + ... "http" contains the HTTP connection, "user_data" contains the callback pointer } -``` -lution to be -terminated. The callback is provided the "cb_data" value and returns a -bool

    + +

    httpShutdown

    Shutdown one side of an HTTP connection.

    @@ -6532,7 +7040,7 @@

    Discussion

    (v)snprintf.

    ippContainsInteger

    Determine whether an attribute contains the -specified value or is within the list of ranges.

    + specified value or is within the list of ranges.

    bool ippContainsInteger(ipp_attribute_t *attr, int value);

    Parameters

    @@ -6550,7 +7058,7 @@

    Discussion

    values for the attribute.

    ippContainsString

    Determine whether an attribute contains the -specified string value.

    + specified string value.

    bool ippContainsString(ipp_attribute_t *attr, const char *value);

    Parameters

    @@ -6617,7 +7125,7 @@

    Discussion

    partial copy of the source attribute itself.

    ippCreateRequestedArray

    Create a CUPS array of attribute names from the -given requested-attributes attribute.

    + given requested-attributes attribute.

    cups_array_t *ippCreateRequestedArray(ipp_t *request);

    Parameters

    @@ -6642,7 +7150,7 @@

    Discussion

    array must be freed using cupsArrayDelete.

    ippDateToTime

    Convert from RFC 2579 Date/Time format to time in -seconds.

    + seconds.

    time_t ippDateToTime(const ipp_uchar_t *date);

    Parameters

    @@ -8157,7 +8665,7 @@

    Discussion

    are used.

    pwgInitSize

    Initialize a pwg_size_t structure using IPP Job Template -attributes.

    + attributes.

    bool pwgInitSize(pwg_size_t *size, ipp_t *job, bool *margins_set);

    Parameters

    @@ -8332,6 +8840,61 @@

    cups_dir_t

    typedef struct _cups_dir_s cups_dir_t;

    +

    cups_dnssd_browse_cb_t

    +

    DNS-SD browse callback

    +

    +typedef void(*)(cups_dnssd_browse_t *browse, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *name, const char *regtype, const char *domain)cups_dnssd_browse_cb_t; +

    +

    cups_dnssd_error_cb_t

    +

    DNS-SD error callback

    +

    +typedef void(*)(void *cb_data, const char *message)cups_dnssd_error_cb_t; +

    +

    cups_dnssd_flags_t

    +

    DNS-SD callback flag bitmask

    +

    +typedef unsigned cups_dnssd_flags_t; +

    +

    cups_dnssd_query_cb_t

    +

    DNS-SD query callback

    +

    +typedef void(*)(cups_dnssd_query_t *query, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, uint16_t rrtype, const void *qdata, uint16_t qlen) cups_dnssd_query_cb_t; +

    +

    cups_dnssd_query_t

    +

    DNS query request

    +

    +typedef struct _cups_dnssd_query_s cups_dnssd_query_t; +

    +

    cups_dnssd_resolve_cb_t

    +

    DNS-SD resolve callback

    +

    +typedef void(*)(cups_dnssd_resolve_t *res, void *cb_data, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullname, const char *host, uint16_t port, size_t num_txt, cups_option_t *txt)cups_dnssd_resolve_cb_t; +

    +

    cups_dnssd_resolve_t

    +

    DNS resolve request

    +

    +typedef struct _cups_dnssd_resolve_s cups_dnssd_resolve_t; +

    +

    cups_dnssd_browse_t

    +

    DNS record type values

    +

    +typedef typedef struct _cups_dnssd_browse_s cups_dnssd_browse_t; +

    +

    cups_dnssd_service_cb_t

    +

    DNS-SD service registration callback

    +

    +typedef void(*)(cups_dnssd_service_t *service, void *cb_data, cups_dnssd_flags_t flags) cups_dnssd_service_cb_t; +

    +

    cups_dnssd_service_t

    +

    DNS service registration

    +

    +typedef struct _cups_dnssd_service_s cups_dnssd_service_t; +

    +

    cups_dnssd_t

    +

    DNS-SD context

    +

    +typedef struct _cups_dnssd_s cups_dnssd_t; +

    cups_edge_t

    LeadingEdge attribute values

    @@ -8402,11 +8965,6 @@

    cups_ptype_t

    typedef unsigned cups_ptype_t;

    -

    cups_raster_cb_t

    -

    cupsRasterOpenIO callback function

    -

    -typedef ssize_t(*)(void *ctx, unsigned char *buffer, size_t length) cups_raster_cb_t; -

    cups_raster_mode_t

    cupsRasterOpen modes

    @@ -9017,6 +9575,42 @@

    Constants

    CUPS_CUT_PAGE Cut the roll after this page CUPS_CUT_SET Cut the roll after this set +

    cups_dnssd_flags_e

    +

    DNS-SD callback flag values

    +

    Constants

    + + + + + + + + +
    CUPS_DNSSD_FLAGS_ADD Added (removed if not set)
    CUPS_DNSSD_FLAGS_COLLISION Collision occurred
    CUPS_DNSSD_FLAGS_ERROR Error occurred
    CUPS_DNSSD_FLAGS_HOST_CHANGE Host name changed
    CUPS_DNSSD_FLAGS_MORE More coming
    CUPS_DNSSD_FLAGS_NETWORK_CHANGE Network connection changed
    CUPS_DNSSD_FLAGS_NONE No flags
    +

    cups_dnssd_rrtype_e

    +

    DNS record type values

    +

    Constants

    + + + + + + + + + + + + + + + + + + + + +
    CUPS_DNSSD_RRTYPE_A Host address
    CUPS_DNSSD_RRTYPE_AAAA IPv6 Address.
    CUPS_DNSSD_RRTYPE_ANY Wildcard match
    CUPS_DNSSD_RRTYPE_CERT Certification record
    CUPS_DNSSD_RRTYPE_CNAME Canonical name
    CUPS_DNSSD_RRTYPE_DHCID DHCP Client Identifier
    CUPS_DNSSD_RRTYPE_DNSKEY DNSKEY
    CUPS_DNSSD_RRTYPE_HTTPS HTTPS Service Binding
    CUPS_DNSSD_RRTYPE_KEY Security key
    CUPS_DNSSD_RRTYPE_KX Key Exchange
    CUPS_DNSSD_RRTYPE_LOC Location Information.
    CUPS_DNSSD_RRTYPE_NS Name server
    CUPS_DNSSD_RRTYPE_PTR Domain name pointer
    CUPS_DNSSD_RRTYPE_RRSIG RRSIG
    CUPS_DNSSD_RRTYPE_RT Router
    CUPS_DNSSD_RRTYPE_SIG Security signature
    CUPS_DNSSD_RRTYPE_SPF Sender Policy Framework for E-Mail
    CUPS_DNSSD_RRTYPE_TXT One or more text strings
    CUPS_DNSSD_RRTYPE_WKS Well known service

    cups_edge_e

    LeadingEdge attribute values

    Constants

    diff --git a/tools/Makefile b/tools/Makefile index d5fd32d91..adc3c593b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -137,7 +137,7 @@ test: local ippeveprinter: ippeveprinter.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveprinter.o -L../cups -lcups $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveprinter.o $(LINKCUPS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -145,9 +145,9 @@ ippeveprinter: ippeveprinter.o ../cups/$(LIBCUPS) # ippeveprinter-static # -ippeveprinter-static: ippeveprinter.o ../cups/libcups.a +ippeveprinter-static: ippeveprinter.o ../cups/$(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveprinter.o $(PAMLIBS) ../cups/libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveprinter.o $(PAMLIBS) ../cups/$(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -157,7 +157,7 @@ ippeveprinter-static: ippeveprinter.o ../cups/libcups.a ippevepcl: ippevepcl.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippevepcl.o -L../cups -lcups $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippevepcl.o $(LINKCUPS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -167,7 +167,7 @@ ippevepcl: ippevepcl.o ../cups/$(LIBCUPS) ippeveps: ippeveps.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveps.o -L../cups -lcups $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippeveps.o $(LINKCUPS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -177,7 +177,7 @@ ippeveps: ippeveps.o ../cups/$(LIBCUPS) ippfind: ippfind.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippfind.o $(DNSSDLIBS) -L../cups -lcups $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippfind.o $(DNSSDLIBS) $(LINKCUPS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -185,9 +185,9 @@ ippfind: ippfind.o ../cups/$(LIBCUPS) # ippfind-static # -ippfind-static: ippfind.o ../cups/libcups.a +ippfind-static: ippfind.o ../cups/$(LIBCUPS_STATIC) echo Linking $@ - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippfind.o ../cups/libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ippfind.o ../cups/$(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -197,7 +197,7 @@ ippfind-static: ippfind.o ../cups/libcups.a ipptool: ipptool.o ../cups/$(LIBCUPS) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ipptool.o -L../cups -lcups $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ipptool.o $(LINKCUPS) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ @@ -205,9 +205,9 @@ ipptool: ipptool.o ../cups/$(LIBCUPS) # ipptool-static # -ipptool-static: ipptool.o ../cups/libcups.a +ipptool-static: ipptool.o ../cups/$(LIBCUPS_STATIC) echo Linking $@... - $(CC) $(LDFLAGS) $(OPTIM) -o $@ ipptool.o ../cups/libcups.a $(LIBS) + $(CC) $(LDFLAGS) $(OPTIM) -o $@ ipptool.o ../cups/$(LIBCUPS_STATIC) $(LIBS) $(CODE_SIGN) $(CSFLAGS) $@ diff --git a/tools/ippeveprinter.c b/tools/ippeveprinter.c index c814af714..ee7c9faeb 100644 --- a/tools/ippeveprinter.c +++ b/tools/ippeveprinter.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -43,17 +44,6 @@ extern char **environ; # define O_BINARY 0 /* Windows "binary file" nonsense */ #endif /* !O_BINARY */ -#ifdef HAVE_MDNSRESPONDER -# include -#elif defined(HAVE_AVAHI) -# include -# include -# include -# include -# include -# include -#endif /* HAVE_MDNSRESPONDER */ - #ifdef HAVE_SYS_MOUNT_H # include #endif /* HAVE_SYS_MOUNT_H */ @@ -144,19 +134,6 @@ static const char * const ippeve_preason_strings[] = * Structures... */ -#ifdef HAVE_MDNSRESPONDER -typedef DNSServiceRef ippeve_srv_t; /* Service reference */ -typedef TXTRecordRef ippeve_txt_t; /* TXT record */ - -#elif defined(HAVE_AVAHI) -typedef AvahiEntryGroup *ippeve_srv_t; /* Service reference */ -typedef AvahiStringList *ippeve_txt_t; /* TXT record */ - -#else -typedef void *ippeve_srv_t; /* Service reference */ -typedef void *ippeve_txt_t; /* TXT record */ -#endif /* HAVE_MDNSRESPONDER */ - #if HAVE_LIBPAM typedef struct ippeve_authdata_s /* Authentication data */ { @@ -178,14 +155,8 @@ typedef struct ippeve_printer_s /**** Printer data ****/ /* TODO: One IPv4 and one IPv6 listener are really not sufficient */ int ipv4, /* IPv4 listener */ ipv6; /* IPv6 listener */ -#ifdef HAVE_MDNSRESPONDER - ippeve_srv_t ipp_ref, /* DNS-SD IPP service */ - ipps_ref, /* DNS-SD IPPS service */ - http_ref, /* DNS-SD HTTP service */ - printer_ref; /* DNS-SD LPD service */ -#elif defined(HAVE_AVAHI) - ippeve_srv_t dnssd_ref; /* DNS-SD services */ -#endif /* HAVE_MDNSRESPONDER */ + cups_dnssd_t *dnssd; /* DNS-SD context */ + cups_dnssd_service_t *services; /* DNS-SD services */ char *dnssd_subtypes;/* DNS-SD subtypes */ int dnssd_collision;/* Name collision? */ char *dnssd_name, /* printer-dns-sd-name */ @@ -268,20 +239,15 @@ static ippeve_client_t *create_client(ippeve_printer_t *printer, int sock); static ippeve_job_t *create_job(ippeve_client_t *client); static int create_job_file(ippeve_job_t *job, char *fname, size_t fnamesize, const char *dir, const char *ext); static int create_listener(const char *name, int port, int family); -static ipp_t *create_media_col(const char *media, const char *source, const char *type, int width, int length, int bottom, int left, int right, int top); +static ipp_t *create_media_col(const char *media, const char *source, const char *type, ipp_t *media_size, int bottom, int left, int right, int top); static ipp_t *create_media_size(int width, int length); +static ipp_t *create_media_size_range(int min_width, int max_width, int min_length, int max_length); static ippeve_printer_t *create_printer(const char *servername, int serverport, const char *name, const char *location, const char *icons, const char *strings, cups_array_t *docformats, const char *subtypes, const char *directory, const char *command, const char *device_uri, const char *output_format, ipp_t *attrs); static void debug_attributes(const char *title, ipp_t *ipp, int response); static void delete_client(ippeve_client_t *client); static void delete_job(ippeve_job_t *job); static void delete_printer(ippeve_printer_t *printer); -#ifdef HAVE_MDNSRESPONDER -static void DNSSD_API dnssd_callback(DNSServiceRef sdRef, DNSServiceFlags flags, DNSServiceErrorType errorCode, const char *name, const char *regtype, const char *domain, ippeve_printer_t *printer); -#elif defined(HAVE_AVAHI) -static void dnssd_callback(AvahiEntryGroup *p, AvahiEntryGroupState state, void *context); -static void dnssd_client_cb(AvahiClient *c, AvahiClientState state, void *userdata); -#endif /* HAVE_MDNSRESPONDER */ -static void dnssd_init(void); +static void dnssd_callback(cups_dnssd_service_t *service, ippeve_printer_t *printer, cups_dnssd_flags_t flags); static int filter_cb(ippeve_filter_t *filter, ipp_t *dst, ipp_attribute_t *attr); static ippeve_job_t *find_job(ippeve_client_t *client); static void finish_document_data(ippeve_client_t *client, ippeve_job_t *job); @@ -317,7 +283,7 @@ static int process_http(ippeve_client_t *client); static int process_ipp(ippeve_client_t *client); static void *process_job(ippeve_job_t *job); static void process_state_message(ippeve_job_t *job, char *message); -static int register_printer(ippeve_printer_t *printer); +static bool register_printer(ippeve_printer_t *printer); static bool respond_http(ippeve_client_t *client, http_status_t code, const char *content_coding, const char *type, size_t length); static void respond_ipp(ippeve_client_t *client, ipp_status_t status, const char *message, ...) _CUPS_FORMAT(3, 4); static void respond_unsupported(ippeve_client_t *client, ipp_attribute_t *attr); @@ -338,13 +304,6 @@ static bool valid_job_attributes(ippeve_client_t *client); * Globals... */ -#ifdef HAVE_MDNSRESPONDER -static DNSServiceRef DNSSDMaster = NULL; -#elif defined(HAVE_AVAHI) -static AvahiThreadedPoll *DNSSDMaster = NULL; -static AvahiClient *DNSSDClient = NULL; -#endif /* HAVE_MDNSRESPONDER */ - static int KeepFiles = 0, /* Keep spooled job files? */ MaxVersion = 20,/* Maximum IPP version (20 = 2.0, 11 = 1.1, etc.) */ Verbosity = 0; /* Verbosity level */ @@ -647,12 +606,6 @@ main(int argc, /* I - Number of command-line args */ _cupsLangPrintf(stderr, _("Using spool directory \"%s\"."), directory); } - /* - * Initialize DNS-SD... - */ - - dnssd_init(); - /* * Create the printer... */ @@ -1282,16 +1235,13 @@ static ipp_t * /* O - media-col collection */ create_media_col(const char *media, /* I - Media name */ const char *source, /* I - Media source, if any */ const char *type, /* I - Media type, if any */ - int width, /* I - x-dimension in 2540ths */ - int length, /* I - y-dimension in 2540ths */ + ipp_t *media_size,/* I - media-size collection value */ int bottom, /* I - Bottom margin in 2540ths */ int left, /* I - Left margin in 2540ths */ int right, /* I - Right margin in 2540ths */ int top) /* I - Top margin in 2540ths */ { - ipp_t *media_col = ippNew(), /* media-col value */ - *media_size = create_media_size(width, length); - /* media-size value */ + ipp_t *media_col = ippNew(); /* media-col value */ char media_key[256]; /* media-key value */ const char *media_key_suffix = ""; /* media-key suffix */ @@ -1299,18 +1249,22 @@ create_media_col(const char *media, /* I - Media name */ if (bottom == 0 && left == 0 && right == 0 && top == 0) media_key_suffix = "_borderless"; - if (type && source) - snprintf(media_key, sizeof(media_key), "%s_%s_%s%s", media, source, type, media_key_suffix); - else if (type) - snprintf(media_key, sizeof(media_key), "%s__%s%s", media, type, media_key_suffix); - else if (source) - snprintf(media_key, sizeof(media_key), "%s_%s%s", media, source, media_key_suffix); - else - snprintf(media_key, sizeof(media_key), "%s%s", media, media_key_suffix); + if (media) + { + if (type && source) + snprintf(media_key, sizeof(media_key), "%s_%s_%s%s", media, source, type, media_key_suffix); + else if (type) + snprintf(media_key, sizeof(media_key), "%s__%s%s", media, type, media_key_suffix); + else if (source) + snprintf(media_key, sizeof(media_key), "%s_%s%s", media, source, media_key_suffix); + else + snprintf(media_key, sizeof(media_key), "%s%s", media, media_key_suffix); - ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-key", NULL, media_key); + ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-key", NULL, media_key); + } ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size); - ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-size-name", NULL, media); + if (media) + ippAddString(media_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-size-name", NULL, media); if (bottom >= 0) ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", bottom); if (left >= 0) @@ -1341,8 +1295,28 @@ create_media_size(int width, /* I - x-dimension in 2540ths */ ipp_t *media_size = ippNew(); /* media-size value */ - ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", width); - ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", length); + ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", width); + ippAddInteger(media_size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", length); + + return (media_size); +} + + +/* + * 'create_media_size_range()' - Create a ranged media-size value. + */ + +static ipp_t * /* O - media-col collection */ +create_media_size_range(int min_width, /* I - Minimum x-dimension in 2540ths */ + int max_width, /* I - Maximum x-dimension in 2540ths */ + int min_length, /* I - Minimum x-dimension in 2540ths */ + int max_length) /* I - Maximum y-dimension in 2540ths */ +{ + ipp_t *media_size = ippNew(); /* media-size value */ + + + ippAddRange(media_size, IPP_TAG_ZERO, "x-dimension", min_width, max_width); + ippAddRange(media_size, IPP_TAG_ZERO, "y-dimension", min_length, max_length); return (media_size); } @@ -2074,7 +2048,8 @@ delete_job(ippeve_job_t *job) /* I - Job */ */ static void -delete_printer(ippeve_printer_t *printer) /* I - Printer */ +delete_printer( + ippeve_printer_t *printer) /* I - Printer */ { if (printer->ipv4 >= 0) close(printer->ipv4); @@ -2082,23 +2057,7 @@ delete_printer(ippeve_printer_t *printer) /* I - Printer */ if (printer->ipv6 >= 0) close(printer->ipv6); -#if HAVE_MDNSRESPONDER - if (printer->printer_ref) - DNSServiceRefDeallocate(printer->printer_ref); - if (printer->ipp_ref) - DNSServiceRefDeallocate(printer->ipp_ref); - if (printer->ipps_ref) - DNSServiceRefDeallocate(printer->ipps_ref); - if (printer->http_ref) - DNSServiceRefDeallocate(printer->http_ref); -#elif defined(HAVE_AVAHI) - avahi_threaded_poll_lock(DNSSDMaster); - - if (printer->dnssd_ref) - avahi_entry_group_free(printer->dnssd_ref); - - avahi_threaded_poll_unlock(DNSSDMaster); -#endif /* HAVE_MDNSRESPONDER */ + cupsDNSSDDelete(printer->dnssd); if (printer->dnssd_name) free(printer->dnssd_name); @@ -2124,57 +2083,19 @@ delete_printer(ippeve_printer_t *printer) /* I - Printer */ } -#ifdef HAVE_MDNSRESPONDER -/* - * 'dnssd_callback()' - Handle DNS-SD registration events. - */ - -static void DNSSD_API -dnssd_callback( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Status flags */ - DNSServiceErrorType errorCode, /* I - Error, if any */ - const char *name, /* I - Service name */ - const char *regtype, /* I - Service type */ - const char *domain, /* I - Domain for service */ - ippeve_printer_t *printer) /* I - Printer */ -{ - (void)sdRef; - (void)flags; - (void)domain; - (void)name; - - if (errorCode == kDNSServiceErr_NameConflict) - { - fputs("DNS-SD service name collision detected.\n", stderr); - printer->dnssd_collision = 1; - } - else if (errorCode) - { - fprintf(stderr, "DNSServiceRegister for %s failed with error %d.\n", regtype, (int)errorCode); - return; - } -} - - -#elif defined(HAVE_AVAHI) /* * 'dnssd_callback()' - Handle DNS-SD registration events. */ static void dnssd_callback( - AvahiEntryGroup *srv, /* I - Service */ - AvahiEntryGroupState state, /* I - Registration state */ - void *context) /* I - Printer */ + cups_dnssd_service_t *service, /* I - Service registration */ + ippeve_printer_t *printer, /* I - Printer */ + cups_dnssd_flags_t flags) /* I - Status flags */ { - ippeve_printer_t *printer = (ippeve_printer_t *)context; - /* Printer */ - - - (void)srv; + (void)service; - if (state == AVAHI_ENTRY_GROUP_COLLISION) + if (flags & CUPS_DNSSD_FLAGS_COLLISION) { fputs("DNS-SD service name collision detected.\n", stderr); printer->dnssd_collision = 1; @@ -2182,73 +2103,6 @@ dnssd_callback( } -/* - * 'dnssd_client_cb()' - Client callback for Avahi. - * - * Called whenever the client or server state changes... - */ - -static void -dnssd_client_cb( - AvahiClient *c, /* I - Client */ - AvahiClientState state, /* I - Current state */ - void *userdata) /* I - User data (printer) */ -{ - if (!c) - return; - - switch (state) - { - default : - fprintf(stderr, "Ignored Avahi state %d.\n", state); - break; - - case AVAHI_CLIENT_FAILURE: - if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED) - { - fputs("Avahi server crashed, exiting.\n", stderr); - exit(1); - } - break; - } -} -#endif /* HAVE_MDNSRESPONDER */ - - -/* - * 'dnssd_init()' - Initialize the DNS-SD service connections... - */ - -static void -dnssd_init(void) -{ -#ifdef HAVE_MDNSRESPONDER - if (DNSServiceCreateConnection(&DNSSDMaster) != kDNSServiceErr_NoError) - { - fputs("Error: Unable to initialize DNS-SD.\n", stderr); - exit(1); - } - -#elif defined(HAVE_AVAHI) - int error; /* Error code, if any */ - - if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL) - { - fputs("Error: Unable to initialize DNS-SD.\n", stderr); - exit(1); - } - - if ((DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssd_client_cb, NULL, &error)) == NULL) - { - fputs("Error: Unable to initialize DNS-SD.\n", stderr); - exit(1); - } - - avahi_threaded_poll_start(DNSSDMaster); -#endif /* HAVE_MDNSRESPONDER */ -} - - /* * 'filter_cb()' - Filter printer attributes based on the requested array. */ @@ -4238,6 +4092,8 @@ load_legacy_attributes( "iso_a6_105x148mm", /* A6 */ "na_5x7_5x7in", /* Photo 5x7 aka 2L */ "iso_a5_148x210mm", /* A5 */ + "roll_min_4x1in", /* Roll */ + "roll_max_8.5x39.6in" /* Roll */ }; static const char * const media_ready[] = { /* media-ready values */ @@ -4247,7 +4103,8 @@ load_legacy_attributes( static const char * const media_ready_color[] = { /* media-ready values */ "na_letter_8.5x11in", /* Letter */ - "na_index-4x6_4x6in" /* Photo 4x6 */ + "na_index-4x6_4x6in", /* Photo 4x6 */ + "roll_current_8.5x0in" /* 8.5" roll */ }; static const char * const media_source_supported[] = { /* media-source-supported values */ @@ -4260,7 +4117,8 @@ load_legacy_attributes( { /* media-source-supported values */ "auto", "main", - "photo" + "photo", + "roll" }; static const char * const media_type_supported[] = { /* media-type-supported values */ @@ -4360,7 +4218,8 @@ load_legacy_attributes( { /* printer-input-tray values */ "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=-2;level=-2;status=0;name=auto", "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=250;level=-2;status=0;name=main", - "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=25;level=-2;status=0;name=photo" + "type=sheetFeedAutoRemovableTray;mediafeed=0;mediaxfeed=0;maxcapacity=25;level=-2;status=0;name=photo", + "type=continuousRoll;mediafeed=0;mediaxfeed=0;maxcapacity=100;level=-2;status=0;name=roll" }; static const char * const printer_supply[] = { /* printer-supply values */ @@ -4530,8 +4389,7 @@ load_legacy_attributes( ippAddIntegers(attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin-supported", (int)(sizeof(media_bottom_margin_supported_color) / sizeof(media_bottom_margin_supported_color[0])), media_bottom_margin_supported_color); /* media-col-database and media-col-default */ - attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-col-database", num_media, NULL); - for (i = 0; i < num_media; i ++) + for (i = 0, attr = NULL; i < num_media; i ++) { int bottom, left, /* media-xxx-margins */ right, top; @@ -4572,8 +4430,31 @@ load_legacy_attributes( top = ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]; } - col = create_media_col(media[i], source, NULL, pwg->width, pwg->length, bottom, left, right, top); - ippSetCollection(attrs, &attr, i, col); + if (!strncmp(media[i], "roll_min_", 9) && i < (num_media - 1)) + { + // Roll min/max range... + pwg_media_t *pwg2; // Max size + ipp_t *media_size; // media-size member attribute + + i ++; + pwg2 = pwgMediaForPWG(media[i]); + + media_size = ippNew(); + ippAddRange(media_size, IPP_TAG_ZERO, "x-dimension", pwg->width, pwg2->width); + ippAddRange(media_size, IPP_TAG_ZERO, "y-dimension", pwg->length, pwg2->length); + + col = create_media_col(NULL, source, NULL, media_size, bottom, left, right, top); + } + else + { + // Sheet size + col = create_media_col(media[i], source, NULL, create_media_size(pwg->width, pwg->length), bottom, left, right, top); + } + + if (attr) + ippSetCollection(attrs, &attr, ippGetCount(attr), col); + else + attr = ippAddCollection(attrs, IPP_TAG_PRINTER, "media-col-database", col); ippDelete(col); } @@ -4582,9 +4463,9 @@ load_legacy_attributes( pwg = pwgMediaForPWG(ready[0]); if (pwg->width == 21000) - col = create_media_col(ready[0], "main", "stationery", pwg->width, pwg->length, ppm_color > 0 ? media_bottom_margin_supported_color[1] : media_bottom_margin_supported[0], media_lr_margin_supported[0], media_lr_margin_supported[0], ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]); + col = create_media_col(ready[0], "main", "stationery", create_media_size(pwg->width, pwg->length), ppm_color > 0 ? media_bottom_margin_supported_color[1] : media_bottom_margin_supported[0], media_lr_margin_supported[0], media_lr_margin_supported[0], ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]); else - col = create_media_col(ready[0], "main", "stationery", pwg->width, pwg->length, ppm_color > 0 ? media_bottom_margin_supported_color[1] : media_bottom_margin_supported[0], media_lr_margin_supported[1], media_lr_margin_supported[1], ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]); + col = create_media_col(ready[0], "main", "stationery", create_media_size(pwg->width, pwg->length), ppm_color > 0 ? media_bottom_margin_supported_color[1] : media_bottom_margin_supported[0], media_lr_margin_supported[1], media_lr_margin_supported[1], ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]); ippAddCollection(attrs, IPP_TAG_PRINTER, "media-col-default", col); @@ -4638,7 +4519,7 @@ load_legacy_attributes( top = ppm_color > 0 ? media_top_margin_supported_color[1] : media_top_margin_supported[0]; } - col = create_media_col(ready[i], source, type, pwg->width, pwg->length, bottom, left, right, top); + col = create_media_col(ready[i], source, type, create_media_size(pwg->width, pwg->length), bottom, left, right, top); ippSetCollection(attrs, &attr, i, col); ippDelete(col); } @@ -4665,13 +4546,31 @@ load_legacy_attributes( ippAddStrings(attrs, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "media-supported", num_media, NULL, media); /* media-size-supported */ - attr = ippAddCollections(attrs, IPP_TAG_PRINTER, "media-size-supported", num_media, NULL); - for (i = 0; i < num_media; i ++) + for (i = 0, attr = NULL; i < num_media; i ++) { pwg = pwgMediaForPWG(media[i]); - col = create_media_size(pwg->width, pwg->length); - ippSetCollection(attrs, &attr, i, col); + if (!strncmp(media[i], "roll_min_", 9) && i < (num_media - 1)) + { + // Roll min/max range... + pwg_media_t *pwg2; // Max size + + i ++; + pwg2 = pwgMediaForPWG(media[i]); + + col = create_media_size_range(pwg->width, pwg2->width, pwg->length, pwg2->length); + } + else + { + // Sheet size... + col = create_media_size(pwg->width, pwg->length); + } + + if (attr) + ippSetCollection(attrs, &attr, ippGetCount(attr), col); + else + attr = ippAddCollection(attrs, IPP_TAG_PRINTER, "media-size-supported", col); + ippDelete(col); } @@ -6375,12 +6274,13 @@ process_state_message( * 'register_printer()' - Register a printer object via DNS-SD. */ -static int /* O - 1 on success, 0 on error */ +static bool /* O - `true` on success, `false` on error */ register_printer( ippeve_printer_t *printer) /* I - Printer */ { -#ifdef HAVE_DNSSD - ippeve_txt_t ipp_txt; /* DNS-SD IPP TXT record */ + size_t num_txt; /* Number of DNS-SD IPP TXT key/value pairs */ + cups_option_t *txt; /* DNS-SD IPP TXT key/value pairs */ + uint32_t if_index; /* Interface index */ size_t i, /* Looping var */ count; /* Number of values */ ipp_attribute_t *color_supported, @@ -6391,14 +6291,15 @@ register_printer( *sides_supported, *urf_supported; /* Printer attributes */ const char *value; /* Value string */ - char adminurl[247], /* adminurl value */ + char regtype[256], /* Registration types */ + adminurl[247], /* adminurl value */ formats[252], /* List of supported formats */ urf[252], /* List of supported URF values */ *ptr; /* Pointer into string */ if (printer->dnssd_subtypes && !strcmp(printer->dnssd_subtypes, "off")) - return (1); + return (true); color_supported = ippFindAttribute(printer->attrs, "color-supported", IPP_TAG_BOOLEAN); document_format_supported = ippFindAttribute(printer->attrs, "document-format-supported", IPP_TAG_MIMETYPE); @@ -6465,216 +6366,86 @@ register_printer( printer->dnssd_collision = 0; } -#endif /* HAVE_DNSSD */ - -#ifdef HAVE_MDNSRESPONDER - DNSServiceErrorType error; /* Error from DNS-SD */ - char regtype[256]; /* DNS-SD service type */ - uint32_t ifindex; /* Interface index */ - /* * Build the TXT record for IPP... */ - TXTRecordCreate(&ipp_txt, 1024, NULL); - TXTRecordSetValue(&ipp_txt, "rp", 9, "ipp/print"); + num_txt = cupsAddOption("rp", "ipp/print", 0, &txt); if ((value = ippGetString(printer_make_and_model, 0, NULL)) != NULL) - TXTRecordSetValue(&ipp_txt, "ty", (uint8_t)strlen(value), value); - TXTRecordSetValue(&ipp_txt, "adminurl", (uint8_t)strlen(adminurl), adminurl); + num_txt = cupsAddOption("ty", value, num_txt, &txt); + num_txt = cupsAddOption("adminurl", adminurl, num_txt, &txt); if ((value = ippGetString(printer_location, 0, NULL)) != NULL) - TXTRecordSetValue(&ipp_txt, "note", (uint8_t)strlen(value), value); - TXTRecordSetValue(&ipp_txt, "pdl", (uint8_t)strlen(formats), formats); - TXTRecordSetValue(&ipp_txt, "Color", 1, ippGetBoolean(color_supported, 0) ? "T" : "F"); - TXTRecordSetValue(&ipp_txt, "Duplex", 1, ippGetCount(sides_supported) > 1 ? "T" : "F"); + num_txt = cupsAddOption("note", value, num_txt, &txt); + num_txt = cupsAddOption("pdl", formats, num_txt, &txt); + num_txt = cupsAddOption("Color", ippGetBoolean(color_supported, 0) ? "T" : "F", num_txt, &txt); + num_txt = cupsAddOption("Duplex", ippGetCount(sides_supported) > 1 ? "T" : "F", num_txt, &txt); if ((value = ippGetString(printer_uuid, 0, NULL)) != NULL) - TXTRecordSetValue(&ipp_txt, "UUID", (uint8_t)strlen(value) - 9, value + 9); - TXTRecordSetValue(&ipp_txt, "TLS", 3, "1.3"); + num_txt = cupsAddOption("UUID", value + 9, num_txt, &txt); + num_txt = cupsAddOption("TLS", "1.3", num_txt, &txt); if (urf[0]) - TXTRecordSetValue(&ipp_txt, "URF", (uint8_t)strlen(urf), urf); - TXTRecordSetValue(&ipp_txt, "txtvers", 1, "1"); - TXTRecordSetValue(&ipp_txt, "qtotal", 1, "1"); + num_txt = cupsAddOption("URF", urf, num_txt, &txt); + num_txt = cupsAddOption("txtvers", "1", num_txt, &txt); + num_txt = cupsAddOption("qtotal", "1", num_txt, &txt); /* * Register the _printer._tcp (LPD) service type with a port number of 0 to * defend our service name but not actually support LPD... */ - ifindex = !strcmp(printer->hostname, "localhost") ? kDNSServiceInterfaceIndexLocalOnly : kDNSServiceInterfaceIndexAny; + if_index = !strcmp(printer->hostname, "localhost") ? CUPS_DNSSD_IF_INDEX_LOCAL : CUPS_DNSSD_IF_INDEX_ANY; - if (printer->printer_ref) - DNSServiceRefDeallocate(printer->printer_ref); + if (!printer->dnssd) + printer->dnssd = cupsDNSSDNew(NULL, NULL); - printer->printer_ref = DNSSDMaster; + cupsDNSSDServiceDelete(printer->services); + if ((printer->services = cupsDNSSDServiceNew(printer->dnssd, if_index, printer->dnssd_name, (cups_dnssd_service_cb_t)dnssd_callback, printer)) == NULL) + return (false); - if ((error = DNSServiceRegister(&(printer->printer_ref), kDNSServiceFlagsShareConnection | kDNSServiceFlagsNoAutoRename, ifindex, printer->dnssd_name, "_printer._tcp", NULL /* domain */, NULL /* host */, 0 /* port */, 0 /* txtLen */, NULL /* txtRecord */, (DNSServiceRegisterReply)dnssd_callback, printer)) != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("Unable to register \"%s.%s\": %d"), printer->dnssd_name, "_printer._tcp", error); - return (0); - } + if (!cupsDNSSDServiceAdd(printer->services, "_printer._tcp", /*domain*/NULL, printer->hostname, /*port*/0, /*num_txt*/0, /*txt*/NULL)) + return (false); /* * Then register the _ipp._tcp (IPP) service type with the real port number to * advertise our IPP printer... */ - if (printer->ipp_ref) - DNSServiceRefDeallocate(printer->ipp_ref); - - printer->ipp_ref = DNSSDMaster; - if (printer->dnssd_subtypes && *(printer->dnssd_subtypes)) snprintf(regtype, sizeof(regtype), "_ipp._tcp,%s", printer->dnssd_subtypes); else cupsCopyString(regtype, "_ipp._tcp", sizeof(regtype)); - if ((error = DNSServiceRegister(&(printer->ipp_ref), kDNSServiceFlagsShareConnection | kDNSServiceFlagsNoAutoRename, ifindex, printer->dnssd_name, regtype, NULL /* domain */, NULL /* host */, htons(printer->port), TXTRecordGetLength(&ipp_txt), TXTRecordGetBytesPtr(&ipp_txt), (DNSServiceRegisterReply)dnssd_callback, printer)) != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("Unable to register \"%s.%s\": %d"), printer->dnssd_name, regtype, error); - return (0); - } + if (!cupsDNSSDServiceAdd(printer->services, regtype, /*domain*/NULL, printer->hostname, (uint16_t)printer->port, num_txt, txt)) + return (false); /* * Then register the _ipps._tcp (IPP) service type with the real port number to * advertise our IPPS printer... */ - if (printer->ipps_ref) - DNSServiceRefDeallocate(printer->ipps_ref); - - printer->ipps_ref = DNSSDMaster; - if (printer->dnssd_subtypes && *(printer->dnssd_subtypes)) snprintf(regtype, sizeof(regtype), "_ipps._tcp,%s", printer->dnssd_subtypes); else cupsCopyString(regtype, "_ipps._tcp", sizeof(regtype)); - if ((error = DNSServiceRegister(&(printer->ipps_ref), kDNSServiceFlagsShareConnection | kDNSServiceFlagsNoAutoRename, ifindex, printer->dnssd_name, regtype, NULL /* domain */, NULL /* host */, htons(printer->port), TXTRecordGetLength(&ipp_txt), TXTRecordGetBytesPtr(&ipp_txt), (DNSServiceRegisterReply)dnssd_callback, printer)) != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("Unable to register \"%s.%s\": %d"), printer->dnssd_name, regtype, error); - return (0); - } + if (!cupsDNSSDServiceAdd(printer->services, regtype, /*domain*/NULL, printer->hostname, (uint16_t)printer->port, num_txt, txt)) + return (false); /* * Similarly, register the _http._tcp,_printer (HTTP) service type with the - * real port number to advertise our IPP printer... - */ - - if (printer->http_ref) - DNSServiceRefDeallocate(printer->http_ref); - - printer->http_ref = DNSSDMaster; - - if ((error = DNSServiceRegister(&(printer->http_ref), kDNSServiceFlagsShareConnection | kDNSServiceFlagsNoAutoRename, ifindex, printer->dnssd_name, "_http._tcp,_printer", NULL /* domain */, NULL /* host */, htons(printer->port), 0 /* txtLen */, NULL /* txtRecord */, (DNSServiceRegisterReply)dnssd_callback, printer)) != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("Unable to register \"%s.%s\": %d"), printer->dnssd_name, "_http._tcp,_printer", error); - return (0); - } - - TXTRecordDeallocate(&ipp_txt); - -#elif defined(HAVE_AVAHI) - char temp[256]; /* Subtype service string */ - - /* - * Create the TXT record... - */ - - ipp_txt = NULL; - ipp_txt = avahi_string_list_add_printf(ipp_txt, "rp=ipp/print"); - if ((value = ippGetString(printer_make_and_model, 0, NULL)) != NULL) - ipp_txt = avahi_string_list_add_printf(ipp_txt, "ty=%s", value); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "adminurl=%s", adminurl); - if ((value = ippGetString(printer_location, 0, NULL)) != NULL) - ipp_txt = avahi_string_list_add_printf(ipp_txt, "note=%s", value); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "pdl=%s", formats); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "Color=%s", ippGetBoolean(color_supported, 0) ? "T" : "F"); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "Duplex=%s", ippGetCount(sides_supported) > 1 ? "T" : "F"); - if ((value = ippGetString(printer_uuid, 0, NULL)) != NULL) - ipp_txt = avahi_string_list_add_printf(ipp_txt, "UUID=%s", value + 9); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "TLS=1.3"); - if (urf[0]) - ipp_txt = avahi_string_list_add_printf(ipp_txt, "URF=%s", urf); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "txtvers=1"); - ipp_txt = avahi_string_list_add_printf(ipp_txt, "qtotal=1"); - - /* - * Register _printer._tcp (LPD) with port 0 to reserve the service name... - */ - - avahi_threaded_poll_lock(DNSSDMaster); - - if (printer->dnssd_ref) - avahi_entry_group_free(printer->dnssd_ref); - - printer->dnssd_ref = avahi_entry_group_new(DNSSDClient, dnssd_callback, printer); - - avahi_entry_group_add_service_strlst(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_printer._tcp", NULL, NULL, 0, NULL); - - /* - * Then register the _ipp._tcp (IPP)... + * real port number to advertise our IPP printer's web interface... */ - avahi_entry_group_add_service_strlst(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_ipp._tcp", NULL, NULL, printer->port, ipp_txt); - if (printer->dnssd_subtypes && *(printer->dnssd_subtypes)) - { - char *temptypes = strdup(printer->dnssd_subtypes), *start, *end; - - for (start = temptypes; *start; start = end) - { - if ((end = strchr(start, ',')) != NULL) - *end++ = '\0'; - else - end = start + strlen(start); - - snprintf(temp, sizeof(temp), "%s._sub._ipp._tcp", start); - avahi_entry_group_add_service_subtype(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_ipp._tcp", NULL, temp); - } - - free(temptypes); - } - - /* - * _ipps._tcp (IPPS) for secure printing... - */ - - avahi_entry_group_add_service_strlst(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_ipps._tcp", NULL, NULL, printer->port, ipp_txt); - if (printer->dnssd_subtypes && *(printer->dnssd_subtypes)) - { - char *temptypes = strdup(printer->dnssd_subtypes), *start, *end; - - for (start = temptypes; *start; start = end) - { - if ((end = strchr(start, ',')) != NULL) - *end++ = '\0'; - else - end = start + strlen(start); - - snprintf(temp, sizeof(temp), "%s._sub._ipps._tcp", start); - avahi_entry_group_add_service_subtype(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_ipps._tcp", NULL, temp); - } - - free(temptypes); - } - - /* - * Finally _http.tcp (HTTP) for the web interface... - */ + if (!cupsDNSSDServiceAdd(printer->services, "_http._tcp,_printer", /*domain*/NULL, printer->hostname, (uint16_t)printer->port, num_txt, txt)) + return (false); - avahi_entry_group_add_service_strlst(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_http._tcp", NULL, NULL, printer->port, NULL); - avahi_entry_group_add_service_subtype(printer->dnssd_ref, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, printer->dnssd_name, "_http._tcp", NULL, "_printer._sub._http._tcp"); + cupsFreeOptions(num_txt, txt); /* * Commit it... */ - avahi_entry_group_commit(printer->dnssd_ref); - avahi_threaded_poll_unlock(DNSSDMaster); - - avahi_string_list_free(ipp_txt); -#endif /* HAVE_MDNSRESPONDER */ - - return (1); + return (cupsDNSSDServicePublish(printer->services)); } @@ -6856,11 +6627,6 @@ run_printer(ippeve_printer_t *printer) /* I - Printer */ num_fds = 2; -#ifdef HAVE_MDNSRESPONDER - polldata[num_fds ].fd = DNSServiceRefSockFD(DNSSDMaster); - polldata[num_fds ++].events = POLLIN; -#endif /* HAVE_MDNSRESPONDER */ - /* * Loop until we are killed or have a hard error... */ @@ -6914,19 +6680,8 @@ run_printer(ippeve_printer_t *printer) /* I - Printer */ } } - /* - * Process DNS-SD messages... - */ - -#ifdef HAVE_MDNSRESPONDER - if (polldata[2].revents & POLLIN) - DNSServiceProcessResult(DNSSDMaster); -#endif /* HAVE_MDNSRESPONDER */ - -#ifdef HAVE_DNSSD if (printer->dnssd_collision) register_printer(printer); -#endif /* HAVE_DNSSD */ /* * Clean out old jobs... @@ -7090,7 +6845,7 @@ show_media(ippeve_client_t *client) /* I - Client connection */ else media_ready = ippAddString(printer->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-ready", NULL, media_size); - media_col = create_media_col(media_size, media_source, media_type, media->width, media->length, -1, -1, -1, -1); + media_col = create_media_col(media_size, media_source, media_type, create_media_size(media->width, media->length), -1, -1, -1, -1); if (media_col_ready) ippSetCollection(printer->attrs, &media_col_ready, ippGetCount(media_col_ready), media_col); @@ -7107,7 +6862,10 @@ show_media(ippeve_client_t *client) /* I - Client connection */ else ready_sheets = 0; - snprintf(tray_str, sizeof(tray_str), "type=sheetFeedAuto%sRemovableTray;mediafeed=%d;mediaxfeed=%d;maxcapacity=%d;level=%d;status=0;name=%s;", !strcmp(media_source, "by-pass-tray") ? "Non" : "", media ? media->length : 0, media ? media->width : 0, strcmp(media_source, "by-pass-tray") ? 250 : 25, ready_sheets, media_source); + if (!strcmp(media_source, "roll")) + snprintf(tray_str, sizeof(tray_str), "type=continuousRoll;mediafeed=%d;mediaxfeed=%d;maxcapacity=%d;level=%d;status=0;name=%s;", media ? media->length : 0, media ? media->width : 0, 100, ready_sheets, media_source); + else + snprintf(tray_str, sizeof(tray_str), "type=sheetFeedAuto%sRemovableTray;mediafeed=%d;mediaxfeed=%d;maxcapacity=%d;level=%d;status=0;name=%s;", !strcmp(media_source, "by-pass-tray") ? "Non" : "", media ? media->length : 0, media ? media->width : 0, strcmp(media_source, "by-pass-tray") ? 250 : 25, ready_sheets, media_source); ippSetOctetString(printer->attrs, &input_tray, i, tray_str, strlen(tray_str)); @@ -7148,6 +6906,9 @@ show_media(ippeve_client_t *client) /* I - Client connection */ ready_source = ippGetString(ippFindAttribute(media_col, "media-source", IPP_TAG_ZERO), 0, NULL); ready_type = ippGetString(ippFindAttribute(media_col, "media-type", IPP_TAG_ZERO), 0, NULL); + if (!ready_size) + ready_size = ippGetString(media_ready, j, NULL); + if (ready_source && !strcmp(ready_source, media_source)) break; @@ -7165,11 +6926,13 @@ show_media(ippeve_client_t *client) /* I - Client connection */ if (printer->web_forms) { html_printf(client, ""); } diff --git a/tools/ippfind.c b/tools/ippfind.c index 2ff420aa7..e6008b1f4 100644 --- a/tools/ippfind.c +++ b/tools/ippfind.c @@ -24,17 +24,7 @@ # include #endif /* _WIN32 */ #include -#ifdef HAVE_MDNSRESPONDER -# include -#elif defined(HAVE_AVAHI) -# include -# include -# include -# include -# include -# include -# define kDNSServiceMaxDomainName AVAHI_DOMAIN_NAME_MAX -#endif /* HAVE_MDNSRESPONDER */ +#include #ifndef _WIN32 extern char **environ; /* Process environment variables */ @@ -98,13 +88,15 @@ typedef struct ippfind_expr_s /* Expression */ char **args; /* Arguments for exec */ } ippfind_expr_t; +typedef struct ippfind_srvs_s /* Services array */ +{ + cups_rwlock_t rwlock; /* R/W lock */ + cups_array_t *services; /* Services array */ +} ippfind_srvs_t; + typedef struct ippfind_srv_s /* Service information */ { -#ifdef HAVE_MDNSRESPONDER - DNSServiceRef ref; /* Service reference for query */ -#elif defined(HAVE_AVAHI) - AvahiServiceResolver *ref; /* Resolver */ -#endif /* HAVE_MDNSRESPONDER */ + cups_dnssd_resolve_t *resolve; /* Resolve request */ char *name, /* Service name */ *domain, /* Domain name */ *regtype, /* Registration type */ @@ -125,15 +117,7 @@ typedef struct ippfind_srv_s /* Service information */ * Local globals... */ -#ifdef HAVE_MDNSRESPONDER -static DNSServiceRef dnssd_ref; /* Master service reference */ -#elif defined(HAVE_AVAHI) -static AvahiClient *avahi_client = NULL;/* Client information */ -static int avahi_got_data = 0; /* Got data from poll? */ -static AvahiSimplePoll *avahi_poll = NULL; - /* Poll information */ -#endif /* HAVE_MDNSRESPONDER */ - +static cups_dnssd_t *dnssd; /* DNS-SD context */ static int address_family = AF_UNSPEC; /* Address family for LIST */ static int bonjour_error = 0; /* Error browsing/resolving? */ @@ -145,42 +129,15 @@ static int ipp_version = 20; /* IPP version for LIST */ * Local functions... */ -#ifdef HAVE_MDNSRESPONDER -static void DNSSD_API browse_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) _CUPS_NONNULL(1,5,6,7,8); -static void DNSSD_API browse_local_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *serviceName, const char *regtype, const char *replyDomain, void *context) _CUPS_NONNULL(1,5,6,7,8); -#elif defined(HAVE_AVAHI) -static void browse_callback(AvahiServiceBrowser *browser, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *serviceName, const char *regtype, const char *replyDomain, AvahiLookupResultFlags flags, void *context); -static void client_callback(AvahiClient *client, AvahiClientState state, void *context); -#endif /* HAVE_MDNSRESPONDER */ - +static void browse_callback(cups_dnssd_browse_t *browse, void *context, cups_dnssd_flags_t flags, uint32_t if_index, const char *serviceName, const char *regtype, const char *replyDomain); static int compare_services(ippfind_srv_t *a, ippfind_srv_t *b); -static const char *dnssd_error_string(int error); static int eval_expr(ippfind_srv_t *service, ippfind_expr_t *expressions); static int exec_program(ippfind_srv_t *service, size_t num_args, char **args); -static ippfind_srv_t *get_service(cups_array_t *services, const char *serviceName, const char *regtype, const char *replyDomain) _CUPS_NONNULL(1,2,3,4); +static ippfind_srv_t *get_service(ippfind_srvs_t *services, const char *serviceName, const char *regtype, const char *replyDomain) _CUPS_NONNULL(1,2,3,4); static double get_time(void); static int list_service(ippfind_srv_t *service); static ippfind_expr_t *new_expr(ippfind_op_t op, bool invert, const char *value, const char *regex, char **args); -#ifdef HAVE_MDNSRESPONDER -static void DNSSD_API resolve_callback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *fullName, const char *hostTarget, uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context) _CUPS_NONNULL(1,5,6,9, 10); -#elif defined(HAVE_AVAHI) -static int poll_callback(struct pollfd *pollfds, - unsigned int num_pollfds, int timeout, - void *context); -static void resolve_callback(AvahiServiceResolver *res, - AvahiIfIndex interface, - AvahiProtocol protocol, - AvahiResolverEvent event, - const char *serviceName, - const char *regtype, - const char *replyDomain, - const char *host_name, - const AvahiAddress *address, - uint16_t port, - AvahiStringList *txt, - AvahiLookupResultFlags flags, - void *context); -#endif /* HAVE_MDNSRESPONDER */ +static void resolve_callback(cups_dnssd_resolve_t *resolve, void *context, cups_dnssd_flags_t flags, uint32_t if_index, const char *fullName, const char *hostTarget, uint16_t port, size_t num_txt, cups_option_t *txt); static void set_service_uri(ippfind_srv_t *service); static void show_usage(void) _CUPS_NORETURN; static void show_version(void) _CUPS_NORETURN; @@ -204,7 +161,7 @@ main(int argc, /* I - Number of command-line args */ const char *opt, /* Option character */ *search; /* Current browse/resolve string */ cups_array_t *searches; /* Things to browse/resolve */ - cups_array_t *services; /* Service array */ + ippfind_srvs_t services; /* Services array */ ippfind_srv_t *service; /* Current service */ ippfind_expr_t *expressions = NULL, /* Expression tree */ @@ -216,11 +173,6 @@ main(int argc, /* I - Number of command-line args */ ippfind_op_t logic = IPPFIND_OP_AND; /* Logic for next expression */ int invert = 0; /* Invert expression? */ - int err; /* DNS-SD error */ -#ifdef HAVE_MDNSRESPONDER - fd_set sinput; /* Input set for select() */ - struct timeval stimeout; /* Timeout for select() */ -#endif /* HAVE_MDNSRESPONDER */ double endtime; /* End time */ static const char * const ops[] = /* Node operation names */ { @@ -259,7 +211,9 @@ main(int argc, /* I - Number of command-line args */ */ searches = cupsArrayNew(NULL, NULL, NULL, 0, NULL, NULL); - services = cupsArrayNew((cups_array_cb_t)compare_services, NULL, NULL, 0, NULL, NULL); + + cupsRWInit(&services.rwlock); + services.services = cupsArrayNew((cups_array_cb_t)compare_services, NULL, NULL, 0, NULL, NULL); /* * Parse command-line... @@ -1119,33 +1073,8 @@ main(int argc, /* I - Number of command-line args */ * Start up browsing/resolving... */ -#ifdef HAVE_MDNSRESPONDER - if ((err = DNSServiceCreateConnection(&dnssd_ref)) != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("ippfind: Unable to use Bonjour: %s"), - dnssd_error_string(err)); - exit(IPPFIND_EXIT_BONJOUR); - } - -#elif defined(HAVE_AVAHI) - if ((avahi_poll = avahi_simple_poll_new()) == NULL) - { - _cupsLangPrintf(stderr, _("ippfind: Unable to use Bonjour: %s"), - strerror(errno)); + if ((dnssd = cupsDNSSDNew(NULL, NULL)) == NULL) exit(IPPFIND_EXIT_BONJOUR); - } - - avahi_simple_poll_set_func(avahi_poll, poll_callback, NULL); - - avahi_client = avahi_client_new(avahi_simple_poll_get(avahi_poll), - 0, client_callback, avahi_poll, &err); - if (!avahi_client) - { - _cupsLangPrintf(stderr, _("ippfind: Unable to use Bonjour: %s"), - dnssd_error_string(err)); - exit(IPPFIND_EXIT_BONJOUR); - } -#endif /* HAVE_MDNSRESPONDER */ for (search = (const char *)cupsArrayGetFirst(searches); search; @@ -1215,29 +1144,13 @@ main(int argc, /* I - Number of command-line args */ if (!domain) domain = "local."; - service = get_service(services, name, regtype, domain); + service = get_service(&services, name, regtype, domain); if (getenv("IPPFIND_DEBUG")) fprintf(stderr, "Resolving name=\"%s\", regtype=\"%s\", domain=\"%s\"\n", name, regtype, domain); -#ifdef HAVE_MDNSRESPONDER - service->ref = dnssd_ref; - err = DNSServiceResolve(&(service->ref), - kDNSServiceFlagsShareConnection, 0, name, - regtype, domain, resolve_callback, - service); - -#elif defined(HAVE_AVAHI) - service->ref = avahi_service_resolver_new(avahi_client, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, name, - regtype, domain, - AVAHI_PROTO_UNSPEC, 0, - resolve_callback, service); - if (service->ref) - err = 0; - else - err = avahi_client_errno(avahi_client); -#endif /* HAVE_MDNSRESPONDER */ + if ((service->resolve = cupsDNSSDResolveNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, name, regtype, domain, resolve_callback, service)) == NULL) + exit(IPPFIND_EXIT_BONJOUR); } else { @@ -1248,47 +1161,8 @@ main(int argc, /* I - Number of command-line args */ if (getenv("IPPFIND_DEBUG")) fprintf(stderr, "Browsing for regtype=\"%s\", domain=\"%s\"\n", regtype, domain); -#ifdef HAVE_MDNSRESPONDER - DNSServiceRef ref; /* Browse reference */ - - ref = dnssd_ref; - err = DNSServiceBrowse(&ref, kDNSServiceFlagsShareConnection, 0, regtype, - domain, browse_callback, services); - - if (!err) - { - ref = dnssd_ref; - err = DNSServiceBrowse(&ref, kDNSServiceFlagsShareConnection, - kDNSServiceInterfaceIndexLocalOnly, regtype, - domain, browse_local_callback, services); - } - -#elif defined(HAVE_AVAHI) - char *subtype, /* Sub-type, if any */ - subtype_buf[256]; /* Sub-type buffer */ - - if ((subtype = strstr(regtype, ",_")) != NULL) - { - *subtype++ = '\0'; - snprintf(subtype_buf, sizeof(subtype_buf), "%s._sub.%s", subtype, regtype); - regtype = subtype_buf; - } - - if (avahi_service_browser_new(avahi_client, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, regtype, domain, 0, - browse_callback, services)) - err = 0; - else - err = avahi_client_errno(avahi_client); -#endif /* HAVE_MDNSRESPONDER */ - } - - if (err) - { - _cupsLangPrintf(stderr, _("ippfind: Unable to browse or resolve: %s"), - dnssd_error_string(err)); - - exit(IPPFIND_EXIT_BONJOUR); + if (!cupsDNSSDBrowseNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, regtype, domain, browse_callback, &services)) + exit(IPPFIND_EXIT_BONJOUR); } } @@ -1303,157 +1177,78 @@ main(int argc, /* I - Number of command-line args */ while (get_time() < endtime) { - int process = 0; /* Process services? */ - -#ifdef HAVE_MDNSRESPONDER - int fd = DNSServiceRefSockFD(dnssd_ref); - /* File descriptor for DNS-SD */ - - FD_ZERO(&sinput); - FD_SET(fd, &sinput); - - stimeout.tv_sec = 0; - stimeout.tv_usec = 500000; - - if (select(fd + 1, &sinput, NULL, NULL, &stimeout) < 0) - continue; - - if (FD_ISSET(fd, &sinput)) - { - /* - * Process responses... - */ - - DNSServiceProcessResult(dnssd_ref); - } - else - { - /* - * Time to process services... - */ - - process = 1; - } - -#elif defined(HAVE_AVAHI) - avahi_got_data = 0; - - if (avahi_simple_poll_iterate(avahi_poll, 500) > 0) - { - /* - * We've been told to exit the loop. Perhaps the connection to - * Avahi failed. - */ + /* + * Process any services that we have found... + */ - exit(IPPFIND_EXIT_BONJOUR); - } + size_t j, /* Looping var */ + count, /* Number of services */ + active = 0, /* Number of active resolves */ + resolved = 0, /* Number of resolved services */ + processed = 0; /* Number of processed services */ - if (!avahi_got_data) + cupsRWLockRead(&services.rwlock); + for (j = 0, count = cupsArrayGetCount(services.services); j < count; j ++) { - /* - * Time to process services... - */ - - process = 1; - } -#endif /* HAVE_MDNSRESPONDER */ + service = (ippfind_srv_t *)cupsArrayGetElement(services.services, j); - if (process) - { - /* - * Process any services that we have found... - */ + if (service->is_processed) + processed ++; - size_t active = 0, /* Number of active resolves */ - resolved = 0, /* Number of resolved services */ - processed = 0; /* Number of processed services */ + if (service->is_resolved) + resolved ++; - for (service = (ippfind_srv_t *)cupsArrayGetFirst(services); - service; - service = (ippfind_srv_t *)cupsArrayGetNext(services)) + if (!service->resolve && !service->is_resolved) { - if (service->is_processed) - processed ++; + /* + * Found a service, now resolve it (but limit to 50 active resolves...) + */ - if (service->is_resolved) - resolved ++; + if (active < 50) + { + if ((service->resolve = cupsDNSSDResolveNew(dnssd, CUPS_DNSSD_IF_INDEX_ANY, service->name, service->regtype, service->domain, resolve_callback, service)) == NULL) + exit(IPPFIND_EXIT_BONJOUR); - if (!service->ref && !service->is_resolved) - { - /* - * Found a service, now resolve it (but limit to 50 active resolves...) - */ + active ++; + } + } + else if (service->is_resolved && !service->is_processed) + { + /* + * Resolved, not process this service against the expressions... + */ - if (active < 50) - { -#ifdef HAVE_MDNSRESPONDER - service->ref = dnssd_ref; - err = DNSServiceResolve(&(service->ref), - kDNSServiceFlagsShareConnection, 0, - service->name, service->regtype, - service->domain, resolve_callback, - service); - -#elif defined(HAVE_AVAHI) - service->ref = avahi_service_resolver_new(avahi_client, - AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, - service->name, - service->regtype, - service->domain, - AVAHI_PROTO_UNSPEC, 0, - resolve_callback, - service); - if (service->ref) - err = 0; - else - err = avahi_client_errno(avahi_client); -#endif /* HAVE_MDNSRESPONDER */ + cupsDNSSDResolveDelete(service->resolve); + service->resolve = NULL; - if (err) - { - _cupsLangPrintf(stderr, - _("ippfind: Unable to browse or resolve: %s"), - dnssd_error_string(err)); - exit(IPPFIND_EXIT_BONJOUR); - } + if (getenv("IPPFIND_DEBUG")) + fprintf(stderr, "EVAL %s\n", service->uri); - active ++; - } - } - else if (service->is_resolved && !service->is_processed) - { - /* - * Resolved, not process this service against the expressions... - */ + if (eval_expr(service, expressions)) + status = IPPFIND_EXIT_TRUE; - if (service->ref) - { -#ifdef HAVE_MDNSRESPONDER - DNSServiceRefDeallocate(service->ref); -#else - avahi_service_resolver_free(service->ref); -#endif /* HAVE_MDNSRESPONDER */ + service->is_processed = true; + } + else if (service->resolve) + active ++; + } + cupsRWUnlock(&services.rwlock); - service->ref = NULL; - } + /* + * If we have processed all services we have discovered, then we are done. + */ - if (eval_expr(service, expressions)) - status = IPPFIND_EXIT_TRUE; + if (getenv("IPPFIND_DEBUG")) + fprintf(stderr, "STATUS processed=%u, resolved=%u, count=%u\n", (unsigned)processed, (unsigned)resolved, (unsigned)count); - service->is_processed = true; - } - else if (service->ref) - active ++; - } + if (processed > 0 && processed == cupsArrayGetCount(services.services) && bonjour_timeout <= 1.0) + break; - /* - * If we have processed all services we have discovered, then we are done. - */ + /* + * Give the browsers/resolvers some time... + */ - if (processed == cupsArrayGetCount(services) && bonjour_timeout <= 1.0) - break; - } + usleep(250000); } if (bonjour_error) @@ -1463,159 +1258,42 @@ main(int argc, /* I - Number of command-line args */ } -#ifdef HAVE_MDNSRESPONDER /* * 'browse_callback()' - Browse devices. */ -static void DNSSD_API +static void browse_callback( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Option flags */ - uint32_t interfaceIndex, /* I - Interface number */ - DNSServiceErrorType errorCode, /* I - Error, if any */ - const char *serviceName, /* I - Name of service/device */ - const char *regtype, /* I - Type of service */ - const char *replyDomain, /* I - Service domain */ - void *context) /* I - Services array */ -{ - /* - * Only process "add" data... - */ - - (void)sdRef; - (void)interfaceIndex; - - if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) - return; - - /* - * Get the device... - */ - - get_service((cups_array_t *)context, serviceName, regtype, replyDomain); -} - - -/* - * 'browse_local_callback()' - Browse local devices. - */ - -static void DNSSD_API -browse_local_callback( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Option flags */ - uint32_t interfaceIndex, /* I - Interface number */ - DNSServiceErrorType errorCode, /* I - Error, if any */ + cups_dnssd_browse_t *browse, /* I - Browse request */ + void *context, /* I - Services array */ + cups_dnssd_flags_t flags, /* I - Flags */ + uint32_t if_index, /* I - Interface */ const char *serviceName, /* I - Name of service/device */ const char *regtype, /* I - Type of service */ - const char *replyDomain, /* I - Service domain */ - void *context) /* I - Services array */ + const char *replyDomain) /* I - Service domain */ { ippfind_srv_t *service; /* Service */ + if (getenv("IPPFIND_DEBUG")) + fprintf(stderr, "B flags=0x%04X, if_index=%u, serviceName=\"%s\", regtype=\"%s\", replyDomain=\"%s\"\n", flags, if_index, serviceName, regtype, replyDomain); + + (void)browse; /* * Only process "add" data... */ - (void)sdRef; - (void)interfaceIndex; - - if (errorCode != kDNSServiceErr_NoError || !(flags & kDNSServiceFlagsAdd)) + if ((flags & CUPS_DNSSD_FLAGS_ERROR) || !(flags & CUPS_DNSSD_FLAGS_ADD)) return; /* * Get the device... */ - service = get_service((cups_array_t *)context, serviceName, regtype, - replyDomain); - service->is_local = 1; + service = get_service((ippfind_srvs_t *)context, serviceName, regtype, replyDomain); + if (if_index == CUPS_DNSSD_IF_INDEX_LOCAL) + service->is_local = 1; } -#endif /* HAVE_MDNSRESPONDER */ - - -#ifdef HAVE_AVAHI -/* - * 'browse_callback()' - Browse devices. - */ - -static void -browse_callback( - AvahiServiceBrowser *browser, /* I - Browser */ - AvahiIfIndex interface, /* I - Interface index (unused) */ - AvahiProtocol protocol, /* I - Network protocol (unused) */ - AvahiBrowserEvent event, /* I - What happened */ - const char *name, /* I - Service name */ - const char *type, /* I - Registration type */ - const char *domain, /* I - Domain */ - AvahiLookupResultFlags flags, /* I - Flags */ - void *context) /* I - Services array */ -{ - AvahiClient *client = avahi_service_browser_get_client(browser); - /* Client information */ - ippfind_srv_t *service; /* Service information */ - - - (void)interface; - (void)protocol; - (void)context; - - switch (event) - { - case AVAHI_BROWSER_FAILURE: - fprintf(stderr, "DEBUG: browse_callback: %s\n", - avahi_strerror(avahi_client_errno(client))); - bonjour_error = 1; - avahi_simple_poll_quit(avahi_poll); - break; - - case AVAHI_BROWSER_NEW: - /* - * This object is new on the network. Create a device entry for it if - * it doesn't yet exist. - */ - - service = get_service((cups_array_t *)context, name, type, domain); - - if (flags & AVAHI_LOOKUP_RESULT_LOCAL) - service->is_local = true; - break; - - case AVAHI_BROWSER_REMOVE: - case AVAHI_BROWSER_ALL_FOR_NOW: - case AVAHI_BROWSER_CACHE_EXHAUSTED: - break; - } -} - - -/* - * 'client_callback()' - Avahi client callback function. - */ - -static void -client_callback( - AvahiClient *client, /* I - Client information (unused) */ - AvahiClientState state, /* I - Current state */ - void *context) /* I - User data (unused) */ -{ - (void)client; - (void)context; - - /* - * If the connection drops, quit. - */ - - if (state == AVAHI_CLIENT_FAILURE) - { - fputs("DEBUG: Avahi connection failed.\n", stderr); - bonjour_error = 1; - avahi_simple_poll_quit(avahi_poll); - } -} -#endif /* HAVE_AVAHI */ /* @@ -1626,123 +1304,7 @@ static int /* O - Result of comparison */ compare_services(ippfind_srv_t *a, /* I - First device */ ippfind_srv_t *b) /* I - Second device */ { - return (strcmp(a->name, b->name)); -} - - -/* - * 'dnssd_error_string()' - Return an error string for an error code. - */ - -static const char * /* O - Error message */ -dnssd_error_string(int error) /* I - Error number */ -{ -# ifdef HAVE_MDNSRESPONDER - switch (error) - { - case kDNSServiceErr_NoError : - return ("OK."); - - default : - case kDNSServiceErr_Unknown : - return ("Unknown error."); - - case kDNSServiceErr_NoSuchName : - return ("Service not found."); - - case kDNSServiceErr_NoMemory : - return ("Out of memory."); - - case kDNSServiceErr_BadParam : - return ("Bad parameter."); - - case kDNSServiceErr_BadReference : - return ("Bad service reference."); - - case kDNSServiceErr_BadState : - return ("Bad state."); - - case kDNSServiceErr_BadFlags : - return ("Bad flags."); - - case kDNSServiceErr_Unsupported : - return ("Unsupported."); - - case kDNSServiceErr_NotInitialized : - return ("Not initialized."); - - case kDNSServiceErr_AlreadyRegistered : - return ("Already registered."); - - case kDNSServiceErr_NameConflict : - return ("Name conflict."); - - case kDNSServiceErr_Invalid : - return ("Invalid name."); - - case kDNSServiceErr_Firewall : - return ("Firewall prevents registration."); - - case kDNSServiceErr_Incompatible : - return ("Client library incompatible."); - - case kDNSServiceErr_BadInterfaceIndex : - return ("Bad interface index."); - - case kDNSServiceErr_Refused : - return ("Server prevents registration."); - - case kDNSServiceErr_NoSuchRecord : - return ("Record not found."); - - case kDNSServiceErr_NoAuth : - return ("Authentication required."); - - case kDNSServiceErr_NoSuchKey : - return ("Encryption key not found."); - - case kDNSServiceErr_NATTraversal : - return ("Unable to traverse NAT boundary."); - - case kDNSServiceErr_DoubleNAT : - return ("Unable to traverse double-NAT boundary."); - - case kDNSServiceErr_BadTime : - return ("Bad system time."); - - case kDNSServiceErr_BadSig : - return ("Bad signature."); - - case kDNSServiceErr_BadKey : - return ("Bad encryption key."); - - case kDNSServiceErr_Transient : - return ("Transient error occurred - please try again."); - - case kDNSServiceErr_ServiceNotRunning : - return ("Server not running."); - - case kDNSServiceErr_NATPortMappingUnsupported : - return ("NAT doesn't support NAT-PMP or UPnP."); - - case kDNSServiceErr_NATPortMappingDisabled : - return ("NAT supports NAT-PNP or UPnP but it is disabled."); - - case kDNSServiceErr_NoRouter : - return ("No Internet/default router configured."); - - case kDNSServiceErr_PollingMode : - return ("Service polling mode error."); - -#ifndef _WIN32 - case kDNSServiceErr_Timeout : - return ("Service timeout."); -#endif /* !_WIN32 */ - } - -# elif defined(HAVE_AVAHI) - return (avahi_strerror(error)); -# endif /* HAVE_MDNSRESPONDER */ + return (_cups_strcasecmp(a->name, b->name)); } @@ -2131,15 +1693,16 @@ exec_program(ippfind_srv_t *service, /* I - Service */ */ static ippfind_srv_t * /* O - Service */ -get_service(cups_array_t *services, /* I - Service array */ - const char *serviceName, /* I - Name of service/device */ - const char *regtype, /* I - Type of service */ - const char *replyDomain) /* I - Service domain */ +get_service(ippfind_srvs_t *services, /* I - Service array */ + const char *serviceName,/* I - Name of service/device */ + const char *regtype, /* I - Type of service */ + const char *replyDomain)/* I - Service domain */ { + size_t i, /* Looping var */ + count; /* Number of services */ ippfind_srv_t key, /* Search key */ *service; /* Service */ - char fullName[kDNSServiceMaxDomainName]; - /* Full name for query */ + char fullName[1024]; /* Full name for query */ /* @@ -2149,13 +1712,20 @@ get_service(cups_array_t *services, /* I - Service array */ key.name = (char *)serviceName; key.regtype = (char *)regtype; - for (service = cupsArrayFind(services, &key); - service; - service = cupsArrayGetNext(services)) - if (_cups_strcasecmp(service->name, key.name)) - break; - else if (!strcmp(service->regtype, key.regtype)) + cupsRWLockRead(&services->rwlock); + for (i = 0, count = cupsArrayGetCount(services->services); i < count; i ++) + { + service = (ippfind_srv_t *)cupsArrayGetElement(services->services, i); + + if (!_cups_strcasecmp(service->name, key.name) && !strcmp(service->regtype, key.regtype)) + { + cupsRWUnlock(&services->rwlock); return (service); + } + else if (_cups_strcasecmp(service->name, key.name) > 0) + break; + } + cupsRWUnlock(&services->rwlock); /* * Yes, add the service... @@ -2168,20 +1738,16 @@ get_service(cups_array_t *services, /* I - Service array */ service->domain = strdup(replyDomain); service->regtype = strdup(regtype); - cupsArrayAdd(services, service); + cupsRWLockWrite(&services->rwlock); + cupsArrayAdd(services->services, service); + cupsRWUnlock(&services->rwlock); /* * Set the "full name" of this service, which is used for queries and * resolves... */ -#ifdef HAVE_MDNSRESPONDER - DNSServiceConstructFullName(fullName, serviceName, regtype, replyDomain); -#else /* HAVE_AVAHI */ - avahi_service_name_join(fullName, kDNSServiceMaxDomainName, serviceName, - regtype, replyDomain); -#endif /* HAVE_MDNSRESPONDER */ - + cupsDNSSDAssembleFullName(fullName, sizeof(fullName), serviceName, regtype, replyDomain); service->fullName = strdup(fullName); return (service); @@ -2507,159 +2073,48 @@ new_expr(ippfind_op_t op, /* I - Operation */ } -#ifdef HAVE_AVAHI -/* - * 'poll_callback()' - Wait for input on the specified file descriptors. - * - * Note: This function is needed because avahi_simple_poll_iterate is broken - * and always uses a timeout of 0 (!) milliseconds. - * (Avahi Ticket #364) - */ - -static int /* O - Number of file descriptors matching */ -poll_callback( - struct pollfd *pollfds, /* I - File descriptors */ - unsigned int num_pollfds, /* I - Number of file descriptors */ - int timeout, /* I - Timeout in milliseconds (unused) */ - void *context) /* I - User data (unused) */ -{ - int val; /* Return value */ - - - (void)timeout; - (void)context; - - val = poll(pollfds, num_pollfds, 500); - - if (val > 0) - avahi_got_data = 1; - - return (val); -} -#endif /* HAVE_AVAHI */ - - /* * 'resolve_callback()' - Process resolve data. */ -#ifdef HAVE_MDNSRESPONDER -static void DNSSD_API +static void resolve_callback( - DNSServiceRef sdRef, /* I - Service reference */ - DNSServiceFlags flags, /* I - Data flags */ - uint32_t interfaceIndex, /* I - Interface */ - DNSServiceErrorType errorCode, /* I - Error, if any */ - const char *fullName, /* I - Full service name */ - const char *hostTarget, /* I - Hostname */ - uint16_t port, /* I - Port number (network byte order) */ - uint16_t txtLen, /* I - Length of TXT record data */ - const unsigned char *txtRecord, /* I - TXT record data */ - void *context) /* I - Service */ + cups_dnssd_resolve_t *resolve, /* I - Resolver */ + void *context, /* I - Service */ + cups_dnssd_flags_t flags, /* I - Flags */ + uint32_t if_index, /* I - Interface index */ + const char *fullName, /* I - Full service name */ + const char *hostTarget, /* I - Hostname */ + uint16_t port, /* I - Port number */ + size_t num_txt, /* I - Number of TXT key/value pairs */ + cups_option_t *txt) /* I - TXT key/value pairs */ { - char key[256], /* TXT key value */ - *value; /* Value from TXT record */ - const unsigned char *txtEnd; /* End of TXT record */ - uint8_t valueLen; /* Length of value */ ippfind_srv_t *service = (ippfind_srv_t *)context; /* Service */ + size_t i; /* Looping var */ + char *value; /* Pointer into value */ - /* - * Only process "add" data... - */ + if (getenv("IPPFIND_DEBUG")) + fprintf(stderr, "R flags=0x%04X, if_index=%u, fullName=\"%s\", hostTarget=\"%s\", port=%u, num_txt=%u, txt=%p\n", flags, if_index, fullName, hostTarget, port, (unsigned)num_txt, txt); - (void)sdRef; - (void)flags; - (void)interfaceIndex; + (void)resolve; + (void)if_index; (void)fullName; - if (errorCode != kDNSServiceErr_NoError) - { - _cupsLangPrintf(stderr, _("ippfind: Unable to browse or resolve: %s"), - dnssd_error_string(errorCode)); - bonjour_error = 1; - return; - } - - service->is_resolved = true; - service->host = strdup(hostTarget); - service->port = ntohs(port); - - value = service->host + strlen(service->host) - 1; - if (value >= service->host && *value == '.') - *value = '\0'; - /* - * Loop through the TXT key/value pairs and add them to an array... + * Only process "add" data... */ - for (txtEnd = txtRecord + txtLen; txtRecord < txtEnd; txtRecord += valueLen) - { - /* - * Ignore bogus strings... - */ - - valueLen = *txtRecord++; - - memcpy(key, txtRecord, valueLen); - key[valueLen] = '\0'; - - if ((value = strchr(key, '=')) == NULL) - continue; - - *value++ = '\0'; - - /* - * Add to array of TXT values... - */ - - service->num_txt = cupsAddOption(key, value, service->num_txt, - &(service->txt)); - } - - set_service_uri(service); -} - - -#elif defined(HAVE_AVAHI) -static void -resolve_callback( - AvahiServiceResolver *resolver, /* I - Resolver */ - AvahiIfIndex interface, /* I - Interface */ - AvahiProtocol protocol, /* I - Address protocol */ - AvahiResolverEvent event, /* I - Event */ - const char *serviceName,/* I - Service name */ - const char *regtype, /* I - Registration type */ - const char *replyDomain,/* I - Domain name */ - const char *hostTarget, /* I - FQDN */ - const AvahiAddress *address, /* I - Address */ - uint16_t port, /* I - Port number */ - AvahiStringList *txt, /* I - TXT records */ - AvahiLookupResultFlags flags, /* I - Lookup flags */ - void *context) /* I - Service */ -{ - char key[256], /* TXT key */ - *value; /* TXT value */ - ippfind_srv_t *service = (ippfind_srv_t *)context; - /* Service */ - AvahiStringList *current; /* Current TXT key/value pair */ - - - (void)address; - - if (event != AVAHI_RESOLVER_FOUND) + if (flags & CUPS_DNSSD_FLAGS_ERROR) { bonjour_error = 1; - - avahi_service_resolver_free(resolver); - avahi_simple_poll_quit(avahi_poll); return; } - service->is_resolved = 1; + service->is_resolved = true; service->host = strdup(hostTarget); - service->port = port; + service->port = ntohs(port); value = service->host + strlen(service->host) - 1; if (value >= service->host && *value == '.') @@ -2669,34 +2124,11 @@ resolve_callback( * Loop through the TXT key/value pairs and add them to an array... */ - for (current = txt; current; current = current->next) - { - /* - * Ignore bogus strings... - */ - - if (current->size > (sizeof(key) - 1)) - continue; - - memcpy(key, current->text, current->size); - key[current->size] = '\0'; - - if ((value = strchr(key, '=')) == NULL) - continue; - - *value++ = '\0'; - - /* - * Add to array of TXT values... - */ - - service->num_txt = cupsAddOption(key, value, service->num_txt, - &(service->txt)); - } + for (i = 0; i < num_txt; i ++) + service->num_txt = cupsAddOption(txt[i].name, txt[i].value, service->num_txt, &service->txt); set_service_uri(service); } -#endif /* HAVE_MDNSRESPONDER */ /* @@ -2752,8 +2184,7 @@ set_service_uri(ippfind_srv_t *service) /* I - Service */ service->resource = strdup(uri); } - httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL, - service->host, service->port, service->resource); + httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), scheme, NULL, service->host, service->port, service->resource); service->uri = strdup(uri); } diff --git a/xcode/libcups.xcodeproj/project.pbxproj b/xcode/libcups.xcodeproj/project.pbxproj index 33074edc4..324424f01 100644 --- a/xcode/libcups.xcodeproj/project.pbxproj +++ b/xcode/libcups.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 729181C32011560E005E7560 /* PBXTargetDependency */, 270D02281D707E5100EA9403 /* PBXTargetDependency */, 2767FC5619267469000F61D3 /* PBXTargetDependency */, + 2794E90D28AFFC3F00BEDC04 /* PBXTargetDependency */, 271284AB1CC11FA500E517C7 /* PBXTargetDependency */, 278C58D6136B641D00836530 /* PBXTargetDependency */, 271284AF1CC11FA500E517C7 /* PBXTargetDependency */, @@ -130,9 +131,9 @@ 273B1EB5226B3E5200428143 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5D1926750C000F61D3 /* Security.framework */; }; 273B1EBF226B3EF300428143 /* ippevepcl.c in Sources */ = {isa = PBXBuildFile; fileRef = 273B1EBE226B3EE300428143 /* ippevepcl.c */; }; 273B1EC0226B3EFF00428143 /* ippeveps.c in Sources */ = {isa = PBXBuildFile; fileRef = 273B1EBC226B3EE300428143 /* ippeveps.c */; }; - 273B1EC7226B41F700428143 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; }; - 273B1ECA226B420C00428143 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; }; - 273B1ECD226B421E00428143 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; }; + 273B1EC7226B41F700428143 /* libcups3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups3.dylib */; }; + 273B1ECA226B420C00428143 /* libcups3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups3.dylib */; }; + 273B1ECD226B421E00428143 /* libcups3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups3.dylib */; }; 273BF6C71333B5370022CAAB /* testcups.c in Sources */ = {isa = PBXBuildFile; fileRef = 273BF6C61333B5370022CAAB /* testcups.c */; }; 274770D72345342B0089BC31 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; }; 274770D82345342B0089BC31 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 278C58E5136B64AF00836530 /* CoreFoundation.framework */; }; @@ -167,7 +168,7 @@ 274FF6B81333B1C400317ECB /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 72220F09133305BB00FCA411 /* util.c */; }; 274FF6C61333B1C400317ECB /* dir.h in Headers */ = {isa = PBXBuildFile; fileRef = 72220ED4133305BB00FCA411 /* dir.h */; settings = {ATTRIBUTES = (); }; }; 276683FA1337F7A9000D33D0 /* ipptool.c in Sources */ = {isa = PBXBuildFile; fileRef = 276683F91337F7A9000D33D0 /* ipptool.c */; }; - 276683FD1337F7B8000D33D0 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; }; + 276683FD1337F7B8000D33D0 /* libcups3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups3.dylib */; }; 2767FC5219266A36000F61D3 /* testdest.c in Sources */ = {isa = PBXBuildFile; fileRef = 2767FC5119266A36000F61D3 /* testdest.c */; }; 2767FC58192674E0000F61D3 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; }; 2767FC5F1926750C000F61D3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC591926750C000F61D3 /* CoreFoundation.framework */; }; @@ -198,7 +199,23 @@ 278CA9052884D9B100367E41 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 278CA9042884D9B100367E41 /* rand.c */; }; 278CA9062884D9B100367E41 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 278CA9042884D9B100367E41 /* rand.c */; }; 278CA9072884D9B100367E41 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = 278CA9042884D9B100367E41 /* rand.c */; }; + 2794E8FF28AFFC2400BEDC04 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27CAFC60282C895700FE02FC /* libcrypto.a */; }; + 2794E90028AFFC2400BEDC04 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27CAFC5F282C895700FE02FC /* libssl.a */; }; + 2794E90128AFFC2400BEDC04 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; }; + 2794E90228AFFC2400BEDC04 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC591926750C000F61D3 /* CoreFoundation.framework */; }; + 2794E90328AFFC2400BEDC04 /* libiconv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5A1926750C000F61D3 /* libiconv.dylib */; }; + 2794E90428AFFC2400BEDC04 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5B1926750C000F61D3 /* libresolv.dylib */; }; + 2794E90528AFFC2400BEDC04 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5C1926750C000F61D3 /* libz.dylib */; }; + 2794E90628AFFC2400BEDC04 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5D1926750C000F61D3 /* Security.framework */; }; + 2794E90F28AFFC6600BEDC04 /* testdnssd.c in Sources */ = {isa = PBXBuildFile; fileRef = 2794E90E28AFFC6600BEDC04 /* testdnssd.c */; }; + 2794E91028B2E20A00BEDC04 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5E1926750C000F61D3 /* SystemConfiguration.framework */; }; 279AE6F52395B80F004DD600 /* libpam.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 279AE6F42395B80F004DD600 /* libpam.tbd */; }; + 27A8096128A9B9D500B20BC8 /* dnssd.h in Headers */ = {isa = PBXBuildFile; fileRef = 27A8095F28A9B9D500B20BC8 /* dnssd.h */; }; + 27A8096228A9B9D500B20BC8 /* dnssd.h in Headers */ = {isa = PBXBuildFile; fileRef = 27A8095F28A9B9D500B20BC8 /* dnssd.h */; }; + 27A8096328A9B9D500B20BC8 /* dnssd.h in Headers */ = {isa = PBXBuildFile; fileRef = 27A8095F28A9B9D500B20BC8 /* dnssd.h */; }; + 27A8096428A9B9D500B20BC8 /* dnssd.c in Sources */ = {isa = PBXBuildFile; fileRef = 27A8096028A9B9D500B20BC8 /* dnssd.c */; }; + 27A8096528A9B9D500B20BC8 /* dnssd.c in Sources */ = {isa = PBXBuildFile; fileRef = 27A8096028A9B9D500B20BC8 /* dnssd.c */; }; + 27A8096628A9B9D500B20BC8 /* dnssd.c in Sources */ = {isa = PBXBuildFile; fileRef = 27A8096028A9B9D500B20BC8 /* dnssd.c */; }; 27CAFC61282C895700FE02FC /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27CAFC5F282C895700FE02FC /* libssl.a */; }; 27CAFC62282C895700FE02FC /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27CAFC60282C895700FE02FC /* libcrypto.a */; }; 27CAFC63282C898300FE02FC /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 27CAFC60282C895700FE02FC /* libcrypto.a */; }; @@ -259,6 +276,7 @@ 27D3968C27BB3972003D3D8E /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D3968227BB390D003D3D8E /* libresolv.tbd */; }; 27D3968D27BB397F003D3D8E /* libiconv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D3967E27BB38E6003D3D8E /* libiconv.tbd */; }; 27D3968E27BB3989003D3D8E /* libresolv.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 27D3968227BB390D003D3D8E /* libresolv.tbd */; }; + 27E934E028B7E951001A0EA4 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5E1926750C000F61D3 /* SystemConfiguration.framework */; }; 720E854320164E7B00C6C411 /* ipp-file.c in Sources */ = {isa = PBXBuildFile; fileRef = 720E854120164E7A00C6C411 /* ipp-file.c */; }; 720E854420164E7B00C6C411 /* ipp-file.c in Sources */ = {isa = PBXBuildFile; fileRef = 720E854120164E7A00C6C411 /* ipp-file.c */; }; 72220EC51333056300FCA411 /* array.c in Sources */ = {isa = PBXBuildFile; fileRef = 72220EB81333056300FCA411 /* array.c */; }; @@ -396,7 +414,7 @@ 72CF95E318A13543000FCAE4 /* dest-job.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E018A13543000FCAE4 /* dest-job.c */; }; 72CF95E418A13543000FCAE4 /* dest-localization.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E118A13543000FCAE4 /* dest-localization.c */; }; 72CF95E518A13543000FCAE4 /* dest-options.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95E218A13543000FCAE4 /* dest-options.c */; }; - 72CF95EC18A19134000FCAE4 /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; }; + 72CF95EC18A19134000FCAE4 /* libcups3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups3.dylib */; }; 72CF95F318A19165000FCAE4 /* ippfind.c in Sources */ = {isa = PBXBuildFile; fileRef = 72CF95F218A19165000FCAE4 /* ippfind.c */; }; /* End PBXBuildFile section */ @@ -597,6 +615,20 @@ remoteGlobalIDString = 274FF6891333B1C400317ECB; remoteInfo = libcups_static; }; + 2794E8FB28AFFC2400BEDC04 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 72BF96371333042100B1EAD7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 274FF6891333B1C400317ECB; + remoteInfo = libcups_static; + }; + 2794E90C28AFFC3F00BEDC04 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 72BF96371333042100B1EAD7 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2794E8F928AFFC2400BEDC04; + remoteInfo = testdnssd; + }; 27D3966A27BA81D3003D3D8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 72BF96371333042100B1EAD7 /* Project object */; @@ -802,6 +834,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + 2794E90728AFFC2400BEDC04 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; 27D3967127BA81D3003D3D8E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -913,7 +954,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 2706965A1CADF3E200FFE5FB /* libcups_ios.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 2706965A1CADF3E200FFE5FB /* libcups3_ios.a */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups3_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; 270B267E17F5C06700C8A3A9 /* tls-gnutls.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-gnutls.c"; path = "../cups/tls-gnutls.c"; sourceTree = ""; }; 270D02241D707E0200EA9403 /* testcreds */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testcreds; sourceTree = BUILT_PRODUCTS_DIR; }; 270D02251D707E3700EA9403 /* testcreds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testcreds.c; path = ../cups/testcreds.c; sourceTree = ""; }; @@ -957,7 +998,11 @@ 278C58E7136B64B000836530 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; 278C58E8136B64B000836530 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = ""; }; 278CA9042884D9B100367E41 /* rand.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rand.c; path = ../cups/rand.c; sourceTree = ""; }; + 2794E90B28AFFC2400BEDC04 /* testdnssd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testdnssd; sourceTree = BUILT_PRODUCTS_DIR; }; + 2794E90E28AFFC6600BEDC04 /* testdnssd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testdnssd.c; path = ../cups/testdnssd.c; sourceTree = ""; }; 279AE6F42395B80F004DD600 /* libpam.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libpam.tbd; path = usr/lib/libpam.tbd; sourceTree = SDKROOT; }; + 27A8095F28A9B9D500B20BC8 /* dnssd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dnssd.h; path = ../cups/dnssd.h; sourceTree = ""; }; + 27A8096028A9B9D500B20BC8 /* dnssd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dnssd.c; path = ../cups/dnssd.c; sourceTree = ""; }; 27CAFC5F282C895700FE02FC /* libssl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libssl.a; path = ../../../../../usr/local/lib/libssl.a; sourceTree = ""; }; 27CAFC60282C895700FE02FC /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = ../../../../../usr/local/lib/libcrypto.a; sourceTree = ""; }; 27CAFC6F282C8ADF00FE02FC /* tls-openssl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "tls-openssl.c"; path = "../cups/tls-openssl.c"; sourceTree = ""; }; @@ -970,7 +1015,7 @@ 27D3968227BB390D003D3D8E /* libresolv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libresolv.tbd; path = usr/lib/libresolv.tbd; sourceTree = SDKROOT; }; 27F89DA21B3AC43B00E5A4B7 /* testraster.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = testraster.c; path = ../cups/testraster.c; sourceTree = ""; }; 720E854120164E7A00C6C411 /* ipp-file.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "ipp-file.c"; path = "../cups/ipp-file.c"; sourceTree = ""; }; - 72220EAE1333047D00FCA411 /* libcups.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + 72220EAE1333047D00FCA411 /* libcups3.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libcups3.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; 72220EB81333056300FCA411 /* array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = array.c; path = ../cups/array.c; sourceTree = ""; }; 72220EB91333056300FCA411 /* array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = array.h; path = ../cups/array.h; sourceTree = ""; }; 72220EBB1333056300FCA411 /* auth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = auth.c; path = ../cups/auth.c; sourceTree = ""; }; @@ -1118,7 +1163,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 273B1EC7226B41F700428143 /* libcups.dylib in Frameworks */, + 273B1EC7226B41F700428143 /* libcups3.dylib in Frameworks */, 273B1EA1226B3E4800428143 /* CoreFoundation.framework in Frameworks */, 273B1EA2226B3E4800428143 /* libresolv.dylib in Frameworks */, 273B1EA3226B3E4800428143 /* libz.dylib in Frameworks */, @@ -1130,7 +1175,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 273B1ECD226B421E00428143 /* libcups.dylib in Frameworks */, + 273B1ECD226B421E00428143 /* libcups3.dylib in Frameworks */, 273B1EB2226B3E5200428143 /* CoreFoundation.framework in Frameworks */, 273B1EB3226B3E5200428143 /* libresolv.dylib in Frameworks */, 273B1EB4226B3E5200428143 /* libz.dylib in Frameworks */, @@ -1186,7 +1231,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 276683FD1337F7B8000D33D0 /* libcups.dylib in Frameworks */, + 276683FD1337F7B8000D33D0 /* libcups3.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1234,6 +1279,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2794E8FE28AFFC2400BEDC04 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2794E91028B2E20A00BEDC04 /* SystemConfiguration.framework in Frameworks */, + 2794E8FF28AFFC2400BEDC04 /* libcrypto.a in Frameworks */, + 2794E90028AFFC2400BEDC04 /* libssl.a in Frameworks */, + 2794E90128AFFC2400BEDC04 /* libcups_static.a in Frameworks */, + 2794E90228AFFC2400BEDC04 /* CoreFoundation.framework in Frameworks */, + 2794E90328AFFC2400BEDC04 /* libiconv.dylib in Frameworks */, + 2794E90428AFFC2400BEDC04 /* libresolv.dylib in Frameworks */, + 2794E90528AFFC2400BEDC04 /* libz.dylib in Frameworks */, + 2794E90628AFFC2400BEDC04 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 27D3966D27BA81D3003D3D8E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1252,6 +1313,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 27E934E028B7E951001A0EA4 /* SystemConfiguration.framework in Frameworks */, 27CAFC61282C895700FE02FC /* libssl.a in Frameworks */, 27CAFC62282C895700FE02FC /* libcrypto.a in Frameworks */, 728FB7F11536167A005426E1 /* libiconv.dylib in Frameworks */, @@ -1376,7 +1438,7 @@ buildActionMask = 2147483647; files = ( 279AE6F52395B80F004DD600 /* libpam.tbd in Frameworks */, - 273B1ECA226B420C00428143 /* libcups.dylib in Frameworks */, + 273B1ECA226B420C00428143 /* libcups3.dylib in Frameworks */, 2767FC6619267538000F61D3 /* CoreFoundation.framework in Frameworks */, 2767FC6719267538000F61D3 /* libresolv.dylib in Frameworks */, 2767FC6819267538000F61D3 /* libz.dylib in Frameworks */, @@ -1403,7 +1465,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 72CF95EC18A19134000FCAE4 /* libcups.dylib in Frameworks */, + 72CF95EC18A19134000FCAE4 /* libcups3.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1432,6 +1494,7 @@ 270D02251D707E3700EA9403 /* testcreds.c */, 273BF6C61333B5370022CAAB /* testcups.c */, 2767FC5119266A36000F61D3 /* testdest.c */, + 2794E90E28AFFC6600BEDC04 /* testdnssd.c */, 727EF045192E3544001EF690 /* testfile.c */, 278C58E2136B647200836530 /* testhttp.c */, 727EF046192E3544001EF690 /* testi18n.c */, @@ -1472,7 +1535,7 @@ 72A4332F155844CF002E172D /* libcups_static.a */, 72CF95F118A19134000FCAE4 /* ipptool copy */, 2767FC5019266A0D000F61D3 /* testdest */, - 2706965A1CADF3E200FFE5FB /* libcups_ios.a */, + 2706965A1CADF3E200FFE5FB /* libcups3_ios.a */, 724FA5481CC037370092477B /* testarray */, 724FA5811CC037810092477B /* testfile */, 724FA5941CC037980092477B /* testi18n */, @@ -1489,6 +1552,7 @@ 274770E02345342B0089BC31 /* testthreads */, 2778BBD9275DA09B0070DA11 /* fuzzipp */, 27D3967527BA81D3003D3D8E /* testtestpage */, + 2794E90B28AFFC2400BEDC04 /* testdnssd */, ); name = Products; sourceTree = ""; @@ -1514,6 +1578,8 @@ 72CF95E218A13543000FCAE4 /* dest-options.c */, 72220ED4133305BB00FCA411 /* dir.h */, 72220ED3133305BB00FCA411 /* dir.c */, + 27A8095F28A9B9D500B20BC8 /* dnssd.h */, + 27A8096028A9B9D500B20BC8 /* dnssd.c */, 72220ED6133305BB00FCA411 /* encode.c */, 72220ED9133305BB00FCA411 /* file.h */, 72220ED7133305BB00FCA411 /* file-private.h */, @@ -1593,7 +1659,7 @@ 278C58E6136B64B000836530 /* Kerberos.framework */, 278C58E7136B64B000836530 /* Security.framework */, 278C58E8136B64B000836530 /* SystemConfiguration.framework */, - 72220EAE1333047D00FCA411 /* libcups.dylib */, + 72220EAE1333047D00FCA411 /* libcups3.dylib */, ); name = Frameworks; sourceTree = ""; @@ -1658,6 +1724,7 @@ 270696441CADF3E200FFE5FB /* ipp-private.h in Headers */, 270696451CADF3E200FFE5FB /* language-private.h in Headers */, 270696461CADF3E200FFE5FB /* md5-internal.h in Headers */, + 27A8096228A9B9D500B20BC8 /* dnssd.h in Headers */, 270696481CADF3E200FFE5FB /* pwg-private.h in Headers */, 2706964A1CADF3E200FFE5FB /* string-private.h in Headers */, 7253C46C216ED5E500494ADD /* raster-private.h in Headers */, @@ -1681,6 +1748,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 27A8096328A9B9D500B20BC8 /* dnssd.h in Headers */, 722A24F52178D091000CAB20 /* debug-private.h in Headers */, 274FF6C61333B1C400317ECB /* dir.h in Headers */, 27D3966727BA81C6003D3D8E /* raster-testpage.h in Headers */, @@ -1701,6 +1769,7 @@ 72220F21133305BB00FCA411 /* ipp.h in Headers */, 72220F25133305BB00FCA411 /* language.h in Headers */, 722A24F32178D091000CAB20 /* debug-private.h in Headers */, + 27A8096128A9B9D500B20BC8 /* dnssd.h in Headers */, 72220F41133305BB00FCA411 /* transcode.h in Headers */, 72220F44133305BB00FCA411 /* base.h in Headers */, 72220ECD1333056300FCA411 /* cups-private.h in Headers */, @@ -1723,9 +1792,9 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 270695FD1CADF3E200FFE5FB /* libcups_ios */ = { + 270695FD1CADF3E200FFE5FB /* libcups3_ios */ = { isa = PBXNativeTarget; - buildConfigurationList = 270696571CADF3E200FFE5FB /* Build configuration list for PBXNativeTarget "libcups_ios" */; + buildConfigurationList = 270696571CADF3E200FFE5FB /* Build configuration list for PBXNativeTarget "libcups3_ios" */; buildPhases = ( 270695FE1CADF3E200FFE5FB /* Sources */, 270696331CADF3E200FFE5FB /* Frameworks */, @@ -1735,9 +1804,9 @@ ); dependencies = ( ); - name = libcups_ios; + name = libcups3_ios; productName = libcups; - productReference = 2706965A1CADF3E200FFE5FB /* libcups_ios.a */; + productReference = 2706965A1CADF3E200FFE5FB /* libcups3_ios.a */; productType = "com.apple.product-type.library.dynamic"; }; 270D02131D707E0200EA9403 /* testcreds */ = { @@ -1848,9 +1917,9 @@ productReference = 274770E02345342B0089BC31 /* testthreads */; productType = "com.apple.product-type.tool"; }; - 274FF6891333B1C400317ECB /* libcups_static */ = { + 274FF6891333B1C400317ECB /* libcups3_static */ = { isa = PBXNativeTarget; - buildConfigurationList = 274FF6DD1333B1C400317ECB /* Build configuration list for PBXNativeTarget "libcups_static" */; + buildConfigurationList = 274FF6DD1333B1C400317ECB /* Build configuration list for PBXNativeTarget "libcups3_static" */; buildPhases = ( 274FF68A1333B1C400317ECB /* Sources */, 274FF6B91333B1C400317ECB /* Frameworks */, @@ -1860,7 +1929,7 @@ ); dependencies = ( ); - name = libcups_static; + name = libcups3_static; productName = libcups; productReference = 72A4332F155844CF002E172D /* libcups_static.a */; productType = "com.apple.product-type.library.dynamic"; @@ -1937,6 +2006,24 @@ productReference = 278C58CB136B640300836530 /* testhttp */; productType = "com.apple.product-type.tool"; }; + 2794E8F928AFFC2400BEDC04 /* testdnssd */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2794E90828AFFC2400BEDC04 /* Build configuration list for PBXNativeTarget "testdnssd" */; + buildPhases = ( + 2794E8FC28AFFC2400BEDC04 /* Sources */, + 2794E8FE28AFFC2400BEDC04 /* Frameworks */, + 2794E90728AFFC2400BEDC04 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + 2794E8FA28AFFC2400BEDC04 /* PBXTargetDependency */, + ); + name = testdnssd; + productName = testcups; + productReference = 2794E90B28AFFC2400BEDC04 /* testdnssd */; + productType = "com.apple.product-type.tool"; + }; 27D3966827BA81D3003D3D8E /* testtestpage */ = { isa = PBXNativeTarget; buildConfigurationList = 27D3967227BA81D3003D3D8E /* Build configuration list for PBXNativeTarget "testtestpage" */; @@ -1955,9 +2042,9 @@ productReference = 27D3967527BA81D3003D3D8E /* testtestpage */; productType = "com.apple.product-type.tool"; }; - 72220EAD1333047D00FCA411 /* libcups */ = { + 72220EAD1333047D00FCA411 /* libcups3 */ = { isa = PBXNativeTarget; - buildConfigurationList = 72220EB21333047D00FCA411 /* Build configuration list for PBXNativeTarget "libcups" */; + buildConfigurationList = 72220EB21333047D00FCA411 /* Build configuration list for PBXNativeTarget "libcups3" */; buildPhases = ( 72220EAA1333047D00FCA411 /* Sources */, 72220EAB1333047D00FCA411 /* Frameworks */, @@ -1967,9 +2054,9 @@ ); dependencies = ( ); - name = libcups; + name = libcups3; productName = libcups; - productReference = 72220EAE1333047D00FCA411 /* libcups.dylib */; + productReference = 72220EAE1333047D00FCA411 /* libcups3.dylib */; productType = "com.apple.product-type.library.dynamic"; }; 724FA5371CC037370092477B /* testarray */ = { @@ -2199,9 +2286,9 @@ targets = ( 274FF5DE13332D3000317ECB /* All */, 273BF6D91333B6260022CAAB /* Tests */, - 72220EAD1333047D00FCA411 /* libcups */, - 270695FD1CADF3E200FFE5FB /* libcups_ios */, - 274FF6891333B1C400317ECB /* libcups_static */, + 72220EAD1333047D00FCA411 /* libcups3 */, + 270695FD1CADF3E200FFE5FB /* libcups3_ios */, + 274FF6891333B1C400317ECB /* libcups3_static */, 2778BBC9275DA09B0070DA11 /* fuzzipp */, 273B1E9A226B3E4800428143 /* ippevepcl */, 726AD6F6135E88F0002C930D /* ippeveprinter */, @@ -2213,6 +2300,7 @@ 270D02131D707E0200EA9403 /* testcreds */, 273BF6BC1333B5000022CAAB /* testcups */, 2767FC4619266A0D000F61D3 /* testdest */, + 2794E8F928AFFC2400BEDC04 /* testdnssd */, 724FA5701CC037810092477B /* testfile */, 278C58CA136B640300836530 /* testhttp */, 724FA5831CC037980092477B /* testi18n */, @@ -2240,6 +2328,7 @@ 270696091CADF3E200FFE5FB /* dir.c in Sources */, 2706960B1CADF3E200FFE5FB /* encode.c in Sources */, 2706960C1CADF3E200FFE5FB /* file.c in Sources */, + 27A8096528A9B9D500B20BC8 /* dnssd.c in Sources */, 2706960F1CADF3E200FFE5FB /* getputfile.c in Sources */, 270696101CADF3E200FFE5FB /* globals.c in Sources */, 270696111CADF3E200FFE5FB /* http-addr.c in Sources */, @@ -2360,6 +2449,7 @@ 274FF6B51333B1C400317ECB /* thread.c in Sources */, 274FF6B61333B1C400317ECB /* transcode.c in Sources */, 274FF6B71333B1C400317ECB /* usersys.c in Sources */, + 27A8096628A9B9D500B20BC8 /* dnssd.c in Sources */, 274FF6B81333B1C400317ECB /* util.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2396,6 +2486,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 2794E8FC28AFFC2400BEDC04 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2794E90F28AFFC6600BEDC04 /* testdnssd.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 27D3966B27BA81D3003D3D8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -2444,6 +2542,7 @@ 72220F40133305BB00FCA411 /* transcode.c in Sources */, 72220F42133305BB00FCA411 /* usersys.c in Sources */, 72220F43133305BB00FCA411 /* util.c in Sources */, + 27A8096428A9B9D500B20BC8 /* dnssd.c in Sources */, 72CF95E318A13543000FCAE4 /* dest-job.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2541,7 +2640,7 @@ /* Begin PBXTargetDependency section */ 270D02141D707E0200EA9403 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 270D02151D707E0200EA9403 /* PBXContainerItemProxy */; }; 270D02281D707E5100EA9403 /* PBXTargetDependency */ = { @@ -2551,7 +2650,7 @@ }; 271284911CC11FA500E517C7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 271284901CC11FA500E517C7 /* PBXContainerItemProxy */; }; 2712849F1CC11FA500E517C7 /* PBXTargetDependency */ = { @@ -2586,7 +2685,7 @@ }; 271286581CC1309000E517C7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 271286591CC1309000E517C7 /* PBXContainerItemProxy */; }; 271286E01CC13EF400E517C7 /* PBXTargetDependency */ = { @@ -2606,27 +2705,27 @@ }; 273B1EC6226B41E600428143 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 273B1EC5226B41E600428143 /* PBXContainerItemProxy */; }; 273B1EC9226B420500428143 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 273B1EC8226B420500428143 /* PBXContainerItemProxy */; }; 273B1ECC226B421700428143 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 273B1ECB226B421700428143 /* PBXContainerItemProxy */; }; 273BF6C91333B5410022CAAB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 273BF6C81333B5410022CAAB /* PBXContainerItemProxy */; }; 274770D22345342B0089BC31 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 274770D32345342B0089BC31 /* PBXContainerItemProxy */; }; 274770E42345347D0089BC31 /* PBXTargetDependency */ = { @@ -2636,12 +2735,12 @@ }; 274FF5E313332D4300317ECB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 274FF5E213332D4300317ECB /* PBXContainerItemProxy */; }; 276683FC1337F7B3000D33D0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 276683FB1337F7B3000D33D0 /* PBXContainerItemProxy */; }; 276683FF1337F7C5000D33D0 /* PBXTargetDependency */ = { @@ -2651,7 +2750,7 @@ }; 2767FC4719266A0D000F61D3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 2767FC4819266A0D000F61D3 /* PBXContainerItemProxy */; }; 2767FC5619267469000F61D3 /* PBXTargetDependency */ = { @@ -2661,7 +2760,7 @@ }; 2778BBCA275DA09B0070DA11 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 2778BBCB275DA09B0070DA11 /* PBXContainerItemProxy */; }; 2778BBDD275DA0ED0070DA11 /* PBXTargetDependency */ = { @@ -2676,12 +2775,22 @@ }; 278C58D8136B642F00836530 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 278C58D7136B642F00836530 /* PBXContainerItemProxy */; }; + 2794E8FA28AFFC2400BEDC04 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 274FF6891333B1C400317ECB /* libcups3_static */; + targetProxy = 2794E8FB28AFFC2400BEDC04 /* PBXContainerItemProxy */; + }; + 2794E90D28AFFC3F00BEDC04 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2794E8F928AFFC2400BEDC04 /* testdnssd */; + targetProxy = 2794E90C28AFFC3F00BEDC04 /* PBXContainerItemProxy */; + }; 27D3966927BA81D3003D3D8E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 27D3966A27BA81D3003D3D8E /* PBXContainerItemProxy */; }; 27D3967927BA8224003D3D8E /* PBXTargetDependency */ = { @@ -2691,47 +2800,47 @@ }; 724FA5381CC037370092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5391CC037370092477B /* PBXContainerItemProxy */; }; 724FA5711CC037810092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5721CC037810092477B /* PBXContainerItemProxy */; }; 724FA5841CC037980092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5851CC037980092477B /* PBXContainerItemProxy */; }; 724FA5971CC037AA0092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5981CC037AA0092477B /* PBXContainerItemProxy */; }; 724FA5AA1CC037C60092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5AB1CC037C60092477B /* PBXContainerItemProxy */; }; 724FA5D01CC037F00092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5D11CC037F00092477B /* PBXContainerItemProxy */; }; 724FA5F81CC038190092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA5F91CC038190092477B /* PBXContainerItemProxy */; }; 724FA60C1CC0382B0092477B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 724FA60D1CC0382B0092477B /* PBXContainerItemProxy */; }; 729181AF201155C1005E7560 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 729181B0201155C1005E7560 /* PBXContainerItemProxy */; }; 729181C32011560E005E7560 /* PBXTargetDependency */ = { @@ -2751,12 +2860,12 @@ }; 72BEA8D819AFA8BB0085F0F3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 274FF6891333B1C400317ECB /* libcups_static */; + target = 274FF6891333B1C400317ECB /* libcups3_static */; targetProxy = 72BEA8D719AFA8BB0085F0F3 /* PBXContainerItemProxy */; }; 72CF95E718A19134000FCAE4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 72220EAD1333047D00FCA411 /* libcups */; + target = 72220EAD1333047D00FCA411 /* libcups3 */; targetProxy = 72CF95E818A19134000FCAE4 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -2771,10 +2880,10 @@ COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = ""; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; SDKROOT = iphoneos; SKIP_INSTALL = YES; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; @@ -2791,10 +2900,10 @@ COMBINE_HIDPI_IMAGES = YES; EXECUTABLE_EXTENSION = a; EXECUTABLE_PREFIX = ""; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; SDKROOT = iphoneos; SKIP_INSTALL = YES; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; @@ -2957,9 +3066,9 @@ EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = libcups_static; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; }; name = Debug; @@ -2973,9 +3082,9 @@ EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/local/lib; MACH_O_TYPE = staticlib; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = libcups_static; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = static; }; name = Release; @@ -3054,6 +3163,24 @@ }; name = Release; }; + 2794E90928AFFC2400BEDC04 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 2794E90A28AFFC2400BEDC04 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = YES; + CODE_SIGN_IDENTITY = "-"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 27D3967327BA81D3003D3D8E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -3081,9 +3208,9 @@ DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/lib; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; }; name = Debug; }; @@ -3096,9 +3223,9 @@ DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; EXECUTABLE_PREFIX = ""; INSTALL_PATH = /usr/lib; - PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/cups; + PRIVATE_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/include/cups; + PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/libcups3/cups; }; name = Release; }; @@ -3443,7 +3570,7 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 270696571CADF3E200FFE5FB /* Build configuration list for PBXNativeTarget "libcups_ios" */ = { + 270696571CADF3E200FFE5FB /* Build configuration list for PBXNativeTarget "libcups3_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 270696581CADF3E200FFE5FB /* Debug */, @@ -3524,7 +3651,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 274FF6DD1333B1C400317ECB /* Build configuration list for PBXNativeTarget "libcups_static" */ = { + 274FF6DD1333B1C400317ECB /* Build configuration list for PBXNativeTarget "libcups3_static" */ = { isa = XCConfigurationList; buildConfigurations = ( 274FF6DE1333B1C400317ECB /* Debug */, @@ -3569,6 +3696,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 2794E90828AFFC2400BEDC04 /* Build configuration list for PBXNativeTarget "testdnssd" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2794E90928AFFC2400BEDC04 /* Debug */, + 2794E90A28AFFC2400BEDC04 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 27D3967227BA81D3003D3D8E /* Build configuration list for PBXNativeTarget "testtestpage" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3578,7 +3714,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 72220EB21333047D00FCA411 /* Build configuration list for PBXNativeTarget "libcups" */ = { + 72220EB21333047D00FCA411 /* Build configuration list for PBXNativeTarget "libcups3" */ = { isa = XCConfigurationList; buildConfigurations = ( 72220EB01333047D00FCA411 /* Debug */, diff --git a/xcode/libcups.xcodeproj/xcshareddata/xcschemes/libcups.xcscheme b/xcode/libcups.xcodeproj/xcshareddata/xcschemes/libcups.xcscheme index 5d3aa10df..cef1b92dd 100644 --- a/xcode/libcups.xcodeproj/xcshareddata/xcschemes/libcups.xcscheme +++ b/xcode/libcups.xcodeproj/xcshareddata/xcschemes/libcups.xcscheme @@ -15,8 +15,8 @@ @@ -51,8 +51,8 @@