diff options
Diffstat (limited to 'usr/src/lib')
319 files changed, 8089 insertions, 34806 deletions
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile index bae90c4045..f2692834b9 100644 --- a/usr/src/lib/Makefile +++ b/usr/src/lib/Makefile @@ -85,6 +85,8 @@ SUBDIRS += \ librt \ libadm \ libctf \ + libbrand .WAIT \ + libzonecfg .WAIT \ libdtrace \ libdtrace_jni \ libcurses \ @@ -111,6 +113,7 @@ SUBDIRS += \ libcryptoutil \ libinetutil \ libipadm \ + libipd \ libipmp \ libiscsit \ libkmf \ @@ -159,7 +162,8 @@ SUBDIRS += \ librdc \ libinstzones \ libpkg \ - libpcidb + libpcidb \ + libumem_trampoline SUBDIRS += \ passwdutil \ @@ -187,7 +191,6 @@ $(CLOSED_BUILD)SUBDIRS += \ $(CLOSED)/lib/libike SUBDIRS += \ nsswitch \ - print \ libuutil \ libscf \ libinetsvc \ @@ -205,10 +208,10 @@ SUBDIRS += \ libwrap \ libxcurses \ libxcurses2 \ - libbrand .WAIT \ - libzonecfg \ + libzdoor \ libzoneinfo \ libzonestat \ + libsmartsshd \ libtsnet \ libtsol \ gss_mechs/mech_spnego \ @@ -223,7 +226,6 @@ SUBDIRS += \ raidcfg_plugins \ cfgadm_plugins \ libmail \ - lvm \ libsmedia \ libipp \ libdiskmgt \ @@ -240,10 +242,7 @@ SUBDIRS += \ libzfs_core \ libzfs \ libbe \ - pylibbe \ libzfs_jni \ - pyzfs \ - pysolaris \ libmapid \ brand \ policykit \ @@ -304,9 +303,6 @@ fm: \ # NOWAIT_SUBDIRS= $(SUBDIRS:.WAIT=) -DCSUBDIRS = \ - lvm - MSGSUBDIRS= \ abi \ auditd_plugins \ @@ -362,12 +358,11 @@ MSGSUBDIRS= \ libwanbootutil \ libzfs \ libzonecfg \ - lvm \ + libzdoor \ + libsmartsshd \ madv \ mpss \ pam_modules \ - pyzfs \ - pysolaris \ rpcsec_gss \ libreparse MSGSUBDIRS += \ @@ -415,6 +410,7 @@ HDRSUBDIRS= \ libfstyp \ libgen \ libipadm \ + libipd \ libipsecutil \ libinetsvc \ libinetutil \ @@ -486,7 +482,6 @@ HDRSUBDIRS= \ libzonestat \ hal \ policykit \ - lvm \ pkcs11 \ passwdutil \ ../cmd/sendmail/libmilter \ @@ -628,6 +623,8 @@ libpool: libnvpair libexacct libpp: libast libzonecfg: libc libsocket libnsl libuuid libnvpair libsysevent libsec \ libbrand libpool libscf +libzdoor: libc libzonecfg libcontract +libsmartsshd: libc libcontract libproc: ../cmd/sgs/librtld_db ../cmd/sgs/libelf libctf libsaveargs libproject: libpool libproc libsecdb libtermcap: libcurses @@ -643,8 +640,6 @@ librestart: libuutil libscf libsaveargs: libdisasm ../cmd/sgs/libdl: ../cmd/sgs/libconv ../cmd/sgs/libelf: ../cmd/sgs/libconv -pkcs11: libcryptoutil -print: libldap5 udapl/udapl_tavor: udapl/libdat libzfs: libdevid libgen libnvpair libuutil \ libadm libavl libefi libidmap libmd libzfs_core @@ -669,9 +664,6 @@ sun_fc: libdevinfo libsysevent libnvpair libsun_ima: libdevinfo libsysevent libnsl sun_sas: libdevinfo libsysevent libnvpair libkstat libdevid libgrubmgmt: libdevinfo libzfs libfstyp -pylibbe: libbe libzfs -pyzfs: libnvpair libzfs -pysolaris: libsec libidmap libreparse: libnvpair libhotplug: libnvpair cfgadm_plugins: libhotplug diff --git a/usr/src/lib/Makefile.astmsg b/usr/src/lib/Makefile.astmsg index 096805e825..ff8202d03a 100644 --- a/usr/src/lib/Makefile.astmsg +++ b/usr/src/lib/Makefile.astmsg @@ -47,8 +47,8 @@ MSGLIBNAME= $(LIBRARY:.a=) ASTMSGCATALOG= $(ROOT)/usr/lib/locale/C/LC_MESSAGES/$(MSGLIBNAME) $(DO_BUILD_AST_CATALOGS)ASTMSGCC= \ - PATH="/usr/ast/bin/:/bin:/usr/bin" \ - /usr/bin/ksh93 /usr/ast/bin/msgcc >>msgcc.out 2>&1 + PATH="$(ASTBINDIR):/bin:/usr/bin" \ + /usr/bin/ksh93 $(MSGCC) >>msgcc.out 2>&1 ASTMSGS= $(OBJECTS:%.o=msgs/%.mso) diff --git a/usr/src/lib/brand/Makefile b/usr/src/lib/brand/Makefile index 05bfc54764..db59df2efc 100644 --- a/usr/src/lib/brand/Makefile +++ b/usr/src/lib/brand/Makefile @@ -30,7 +30,7 @@ include ../../Makefile.master # Build everything in parallel; use .WAIT for dependencies .PARALLEL: -SUBDIRS= shared .WAIT sn1 solaris10 ipkg labeled $($(MACH)_SUBDIRS) +SUBDIRS= shared .WAIT sn1 sngl solaris10 ipkg labeled $($(MACH)_SUBDIRS) MSGSUBDIRS= solaris10 shared $($(MACH)_MSGSUBDIRS) all := TARGET= all diff --git a/usr/src/lib/brand/sngl/Makefile b/usr/src/lib/brand/sngl/Makefile new file mode 100644 index 0000000000..780acc21e1 --- /dev/null +++ b/usr/src/lib/brand/sngl/Makefile @@ -0,0 +1,51 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2012, Joyent, Inc. All rights reserved. +# + +default: all + +include Makefile.sngl + +# Build everything in parallel; use .WAIT for dependencies +.PARALLEL: + +SUBDIRS = sngl_brand zone +MSGSUBDIRS = zone + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint +_msg := TARGET= _msg + +.KEEP_STATE: + +all install clean clobber lint: $(SUBDIRS) + +_msg: $(MSGSUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/print/libipp-core/sparc/Makefile b/usr/src/lib/brand/sngl/Makefile.sngl index 3b985583a4..0c7a280696 100644 --- a/usr/src/lib/print/libipp-core/sparc/Makefile +++ b/usr/src/lib/brand/sngl/Makefile.sngl @@ -19,12 +19,10 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" +# Copyright 2012 Joyent, Inc. All rights reserved. # -include ../Makefile.com +BRAND = sngl + +include $(SRC)/lib/brand/Makefile.brand -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/brand/sngl/sngl_brand/Makefile b/usr/src/lib/brand/sngl/sngl_brand/Makefile new file mode 100644 index 0000000000..4b667e1fa8 --- /dev/null +++ b/usr/src/lib/brand/sngl/sngl_brand/Makefile @@ -0,0 +1,47 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +include $(SRC)/lib/Makefile.lib + +default: all + +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint +_msg := TARGET= _msg + +.KEEP_STATE: + +all install clean clobber lint _msg: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: diff --git a/usr/src/lib/brand/sngl/sngl_brand/Makefile.com b/usr/src/lib/brand/sngl/sngl_brand/Makefile.com new file mode 100644 index 0000000000..070a03dcb5 --- /dev/null +++ b/usr/src/lib/brand/sngl/sngl_brand/Makefile.com @@ -0,0 +1,76 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012, Joyent, Inc. All rights reserved. +# + +LIBRARY = sngl_brand.a +VERS = .1 +COBJS = sngl_brand.o +ASOBJS = crt.o handler.o runexe.o brand_util.o +OBJECTS = $(COBJS) + +include ../../Makefile.sngl +include $(SRC)/lib/Makefile.lib + +SRCDIR = ../common +UTSBASE = $(SRC)/uts + +LIBS = $(DYNLIB) +CSRCS = $(COBJS:%o=../common/%c) +SHAREDOBJS = $(ASOBJS:%o=$(ISAOBJDIR)/%o) +SRCS = $(CSRCS) + +# +# Note that the architecture specific makefiles MUST update DYNFLAGS to +# explicitly specify an interpreter for the brand emulation library so that we +# use /lib/ld.so.1 or /lib/64/ld.so.1, which in a sngl zone is the system +# linker. +# +# Note that since the linker is used to setup processes before libc is loaded, +# it makes system calls directly (ie avoiding libc), and it makes these system +# calls before our library has been initialized. Since our library hasn't been +# initialized yet, there's no way for us to intercept and emulate any of those +# system calls. Luckily we don't have to. +# +# Note that we make sure to link our brand emulation library to libmapmalloc. +# This is required because in most cases there will be two copies of libc in +# the same process and we don't want them to fight over the heap. So for our +# brand library we link against libmapmalloc so that if we (our or copy of +# libc) try to allocate any memory it will be done via mmap() instead of brk(). +# +CPPFLAGS += -D_REENTRANT -U_ASM \ + -I. -I$(BRAND_SHARED)/brand/sys -I$(UTSBASE)/common/brand/sngl +CFLAGS += $(CCVERBOSE) +DYNFLAGS += $(DYNFLAGS_$(CLASS)) +DYNFLAGS += $(BLOCAL) $(ZNOVERSION) -Wl,-e_start +LDLIBS += -lc -lmapmalloc + +$(LIBS):= PICS += $(SHAREDOBJS) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include $(SRC)/lib/Makefile.targ diff --git a/usr/src/lib/brand/sngl/sngl_brand/amd64/Makefile b/usr/src/lib/brand/sngl/sngl_brand/amd64/Makefile new file mode 100644 index 0000000000..d019eaf841 --- /dev/null +++ b/usr/src/lib/brand/sngl/sngl_brand/amd64/Makefile @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012, Joyent, Inc. All rights reserved. +# + +ISAOBJDIR = $(BRAND_SHARED)/brand/amd64/pics/ + +include ../Makefile.com +include $(SRC)/lib/Makefile.lib.64 + +CPPFLAGS += -I$(BRAND_SHARED)/brand/amd64 + +# +# see ../Makefile.com for why we MUST explicity make ld.so.1 our interpreter +# +DYNFLAGS += -Wl,-I/lib/64/ld.so.1 +CPPFLAGS += -D_SYSCALL32 + +# Note that we also set the runtime path for the emulation library to point +# into /system. This is an attempt to ensure that our brand library get's the +# native version of libmapmallc. +# +DYNFLAGS += -R/lib/64 -R/system/usr/lib/64 + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS64) + +install: all $(ROOTLIBS64) diff --git a/usr/src/lib/print/mod_ipp/mapfile b/usr/src/lib/brand/sngl/sngl_brand/common/mapfile-vers index ffdec222b5..29800204f8 100644 --- a/usr/src/lib/print/mod_ipp/mapfile +++ b/usr/src/lib/brand/sngl/sngl_brand/common/mapfile-vers @@ -24,10 +24,6 @@ # # -# $Id: mapfile 149 2006-04-25 16:55:01Z njacobs $ -# - -# # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. @@ -43,10 +39,10 @@ $mapfile_version 2 -SYMBOL_VERSION SUNWprivate_1.0 { - global: - ipp_module; - +# +# Scope everything local -- our .init section is our only public interface. +# +SYMBOL_SCOPE { local: *; }; diff --git a/usr/src/lib/brand/sngl/sngl_brand/common/sngl_brand.c b/usr/src/lib/brand/sngl/sngl_brand/common/sngl_brand.c new file mode 100644 index 0000000000..d2b8d8702d --- /dev/null +++ b/usr/src/lib/brand/sngl/sngl_brand/common/sngl_brand.c @@ -0,0 +1,429 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2012, Joyent, Inc. All rights reserved. + */ + +#include <errno.h> +#include <fcntl.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <unistd.h> +#include <sys/brand.h> +#include <sys/syscall.h> +#include <sys/systm.h> +#include <sys/stat.h> +#include <libgen.h> +#include <sys/auxv.h> + +#include <sngl_brand.h> +#include <brand_misc.h> + +/* + * See usr/src/lib/brand/shared/brand/common/brand_util.c for general + * emulation notes. + */ + +#define CONF32_PATH "/system/usr/lib/brand/sngl/ld.sys.config" +#define CONF64_PATH "/system/usr/lib/brand/sngl/ld.sys64.config" + +brand_sysent_table_t brand_sysent_table[]; + +static boolean_t is_sys = B_FALSE; +static boolean_t is_crle = B_FALSE; + +typedef struct { + char *mnt_name; + dev_t mnt_id; +} sys_mnt_dev_t; + +/* + * The brand platform mounts several GZ file systems into the zone. We know + * which ones can actually be on seperate file systems, so we only stat those + * when checking for system commands. This reduces the number of stats needed + * when we start up. + */ +static sys_mnt_dev_t sys_mounts[] = { + {"/system/usr", 0}, + {"/lib", 0}, + {NULL, 0} +}; + +/* + * If this is a /sytem binary and ld.so is opening the default config file, + * then redirect so it opens the /system config file instead. We need to do it + * this way, instead of setting one of the LD_CONFIG env vars, since those + * are ignored for secure binaries. + * + * We don't redirect if we're crle so that it can still be used on the default + * config files. + */ +int +sngl_open(sysret_t *rval, char *path, int oflag, mode_t mode) +{ + char tstr[MAXPATHLEN]; + + if (is_sys && !is_crle) { + /* Get a copy of the path we're trying to open */ + bzero(tstr, sizeof (tstr)); + (void) brand_uucopystr(path, tstr, sizeof (tstr)); + + if (strcmp(tstr, "/var/ld/ld.config") == 0) + return (__systemcall(rval, SYS_open + 1024, + CONF32_PATH, oflag, mode)); + + if (strcmp(tstr, "/var/ld/64/ld.config") == 0) + return (__systemcall(rval, SYS_open + 1024, + CONF64_PATH, oflag, mode)); + } + + return (__systemcall(rval, SYS_open + 1024, path, oflag, mode)); +} + +/*ARGSUSED*/ +int +brand_init(int argc, char *argv[], char *envp[]) +{ + ulong_t ldentry; + int i; + uintptr_t *p; + auxv_t *ap; + struct stat64 buf; + char *bname; + + brand_pre_init(); + + /* + * Check if we're trying to run a system binary. + * + * We haven't installed our emulation table yet, so its safe to make + * system calls directly. + * + * First, get the /system devices, then stat the executable to see if + * its on one of the /system devs. + */ + for (i = 0; sys_mounts[i].mnt_name != NULL; i++) { + if (stat64(sys_mounts[i].mnt_name, &buf) != -1) + sys_mounts[i].mnt_id = buf.st_dev; + } + + /* Find the aux vector on the stack. */ + p = (uintptr_t *)envp; + while (*p != NULL) + p++; + p++; + + /* Find AT_SUN_EXECNAME */ + for (ap = (auxv_t *)p; ap->a_type != AT_NULL; ap++) { + if (ap->a_type != AT_SUN_EXECNAME) + continue; + if (stat64(ap->a_un.a_ptr, &buf) != -1) { + for (i = 0; sys_mounts[i].mnt_name != NULL; i++) { + if (sys_mounts[i].mnt_id == buf.st_dev) { + is_sys = B_TRUE; + bname = basename(ap->a_un.a_ptr); + if (strcmp("crle", bname) == 0) + is_crle = B_TRUE; + break; + } + } + } + break; + } + + ldentry = brand_post_init(SNGL_VERSION, argc, argv, envp); + + brand_runexe(argv, ldentry); + /*NOTREACHED*/ + brand_abort(0, "brand_runexe() returned"); + return (-1); +} + +/* + * This table must have at least NSYSCALL entries in it. + * + * The second parameter of each entry in the brand_sysent_table + * contains the number of parameters and flags that describe the + * syscall return value encoding. See the block comments at the + * top of this file for more information about the syscall return + * value flags and when they should be used. + */ +brand_sysent_table_t brand_sysent_table[] = { + NOSYS, /* 0 */ + NOSYS, /* 1 */ + NOSYS, /* 2 */ + NOSYS, /* 3 */ + NOSYS, /* 4 */ + EMULATE(sngl_open, 3 | RV_DEFAULT), /* 5 */ + NOSYS, /* 6 */ + NOSYS, /* 7 */ + NOSYS, /* 8 */ + NOSYS, /* 9 */ + NOSYS, /* 10 */ + NOSYS, /* 11 */ + NOSYS, /* 12 */ + NOSYS, /* 13 */ + NOSYS, /* 14 */ + NOSYS, /* 15 */ + NOSYS, /* 16 */ + NOSYS, /* 17 */ + NOSYS, /* 18 */ + NOSYS, /* 19 */ + NOSYS, /* 20 */ + NOSYS, /* 21 */ + NOSYS, /* 22 */ + NOSYS, /* 23 */ + NOSYS, /* 24 */ + NOSYS, /* 25 */ + NOSYS, /* 26 */ + NOSYS, /* 27 */ + NOSYS, /* 28 */ + NOSYS, /* 29 */ + NOSYS, /* 30 */ + NOSYS, /* 31 */ + NOSYS, /* 32 */ + NOSYS, /* 33 */ + NOSYS, /* 34 */ + NOSYS, /* 35 */ + NOSYS, /* 36 */ + NOSYS, /* 37 */ + NOSYS, /* 38 */ + NOSYS, /* 39 */ + NOSYS, /* 40 */ + NOSYS, /* 41 */ + NOSYS, /* 42 */ + NOSYS, /* 43 */ + NOSYS, /* 44 */ + NOSYS, /* 45 */ + NOSYS, /* 46 */ + NOSYS, /* 47 */ + NOSYS, /* 48 */ + NOSYS, /* 49 */ + NOSYS, /* 50 */ + NOSYS, /* 51 */ + NOSYS, /* 52 */ + NOSYS, /* 53 */ + NOSYS, /* 54 */ + NOSYS, /* 55 */ + NOSYS, /* 56 */ + NOSYS, /* 57 */ + NOSYS, /* 58 */ + NOSYS, /* 59 */ + NOSYS, /* 60 */ + NOSYS, /* 61 */ + NOSYS, /* 62 */ + NOSYS, /* 63 */ + NOSYS, /* 64 */ + NOSYS, /* 65 */ + NOSYS, /* 66 */ + NOSYS, /* 67 */ + NOSYS, /* 68 */ + NOSYS, /* 69 */ + NOSYS, /* 70 */ + NOSYS, /* 71 */ + NOSYS, /* 72 */ + NOSYS, /* 73 */ + NOSYS, /* 74 */ + NOSYS, /* 75 */ + NOSYS, /* 76 */ + NOSYS, /* 77 */ + NOSYS, /* 78 */ + NOSYS, /* 79 */ + NOSYS, /* 80 */ + NOSYS, /* 81 */ + NOSYS, /* 82 */ + NOSYS, /* 83 */ + NOSYS, /* 84 */ + NOSYS, /* 85 */ + NOSYS, /* 86 */ + NOSYS, /* 87 */ + NOSYS, /* 88 */ + NOSYS, /* 89 */ + NOSYS, /* 90 */ + NOSYS, /* 91 */ + NOSYS, /* 92 */ + NOSYS, /* 93 */ + NOSYS, /* 94 */ + NOSYS, /* 95 */ + NOSYS, /* 96 */ + NOSYS, /* 97 */ + NOSYS, /* 98 */ + NOSYS, /* 99 */ + NOSYS, /* 100 */ + NOSYS, /* 101 */ + NOSYS, /* 102 */ + NOSYS, /* 103 */ + NOSYS, /* 104 */ + NOSYS, /* 105 */ + NOSYS, /* 106 */ + NOSYS, /* 107 */ + NOSYS, /* 108 */ + NOSYS, /* 109 */ + NOSYS, /* 110 */ + NOSYS, /* 111 */ + NOSYS, /* 112 */ + NOSYS, /* 113 */ + NOSYS, /* 114 */ + NOSYS, /* 115 */ + NOSYS, /* 116 */ + NOSYS, /* 117 */ + NOSYS, /* 118 */ + NOSYS, /* 119 */ + NOSYS, /* 120 */ + NOSYS, /* 121 */ + NOSYS, /* 122 */ + NOSYS, /* 123 */ + NOSYS, /* 124 */ + NOSYS, /* 125 */ + NOSYS, /* 126 */ + NOSYS, /* 127 */ + NOSYS, /* 128 */ + NOSYS, /* 129 */ + NOSYS, /* 130 */ + NOSYS, /* 131 */ + NOSYS, /* 132 */ + NOSYS, /* 133 */ + NOSYS, /* 134 */ + NOSYS, /* 135 */ + NOSYS, /* 136 */ + NOSYS, /* 137 */ + NOSYS, /* 138 */ + NOSYS, /* 139 */ + NOSYS, /* 140 */ + NOSYS, /* 141 */ + NOSYS, /* 142 */ + NOSYS, /* 143 */ + NOSYS, /* 144 */ + NOSYS, /* 145 */ + NOSYS, /* 146 */ + NOSYS, /* 147 */ + NOSYS, /* 148 */ + NOSYS, /* 149 */ + NOSYS, /* 150 */ + NOSYS, /* 151 */ + NOSYS, /* 152 */ + NOSYS, /* 153 */ + NOSYS, /* 154 */ + NOSYS, /* 155 */ + NOSYS, /* 156 */ + NOSYS, /* 157 */ + NOSYS, /* 158 */ + NOSYS, /* 159 */ + NOSYS, /* 160 */ + NOSYS, /* 161 */ + NOSYS, /* 162 */ + NOSYS, /* 163 */ + NOSYS, /* 164 */ + NOSYS, /* 165 */ + NOSYS, /* 166 */ + NOSYS, /* 167 */ + NOSYS, /* 168 */ + NOSYS, /* 169 */ + NOSYS, /* 170 */ + NOSYS, /* 171 */ + NOSYS, /* 172 */ + NOSYS, /* 173 */ + NOSYS, /* 174 */ + NOSYS, /* 175 */ + NOSYS, /* 176 */ + NOSYS, /* 177 */ + NOSYS, /* 178 */ + NOSYS, /* 179 */ + NOSYS, /* 180 */ + NOSYS, /* 181 */ + NOSYS, /* 182 */ + NOSYS, /* 183 */ + NOSYS, /* 184 */ + NOSYS, /* 185 */ + NOSYS, /* 186 */ + NOSYS, /* 187 */ + NOSYS, /* 188 */ + NOSYS, /* 189 */ + NOSYS, /* 190 */ + NOSYS, /* 191 */ + NOSYS, /* 192 */ + NOSYS, /* 193 */ + NOSYS, /* 194 */ + NOSYS, /* 195 */ + NOSYS, /* 196 */ + NOSYS, /* 197 */ + NOSYS, /* 198 */ + NOSYS, /* 199 */ + NOSYS, /* 200 */ + NOSYS, /* 201 */ + NOSYS, /* 202 */ + NOSYS, /* 203 */ + NOSYS, /* 204 */ + NOSYS, /* 205 */ + NOSYS, /* 206 */ + NOSYS, /* 207 */ + NOSYS, /* 208 */ + NOSYS, /* 209 */ + NOSYS, /* 210 */ + NOSYS, /* 211 */ + NOSYS, /* 212 */ + NOSYS, /* 213 */ + NOSYS, /* 214 */ + NOSYS, /* 215 */ + NOSYS, /* 216 */ + NOSYS, /* 217 */ + NOSYS, /* 218 */ + NOSYS, /* 219 */ + NOSYS, /* 220 */ + NOSYS, /* 221 */ + NOSYS, /* 222 */ + NOSYS, /* 223 */ + NOSYS, /* 224 */ + NOSYS, /* 225 */ + NOSYS, /* 226 */ + NOSYS, /* 227 */ + NOSYS, /* 228 */ + NOSYS, /* 229 */ + NOSYS, /* 230 */ + NOSYS, /* 231 */ + NOSYS, /* 232 */ + NOSYS, /* 233 */ + NOSYS, /* 234 */ + NOSYS, /* 235 */ + NOSYS, /* 236 */ + NOSYS, /* 237 */ + NOSYS, /* 238 */ + NOSYS, /* 239 */ + NOSYS, /* 240 */ + NOSYS, /* 241 */ + NOSYS, /* 242 */ + NOSYS, /* 243 */ + NOSYS, /* 244 */ + NOSYS, /* 245 */ + NOSYS, /* 246 */ + NOSYS, /* 247 */ + NOSYS, /* 248 */ + NOSYS, /* 249 */ + NOSYS, /* 250 */ + NOSYS, /* 251 */ + NOSYS, /* 252 */ + NOSYS, /* 253 */ + NOSYS, /* 254 */ + NOSYS /* 255 */ +}; diff --git a/usr/src/lib/brand/sngl/sngl_brand/i386/Makefile b/usr/src/lib/brand/sngl/sngl_brand/i386/Makefile new file mode 100644 index 0000000000..a0c4927252 --- /dev/null +++ b/usr/src/lib/brand/sngl/sngl_brand/i386/Makefile @@ -0,0 +1,46 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012, Joyent, Inc. All rights reserved. +# + +ISAOBJDIR = $(BRAND_SHARED)/brand/i386/pics + +include ../Makefile.com + +CPPFLAGS += -I$(BRAND_SHARED)/brand/i386 + +# +# see ../Makefile.com for why we explicity make ld.so.1 our interpreter +# +DYNFLAGS += -Wl,-I/lib/ld.so.1 + +# Note that we also set the runtime path for the emulation library to point +# into /system. This is an attempt to ensure that our brand library get's the +# native version of libmapmallc. +# +DYNFLAGS += -R/lib -R/system/usr/lib + +CLEANFILES += $(DYNLIB) +CLOBBERFILES += $(ROOTLIBS) + +install: all $(ROOTLIBS) diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile b/usr/src/lib/brand/sngl/zone/Makefile index b92d620b10..42785deab3 100644 --- a/usr/src/lib/print/libpapi-dynamic/Makefile +++ b/usr/src/lib/brand/sngl/zone/Makefile @@ -18,39 +18,36 @@ # # CDDL HEADER END # + # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" +# Copyright 2012 Joyent, Inc. All rights reserved. # -include ../../Makefile.lib +PROGS = sinstall +XMLDOCS= config.xml platform.xml +CLOBBERFILES= $(ROOTPROGS) $(ROOTXMLDOCS) -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint +include $(SRC)/cmd/Makefile.cmd +include ../Makefile.sngl .KEEP_STATE: -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) +all: $(PROGS) -install_h: # $(ROOTHDRS) +POFILES = +POFILE = -check: # $(CHECKHDRS) +install: $(PROGS) $(ROOTPROGS) $(ROOTXMLDOCS) + crle -c $(ROOTBRANDDIR)/ld.sys.config \ + -l /lib:/system/usr/lib \ + -s /lib/secure:/system/usr/lib/secure + crle -64 -c $(ROOTBRANDDIR)/ld.sys64.config \ + -l /lib/64:/system/usr/lib/64 \ + -s /lib/secure/64:/system/usr/lib/secure/64 -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) +lint: -FRC: +clean: + -$(RM) $(PROGS) -include ../../Makefile.targ +include $(SRC)/cmd/Makefile.targ diff --git a/usr/src/lib/brand/sngl/zone/config.xml b/usr/src/lib/brand/sngl/zone/config.xml new file mode 100644 index 0000000000..86e58b6f8b --- /dev/null +++ b/usr/src/lib/brand/sngl/zone/config.xml @@ -0,0 +1,111 @@ +<?xml version="1.0"?> + +<!-- + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + Copyright 2012 Joyent, Inc. All rights reserved. + Use is subject to license terms. + + DO NOT EDIT THIS FILE. +--> + +<!DOCTYPE brand PUBLIC "-//Joyent Inc//DTD Brands//EN" + "file:///usr/share/lib/xml/dtd/brand.dtd.1"> + +<brand name="sngl"> + <modname>sngl_brand</modname> + + <initname>/system/sbin/init</initname> + <login_cmd>/system/usr/bin/login -z %Z %u</login_cmd> + <forcedlogin_cmd>/system/usr/bin/login -z %Z -f %u</forcedlogin_cmd> + <user_cmd>/system/usr/bin/getent passwd %u</user_cmd> + + <install>/usr/lib/brand/sngl/sinstall -z %z -R %R</install> + <installopts>R:t:U:q:z:</installopts> + <boot></boot> + <halt></halt> + <verify_cfg></verify_cfg> + <verify_adm></verify_adm> + <postclone></postclone> + <postinstall></postinstall> + <attach>/bin/true</attach> + <detach>/bin/true</detach> + <clone></clone> + <uninstall>/usr/lib/brand/joyent/juninstall -z %z -R %R</uninstall> + <prestatechange>/usr/lib/brand/joyent/prestate %z %R</prestatechange> + <poststatechange>/usr/lib/brand/joyent/poststate %z %R</poststatechange> + <query>/usr/lib/brand/joyent/query %z %R</query> + + <privilege set="default" name="contract_event" /> + <privilege set="default" name="contract_identity" /> + <privilege set="default" name="contract_observer" /> + <privilege set="default" name="dtrace_proc" /> + <privilege set="default" name="dtrace_user" /> + <privilege set="default" name="file_chown" /> + <privilege set="default" name="file_chown_self" /> + <privilege set="default" name="file_dac_execute" /> + <privilege set="default" name="file_dac_read" /> + <privilege set="default" name="file_dac_search" /> + <privilege set="default" name="file_dac_write" /> + <privilege set="default" name="file_owner" /> + <privilege set="default" name="file_setid" /> + <privilege set="default" name="ipc_dac_read" /> + <privilege set="default" name="ipc_dac_write" /> + <privilege set="default" name="ipc_owner" /> + <privilege set="default" name="net_bindmlp" /> + <privilege set="default" name="net_icmpaccess" /> + <privilege set="default" name="net_mac_aware" /> + <privilege set="default" name="net_observability" /> + <privilege set="default" name="net_privaddr" /> + <privilege set="default" name="net_rawaccess" ip-type="exclusive" /> + <privilege set="default" name="proc_chroot" /> + <privilege set="default" name="sys_audit" /> + <privilege set="default" name="proc_audit" /> + <privilege set="default" name="proc_lock_memory" /> + <privilege set="default" name="proc_owner" /> + <privilege set="default" name="proc_setid" /> + <privilege set="default" name="proc_taskid" /> + <privilege set="default" name="sys_acct" /> + <privilege set="default" name="sys_admin" /> + <privilege set="default" name="sys_ip_config" ip-type="exclusive" /> + <privilege set="default" name="sys_iptun_config" ip-type="exclusive" /> + <privilege set="default" name="sys_mount" /> + <privilege set="default" name="sys_nfs" /> + <privilege set="default" name="sys_resource" /> + <privilege set="default" name="sys_ppp_config" ip-type="exclusive" /> + + <privilege set="prohibited" name="dtrace_kernel" /> + <privilege set="prohibited" name="proc_zone" /> + <privilege set="prohibited" name="sys_config" /> + <privilege set="prohibited" name="sys_devices" /> + <privilege set="prohibited" name="sys_ip_config" ip-type="shared" /> + <privilege set="prohibited" name="sys_linkdir" /> + <privilege set="prohibited" name="sys_net_config" /> + <privilege set="prohibited" name="sys_res_config" /> + <privilege set="prohibited" name="sys_suser_compat" /> + <privilege set="prohibited" name="xvm_control" /> + <privilege set="prohibited" name="virt_manage" /> + <privilege set="prohibited" name="sys_ppp_config" ip-type="shared" /> + + <privilege set="required" name="proc_exec" /> + <privilege set="required" name="proc_fork" /> + <privilege set="required" name="sys_ip_config" ip-type="exclusive" /> + <privilege set="required" name="sys_mount" /> +</brand> diff --git a/usr/src/lib/brand/sngl/zone/platform.xml b/usr/src/lib/brand/sngl/zone/platform.xml new file mode 100644 index 0000000000..d9313f8b5c --- /dev/null +++ b/usr/src/lib/brand/sngl/zone/platform.xml @@ -0,0 +1,160 @@ +<?xml version="1.0"?> + +<!-- + CDDL HEADER START + + The contents of this file are subject to the terms of the + Common Development and Distribution License (the "License"). + You may not use this file except in compliance with the License. + + You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + or http://www.opensolaris.org/os/licensing. + See the License for the specific language governing permissions + and limitations under the License. + + When distributing Covered Code, include this CDDL HEADER in each + file and include the License file at usr/src/OPENSOLARIS.LICENSE. + If applicable, add the following below this CDDL HEADER, with the + fields enclosed by brackets "[]" replaced with your own identifying + information: Portions Copyright [yyyy] [name of copyright owner] + + CDDL HEADER END + + Copyright (c) 2012 Joyent, Inc. All rights reserved. + Use is subject to license terms. + + DO NOT EDIT THIS FILE. +--> + +<!DOCTYPE platform PUBLIC "-//Joyent Inc//Zones Platform//EN" + "file:///usr/share/lib/xml/dtd/zone_platform.dtd.1"> + +<platform name="sngl" allow-exclusive-ip="true"> + + <!-- Global filesystems to mount when booting the zone --> + <global_mount special="/dev" directory="/dev" type="dev" + opt="attrdir=%R/root/dev"/> + + <global_mount special="/lib" directory="/lib" + opt="ro,nodevices" type="lofs" /> + <global_mount special="%P/manifests/joyent" + directory="/lib/svc/manifest" + opt="ro,nodevices" type="lofs" /> + <global_mount special="%R/site" directory="/lib/svc/manifest/site" + opt="nodevices" type="lofs" /> + <global_mount special="/sbin" directory="/sbin" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/lib" directory="/system/lib" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/sbin" directory="/system/sbin" + opt="ro,nodevices" type="lofs" /> + <global_mount special="/usr" directory="/system/usr" + opt="ro,nodevices" type="lofs" /> + + <!-- Local filesystems to mount when booting the zone --> + <mount special="/proc" directory="/proc" type="proc" /> + <mount special="ctfs" directory="/system/contract" type="ctfs" /> + <mount special="mnttab" directory="/etc/mnttab" type="mntfs" /> + <mount special="objfs" directory="/system/object" type="objfs" /> + <mount special="lxproc" directory="/system/lxproc" type="lxproc" /> + <mount special="swap" directory="/etc/svc/volatile" type="tmpfs" /> + + <!-- Devices to create under /dev --> + <device match="arp" /> + <device match="bpf" /> + <device match="conslog" /> + <device match="cpu/self/cpuid" /> + <device match="crypto" /> + <device match="cryptoadm" /> + <device match="dsk" /> + <device match="dtrace/*" /> + <device match="dtrace/provider/*" /> + <device match="fd" /> + <device match="ipnet" /> + <device match="kstat" /> + <device match="lo0" /> + <device match="lofictl" /> + <device match="lofi" /> + <device match="log" /> + <device match="logindmux" /> + <device match="nsmb" /> + <device match="net/*" /> + <device match="null" /> + <device match="openprom" arch="sparc" /> + <device match="poll" /> + <device match="pool" /> + <device match="ptmx" /> + <device match="pts/*" /> + <device match="random" /> + <device match="rdsk" /> + <device match="rlofi" /> + <device match="rmt" /> + <device match="sad/user" /> + <device match="svvslo0" /> + <device match="svvslo1" /> + <device match="svvslo2" /> + <device match="svvslo3" /> + <device match="swap" /> + <device match="sysevent" /> + <device match="tap" /> + <device match="tcp" /> + <device match="tcp6" /> + <device match="term" /> + <device match="ticlts" /> + <device match="ticots" /> + <device match="ticotsord" /> + <device match="tty" /> + <device match="tun" /> + <device match="udp" /> + <device match="udp6" /> + <device match="urandom" /> + <device match="zero" /> + <device match="zfs" /> + <device match="zvol/dsk/%P/%z/*" /> + <device match="zvol/rdsk/%P/%z/*" /> + + <!-- Devices to create in exclusive IP zone only --> + <device match="dld" ip-type="exclusive" /> + <device match="icmp" ip-type="exclusive" /> + <device match="icmp6" ip-type="exclusive" /> + <device match="ip" ip-type="exclusive" /> + <device match="ip6" ip-type="exclusive" /> + <device match="ipauth" ip-type="exclusive" /> + <device match="ipd" ip-type="exclusive" /> + <device match="ipf" ip-type="exclusive" /> + <device match="ipl" ip-type="exclusive" /> + <device match="iplookup" ip-type="exclusive" /> + <device match="ipmpstub" ip-type="exclusive" /> + <device match="ipnat" ip-type="exclusive" /> + <device match="ipscan" ip-type="exclusive" /> + <device match="ipsecah" ip-type="exclusive" /> + <device match="ipsecesp" ip-type="exclusive" /> + <device match="ipstate" ip-type="exclusive" /> + <device match="ipsync" ip-type="exclusive" /> + <device match="keysock" ip-type="exclusive" /> + <device match="rawip" ip-type="exclusive" /> + <device match="rawip6" ip-type="exclusive" /> + <device match="rts" ip-type="exclusive" /> + <device match="sad/admin" ip-type="exclusive" /> + <device match="sctp" ip-type="exclusive" /> + <device match="sctp6" ip-type="exclusive" /> + <device match="spdsock" ip-type="exclusive" /> + <device match="sppp" ip-type="exclusive" /> + <device match="sppptun" ip-type="exclusive" /> + <device match="vni" ip-type="exclusive" /> + + <!-- Renamed devices to create under /dev --> + <device match="zcons/%z/zoneconsole" name="zconsole" /> + + <!-- Symlinks to create under /dev --> + <symlink source="console" target="zconsole" /> + <symlink source="dtremote" target="/dev/null" /> + <symlink source="msglog" target="zconsole" /> + <symlink source="stderr" target="./fd/2" /> + <symlink source="stdin" target="./fd/0" /> + <symlink source="stdout" target="./fd/1" /> + <symlink source="syscon" target="zconsole" /> + <symlink source="sysmsg" target="zconsole" /> + <symlink source="systty" target="zconsole" /> + +</platform> diff --git a/usr/src/lib/brand/sngl/zone/sinstall.sh b/usr/src/lib/brand/sngl/zone/sinstall.sh new file mode 100644 index 0000000000..70b02a06c5 --- /dev/null +++ b/usr/src/lib/brand/sngl/zone/sinstall.sh @@ -0,0 +1,106 @@ +#!/bin/ksh -p +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +unset LD_LIBRARY_PATH +PATH=/usr/bin:/usr/sbin +export PATH + +. /usr/lib/brand/shared/common.ksh +. /usr/lib/brand/joyent/common.ksh + +ZONENAME="" +ZONEPATH="" +# Default to 10GB diskset quota +ZQUOTA=10 + +while getopts "R:t:U:q:z:" opt +do + case "$opt" in + R) ZONEPATH="$OPTARG";; + t) TMPLZONE="$OPTARG";; + # UUID is only used in the postinstall script + U) UUID="$OPTARG";; + q) ZQUOTA="$OPTARG";; + z) ZONENAME="$OPTARG";; + *) printf "$m_usage\n" + exit $ZONE_SUBPROC_USAGE;; + esac +done +shift OPTIND-1 + +if [[ -n $(zonecfg -z "${ZONENAME}" info attr name=transition \ + | grep "value: receiving:") ]]; then + + # Here we're doing an install for a received zone, the dataset should have + # already been created. + exit $ZONE_SUBPROC_OK +fi + +if [[ -z $ZONEPATH || -z $ZONENAME ]]; then + print -u2 "Brand error: No zone path or name" + exit $ZONE_SUBPROC_USAGE +fi + +# The install requires a template zone. +if [[ -z $TMPLZONE ]]; then + print -u2 "Brand error: a zone template is required" + exit $ZONE_SUBPROC_USAGE +fi + +# The dataset quota must be a number. +case $ZQUOTA in *[!0-9]*) + print -u2 "Brand error: The quota $ZQUOTA is not a number" + exit $ZONE_SUBPROC_USAGE;; +esac + +ZROOT=$ZONEPATH/root + +# Get the dataset of the parent directory of the zonepath. +dname=${ZONEPATH%/*} +bname=${ZONEPATH##*/} +PDS_NAME=`mount | nawk -v p=$dname '{if ($1 == p) print $3}'` +[ -z "$PDS_NAME" ] && \ + print -u2 "Brand error: missing parent ZFS dataset for $dname" + +# We expect that zoneadm was invoked with '-x nodataset', so it won't have +# created the dataset. + +QUOTA_ARG= +if [[ ${ZQUOTA} != "0" ]]; then + QUOTA_ARG="-o quota=${ZQUOTA}g" +fi + +zfs snapshot $PDS_NAME/${TMPLZONE}@${bname} +zfs clone -F ${QUOTA_ARG} $PDS_NAME/${TMPLZONE}@${bname} \ + $PDS_NAME/$bname || fatal "failed to clone zone dataset" + +if [ ! -d ${ZONEPATH}/config ]; then + mkdir -p ${ZONEPATH}/config + chmod 755 ${ZONEPATH}/config +fi + +final_setup + +exit $ZONE_SUBPROC_OK diff --git a/usr/src/lib/efcode/interpreter/Makefile b/usr/src/lib/efcode/interpreter/Makefile index 82c44bbdc2..d7475b45bb 100644 --- a/usr/src/lib/efcode/interpreter/Makefile +++ b/usr/src/lib/efcode/interpreter/Makefile @@ -39,7 +39,8 @@ CERRWARN += -_gcc=-Wno-uninitialized LDFLAGS += -R/usr/lib/efcode/$(MACH64) -M mapfile64 LIBS = fcode.so fcdriver.so -$(PROG) := LDLIBS += -L/usr/lib/efcode/$(MACH64) $(LIBS:%=$(EFCODEDIR64)/%) +$(PROG) := LDLIBS += -L$(ADJUNCT_PROTO)/usr/lib/efcode/$(MACH64) \ + $(LIBS:%=$(EFCODEDIR64)/%) all: $(PROG) diff --git a/usr/src/lib/fm/libldom/Makefile.com b/usr/src/lib/fm/libldom/Makefile.com index 931961fe4a..859a177363 100644 --- a/usr/src/lib/fm/libldom/Makefile.com +++ b/usr/src/lib/fm/libldom/Makefile.com @@ -38,7 +38,7 @@ SRCDIR = ../sparc LIBS = $(DYNLIB) $(LINTLIB) CPPFLAGS += -I. -I$(SRC)/uts/sun4v -I$(ROOT)/usr/platform/sun4v/include \ - -I/usr/include/libxml2 -I/usr/sfw/include + -I$(ADJUNCT_PROTO)/usr/include/libxml2 CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS) CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) diff --git a/usr/src/lib/fm/topo/libtopo/Makefile.com b/usr/src/lib/fm/topo/libtopo/Makefile.com index 0b7dc59c6d..56871dd6d4 100644 --- a/usr/src/lib/fm/topo/libtopo/Makefile.com +++ b/usr/src/lib/fm/topo/libtopo/Makefile.com @@ -74,7 +74,7 @@ SRCDIR = ../common CLEANFILES += $(SRCDIR)/topo_error.c $(SRCDIR)/topo_tables.c -CPPFLAGS += -I../common -I/usr/include/libxml2 -I. +CPPFLAGS += -I../common -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I. CFLAGS += $(CCVERBOSE) $(C_BIGPICFLAGS) CFLAGS += -D_POSIX_PTHREAD_SEMANTICS CFLAGS64 += $(CCVERBOSE) $(C_BIGPICFLAGS) diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h index 1c3a92f804..7b29adad69 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_hc.h +++ b/usr/src/lib/fm/topo/libtopo/common/topo_hc.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #ifndef _TOPO_HC_H @@ -115,6 +116,10 @@ extern "C" { #define TOPO_PGROUP_BINDING "binding" #define TOPO_BINDING_OCCUPANT "occupant-path" +#define TOPO_BINDING_DRIVER "driver" +#define TOPO_BINDING_DEVCTL "devctl" +#define TOPO_BINDING_ENCLOSURE "enclosure" +#define TOPO_BINDING_SLOT "slot" #define TOPO_PGROUP_STORAGE "storage" #define TOPO_STORAGE_INITIATOR_PORT "initiator-port" diff --git a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c index 9e4c18c250..f26d5f6ef9 100644 --- a/usr/src/lib/fm/topo/libtopo/common/topo_xml.c +++ b/usr/src/lib/fm/topo/libtopo/common/topo_xml.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <libxml/parser.h> @@ -1376,16 +1377,10 @@ fac_enum_process(topo_mod_t *mp, xmlNodePtr pn, tnode_t *ptn) if ((fprov = xmlGetProp(cn, (xmlChar *)Provider)) == NULL) goto fenumdone; - - if (xmlStrcmp(fprov, (xmlChar *)"fac_prov_ipmi") != 0) { - topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, - "Invalid provider specified: %s\n", fprov); - goto fenumdone; - } - /* - * Invoke enum entry point in fac provider which will cause the - * facility enumeration node method to be registered. + * Invoke enum entry point in facility provider which will + * cause the facility enumeration node method to be + * registered. */ if (fac_enum_run(mp, ptn, (const char *)fprov) != 0) { topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, @@ -1440,12 +1435,6 @@ fac_process(topo_mod_t *mp, xmlNodePtr pn, tf_rdata_t *rd, tnode_t *ptn) xmlStrcmp(ftype, (xmlChar *)Indicator) != 0) goto facdone; - if (xmlStrcmp(provider, (xmlChar *)"fac_prov_ipmi") != 0) { - topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "fac_process: " - "Invalid provider attr value: %s\n", provider); - goto facdone; - } - if ((ntn = topo_node_facbind(mp, ptn, (char *)fname, (char *)ftype)) == NULL) goto facdone; @@ -1463,8 +1452,9 @@ fac_process(topo_mod_t *mp, xmlNodePtr pn, tf_rdata_t *rd, tnode_t *ptn) } } /* - * Invoke enum entry point in fac_prov_ipmi module, which will - * cause the provider methods to be registered on this node + * Invoke enum entry point in the facility provider module, + * which will cause the provider methods to be registered on + * this node */ if (fac_enum_run(mp, ntn, (const char *)provider) != 0) { topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "fac_process: " diff --git a/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Joyent-Compute-Platform-1101-disk-hc-topology.xmlgenksh b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Joyent-Compute-Platform-1101-disk-hc-topology.xmlgenksh new file mode 100755 index 0000000000..000742db71 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Joyent-Compute-Platform-1101-disk-hc-topology.xmlgenksh @@ -0,0 +1,95 @@ +#!/bin/ksh +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright (c) 2013, Joyent, Inc. All rights reserved. +# + +function do_node +{ + cat <<EOF + <node instance='${1}'> + <propgroup name='protocol' version='1' name-stability='Private' + data-stability='Private'> + <propval name='label' type='string' value='${2}' /> + </propgroup> + <propgroup name='binding' version='1' name-stability='Private' + data-stability='Private'> + <propval name='driver' type='string' value='mpt_sas' /> + <propval name='devctl' type='string' value='${3}' /> + <propval name='enclosure' type='uint32' value='${4}' /> + <propval name='slot' type='uint32' value='${5}' /> + </propgroup> + </node> +EOF +} + + +cat <<EOF +<topology name='disk' scheme='hc'> + <range name='bay' min='0' max='15'> + <facility name='fail' type='indicator' provider='fac_prov_mptsas' > + <propgroup name='facility' version='1' name-stability='Private' + data-stability='Private' > + <propval name='type' type='uint32' value='0' /> + <propmethod name='mptsas_led_mode' version='0' propname='mode' + proptype='uint32' mutable='1'> + </propmethod> + </propgroup> + </facility> + <facility name='ident' type='indicator' provider='fac_prov_mptsas' > + <propgroup name='facility' version='1' name-stability='Private' + data-stability='Private' > + <propval name='type' type='uint32' value='1' /> + <propmethod name='mptsas_led_mode' version='0' propname='mode' + proptype='uint32' mutable='1'> + </propmethod> + </propgroup> + </facility> + <facility name='ok2rm' type='indicator' provider='fac_prov_mptsas' > + <propgroup name='facility' version='1' name-stability='Private' + data-stability='Private' > + <propval name='type' type='uint32' value='2' /> + <propmethod name='mptsas_led_mode' version='0' propname='mode' + proptype='uint32' mutable='1'> + </propmethod> + </propgroup> + </facility> +EOF + +enclosure=1 +bay=0 +slot=0 +devctl='/devices/pci@0,0/pci8086,3c02@1/pci15d9,691@0:devctl' +while (( slot <= 7 )); do + do_node $bay "Front Disk $bay" "$devctl" $enclosure $slot + (( bay = bay + 1 )) + (( slot = slot + 1 )) +done + +slot=0 +devctl='/devices/pci@0,0/pci8086,3c06@2,2/pci15d9,691@0:devctl' +while (( slot <= 7 )); do + do_node $bay "Front Disk $bay" "$devctl" $enclosure $slot + (( bay = bay + 1 )) + (( slot = slot + 1 )) +done + +cat <<EOF + <dependents grouping='children'> + <range name='disk' min='0' max='0'> + <enum-method name='disk' version='1' /> + </range> + </dependents> + </range> +</topology> +EOF diff --git a/usr/src/lib/print/libipp-listener/Makefile b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Makefile index b92d620b10..072ea71be7 100644 --- a/usr/src/lib/print/libipp-listener/Makefile +++ b/usr/src/lib/fm/topo/maps/Joyent,Joyent-Compute-Platform-1101/Makefile @@ -18,39 +18,24 @@ # # CDDL HEADER END # + # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) - -install_h: # $(ROOTHDRS) -check: # $(CHECKHDRS) +# NOTE: The name of the xml file we are building is 'platform' +# specific, but its build is structured as 'arch' specific since +# 'uname -i' on all x86 platforms returns i86pc. -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) +ARCH = i86pc +CLASS = arch +DTDFILE = topology.dtd.1 +TOPOFILE = Joyent-Compute-Platform-1101-disk-hc-topology.xml +SRCDIR = ../Joyent,Joyent-Compute-Platform-1101 -FRC: +PLATFORM = Joyent-Compute-Platform-1101 +TOPOBASE = ../i86pc/i86pc-hc-topology.xml -include ../../Makefile.targ +include ../Makefile.map diff --git a/usr/src/lib/fm/topo/maps/Makefile b/usr/src/lib/fm/topo/maps/Makefile index de6d9f5e0f..a01b016ebe 100644 --- a/usr/src/lib/fm/topo/maps/Makefile +++ b/usr/src/lib/fm/topo/maps/Makefile @@ -48,7 +48,8 @@ i386_SUBDIRS = i86pc \ SUNW,Netra-X4200-M2 \ SUNW,Sun-Fire-X4500 \ SUNW,Sun-Fire-X4540 \ - SUNW,Sun-Fire-X4600-M2 + SUNW,Sun-Fire-X4600-M2 \ + Joyent,Joyent-Compute-Platform-1101 SUBDIRS = $($(MACH)_SUBDIRS) diff --git a/usr/src/lib/fm/topo/maps/Makefile.map b/usr/src/lib/fm/topo/maps/Makefile.map index b72cd29d74..25577f6b26 100644 --- a/usr/src/lib/fm/topo/maps/Makefile.map +++ b/usr/src/lib/fm/topo/maps/Makefile.map @@ -22,12 +22,12 @@ # # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" .KEEP_STATE: .SUFFIXES: -.SUFFIXES: .xml .xmlgen $(SUFFIXES) +.SUFFIXES: .xml .xmlgen .xmlgenksh $(SUFFIXES) MODCLASS = maps @@ -54,6 +54,11 @@ install:= FILEMODE = 0444 $(RM) $@ $(CAT) ../common/xmlgen-header.xml > $@ $(PERL) $< >> $@ + +.xmlgenksh.xml: + $(RM) $@ + $(CAT) ../common/xmlgen-header-new.xml > $@ + $(KSH93) $< >> $@ %.xml: ../common/%.xml $(RM) $@ diff --git a/usr/src/lib/fm/topo/maps/common/xmlgen-header-new.xml b/usr/src/lib/fm/topo/maps/common/xmlgen-header-new.xml new file mode 100644 index 0000000000..14cf1ff1e8 --- /dev/null +++ b/usr/src/lib/fm/topo/maps/common/xmlgen-header-new.xml @@ -0,0 +1,2 @@ +<?xml version="1.0"?> +<!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1"> diff --git a/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml b/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml index 54021a7a5f..237771ab4d 100644 --- a/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml +++ b/usr/src/lib/fm/topo/maps/i86pc/i86pc-legacy-hc-topology.xml @@ -2,6 +2,7 @@ <!DOCTYPE topology SYSTEM "/usr/share/lib/xml/dtd/topology.dtd.1"> <!-- Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2013, Joyent, Inc. All rights reserved. CDDL HEADER START @@ -151,6 +152,18 @@ Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. </range> </set> + <set type='product' setlist='Joyent-Compute-Platform-1101'> + <range name='psu' min='0' max='1'> + <enum-method name='ipmi' version='1' /> + </range> + <range name='fan' min='0' max='100'> + <enum-method name='ipmi' version='1' /> + </range> + <range name='bay' min='0' max='15'> + <propmap name='Joyent-Compute-Platform-1101-disk' /> + </range> + </set> + <set type='product' setlist='default'> <range name='psu' min='0' max='100'> <enum-method name='ipmi' version='1' /> diff --git a/usr/src/lib/fm/topo/modules/common/Makefile b/usr/src/lib/fm/topo/modules/common/Makefile index 0b0f965a70..fa38496755 100644 --- a/usr/src/lib/fm/topo/modules/common/Makefile +++ b/usr/src/lib/fm/topo/modules/common/Makefile @@ -23,11 +23,11 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#pragma ident "%Z%%M% %I% %E% SMI" SUBDIRS = \ disk \ fac_prov_ipmi \ + fac_prov_mptsas \ ipmi \ ses \ xfp diff --git a/usr/src/lib/fm/topo/modules/common/disk/Makefile b/usr/src/lib/fm/topo/modules/common/disk/Makefile index b4821a6a82..4b4c965050 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/Makefile +++ b/usr/src/lib/fm/topo/modules/common/disk/Makefile @@ -22,14 +22,15 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#pragma ident "%Z%%M% %I% %E% SMI" MODULE = disk CLASS = common -MODULESRCS = disk.c disk_common.c +MODULESRCS = disk.c disk_common.c disk_mptsas.c include ../../Makefile.plugin +CPPFLAGS += -I$(SRC)/uts/common + LDLIBS += -ldevinfo -ldevid -lcfgadm -ldiskstatus diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk.c b/usr/src/lib/fm/topo/modules/common/disk/disk.c index 427402c934..ec53198906 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk.c +++ b/usr/src/lib/fm/topo/modules/common/disk/disk.c @@ -21,6 +21,9 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <strings.h> #include <devid.h> @@ -33,6 +36,7 @@ #include <fm/libdiskstatus.h> #include <sys/fm/protocol.h> #include "disk.h" +#include "disk_drivers.h" static int disk_enum(topo_mod_t *, tnode_t *, const char *, topo_instance_t, topo_instance_t, void *, void *); @@ -43,13 +47,38 @@ static const topo_modops_t disk_ops = static const topo_modinfo_t disk_info = {DISK, FM_FMRI_SCHEME_HC, DISK_VERSION, &disk_ops}; +static int +disk_declare_driver(topo_mod_t *mod, tnode_t *baynode, topo_list_t *dlistp, + char *driver) +{ + int err; + + if (strcmp("mpt_sas", driver) == 0) { + char *sas_address = NULL; + tnode_t *child = NULL; + + if ((err = disk_mptsas_find_disk(mod, baynode, + &sas_address)) != 0) + return (err); + + err = disk_declare_addr(mod, baynode, dlistp, + sas_address, &child); + topo_mod_strfree(mod, sas_address); + + return (err); + } + + topo_mod_dprintf(mod, "unknown disk driver '%s'\n", driver); + return (-1); +} + /*ARGSUSED*/ static int disk_enum(topo_mod_t *mod, tnode_t *baynode, const char *name, topo_instance_t min, topo_instance_t max, void *arg, void *notused) { - char *device; + char *device, *driver; int err; nvlist_t *fmri; topo_list_t *dlistp = topo_mod_getspecific(mod); @@ -75,6 +104,22 @@ disk_enum(topo_mod_t *mod, tnode_t *baynode, nvlist_free(fmri); /* + * For internal storage, first check to see if we need to + * request more detail from an HBA driver. + */ + if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, + TOPO_BINDING_DRIVER, &driver, &err) == 0) { + err = disk_declare_driver(mod, baynode, dlistp, driver); + + topo_mod_strfree(mod, driver); + return (err); + } else if (err != ETOPO_PROP_NOENT) { + topo_mod_dprintf(mod, "disk_enum: " + "binding error %s\n", topo_strerror(err)); + return (-1); + } + + /* * For internal storage, get the path to the occupant from the * binding group of the bay node */ diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk.h b/usr/src/lib/fm/topo/modules/common/disk/disk.h index 3fabc4c334..e61a54974b 100644 --- a/usr/src/lib/fm/topo/modules/common/disk/disk.h +++ b/usr/src/lib/fm/topo/modules/common/disk/disk.h @@ -22,6 +22,9 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #ifndef _DISK_H #define _DISK_H @@ -54,6 +57,15 @@ extern "C" { */ #define TOPO_PGROUP_BINDING "binding" #define TOPO_BINDING_OCCUPANT "occupant-path" +#define TOPO_BINDING_DRIVER "driver" + +/* + * The binding group required in platform specific xml that describes 'bay' + * nodes containing disks attached to an HBA using the 'mpt_sas' driver. + */ +#define TOPO_BINDING_DEVCTL "devctl" +#define TOPO_BINDING_ENCLOSURE "enclosure" +#define TOPO_BINDING_SLOT "slot" /* * device node information. diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk_drivers.h b/usr/src/lib/fm/topo/modules/common/disk/disk_drivers.h new file mode 100644 index 0000000000..6851e2fe27 --- /dev/null +++ b/usr/src/lib/fm/topo/modules/common/disk/disk_drivers.h @@ -0,0 +1,31 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + +#ifndef _DISK_DRIVERS_H +#define _DISK_DRIVERS_H + +#include <fm/topo_mod.h> +#include <libdevinfo.h> + +#ifdef __cplusplus +extern "C" { +#endif + +int disk_mptsas_find_disk(topo_mod_t *, tnode_t *, char **); + +#ifdef __cplusplus +} +#endif + +#endif /* _DISK_DRIVERS_H */ diff --git a/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c b/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c new file mode 100644 index 0000000000..db853c6695 --- /dev/null +++ b/usr/src/lib/fm/topo/modules/common/disk/disk_mptsas.c @@ -0,0 +1,120 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stropts.h> +#include <string.h> +#include <strings.h> + +#include <fm/topo_mod.h> +#include <fm/topo_list.h> + +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_type.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2.h> +#include <sys/scsi/adapters/mpt_sas/mpi/mpi2_init.h> +#include <sys/scsi/adapters/mpt_sas/mptsas_ioctl.h> + +#include "disk.h" +#include "disk_drivers.h" + +static int +get_sas_address(topo_mod_t *mod, char *devctl, uint32_t enclosure, + uint32_t slot, char **sas_address) +{ + int fd, err, i; + mptsas_get_disk_info_t gdi; + mptsas_disk_info_t *di; + size_t disz; + + bzero(&gdi, sizeof (gdi)); + + if ((fd = open(devctl, O_RDWR)) == -1) { + topo_mod_dprintf(mod, "could not open '%s' for ioctl: %s\n", + devctl, strerror(errno)); + return (-1); + } + + if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) { + topo_mod_dprintf(mod, "ioctl 1 on '%s' failed: %s\n", devctl, + strerror(errno)); + (void) close(fd); + return (-1); + } + + gdi.DiskInfoArraySize = disz = sizeof (mptsas_disk_info_t) * + gdi.DiskCount; + gdi.PtrDiskInfoArray = di = topo_mod_alloc(mod, disz); + if (di == NULL) { + topo_mod_dprintf(mod, "memory allocation failed\n"); + (void) close(fd); + return (-1); + } + + if (ioctl(fd, MPTIOCTL_GET_DISK_INFO, &gdi) == -1) { + topo_mod_dprintf(mod, "ioctl 2 on '%s' failed: %s\n", devctl, + strerror(errno)); + topo_mod_free(mod, di, disz); + (void) close(fd); + return (-1); + } + + err = -1; + for (i = 0; i < gdi.DiskCount; i++) { + if (di[i].Enclosure == enclosure && di[i].Slot == slot) { + char sas[17]; /* 16 hex digits and NUL */ + (void) snprintf(sas, 17, "%llx", di[i].SasAddress); + topo_mod_dprintf(mod, "found mpt_sas disk (%d/%d) " + "with adddress %s\n", enclosure, slot, sas); + *sas_address = topo_mod_strdup(mod, sas); + err = 0; + break; + } + } + + topo_mod_free(mod, di, disz); + (void) close(fd); + return (err); +} + +int +disk_mptsas_find_disk(topo_mod_t *mod, tnode_t *baynode, char **sas_address) +{ + char *devctl = NULL; + uint32_t enclosure, slot; + int err; + + /* + * Get the required properties from the node. These come from + * the static XML mapping. + */ + if (topo_prop_get_string(baynode, TOPO_PGROUP_BINDING, + TOPO_BINDING_DEVCTL, &devctl, &err) != 0 || + topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING, + TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 || + topo_prop_get_uint32(baynode, TOPO_PGROUP_BINDING, + TOPO_BINDING_SLOT, &slot, &err) != 0) { + if (devctl != NULL) + topo_mod_strfree(mod, devctl); + topo_mod_dprintf(mod, "bay node was missing mpt_sas binding " + "properties\n"); + return (-1); + } + + return (get_sas_address(mod, devctl, enclosure, slot, sas_address)); + +} diff --git a/usr/src/lib/print/libhttp-core/i386/Makefile b/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/Makefile index 0bc3313291..31838e1bc0 100644 --- a/usr/src/lib/print/libhttp-core/i386/Makefile +++ b/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/Makefile @@ -19,12 +19,16 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. # -# ident "%Z%%M% %I% %E% SMI" -# -include ../Makefile.com +MODULE = fac_prov_mptsas +CLASS = common + +MODULESRCS = fac_prov_mptsas.c + +include ../../Makefile.plugin -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) +CPPFLAGS += -I$(SRC)/uts/common diff --git a/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c b/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c new file mode 100644 index 0000000000..a49a131811 --- /dev/null +++ b/usr/src/lib/fm/topo/modules/common/fac_prov_mptsas/fac_prov_mptsas.c @@ -0,0 +1,244 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <fcntl.h> +#include <string.h> +#include <strings.h> +#include <limits.h> +#include <alloca.h> +#include <errno.h> +#include <libnvpair.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <sys/fm/protocol.h> +#include <fm/libtopo.h> +#include <fm/topo_mod.h> + +#include "sys/scsi/adapters/mpt_sas/mptsas_ioctl.h" + +#define TOPO_METH_MPTSAS_LED_MODE_VERSION 0 + +static int fac_prov_mptsas_enum(topo_mod_t *, tnode_t *, const char *, + topo_instance_t, topo_instance_t, void *, void *); + +/* + * mpt_sas facility provider methods + */ +static int mptsas_led_mode(topo_mod_t *, tnode_t *, topo_version_t, + nvlist_t *, nvlist_t **); + +const topo_modops_t mptsas_ops = { fac_prov_mptsas_enum, NULL }; + +const topo_modinfo_t mptsas_info = + { "mpt_sas facility provider", FM_FMRI_SCHEME_HC, TOPO_VERSION, + &mptsas_ops }; + +static const topo_method_t mptsas_fac_methods[] = { + { "mptsas_led_mode", TOPO_PROP_METH_DESC, + TOPO_METH_MPTSAS_LED_MODE_VERSION, + TOPO_STABILITY_INTERNAL, mptsas_led_mode }, + { NULL } +}; + +/*ARGSUSED*/ +int +_topo_init(topo_mod_t *mod, topo_version_t version) +{ + if (getenv("TOPOFACMPTSASDEBUG") != NULL) + topo_mod_setdebug(mod); + + return (topo_mod_register(mod, &mptsas_info, TOPO_VERSION)); +} + +void +_topo_fini(topo_mod_t *mod) +{ + topo_mod_unregister(mod); +} + +static int +do_led_control(topo_mod_t *mod, char *devctl, uint16_t enclosure, + uint16_t slot, uint8_t led, uint32_t *ledmode, boolean_t set) +{ + int fd; + mptsas_led_control_t lc; + + bzero(&lc, sizeof (lc)); + + lc.Command = set ? MPTSAS_LEDCTL_FLAG_SET : MPTSAS_LEDCTL_FLAG_GET; + lc.Enclosure = enclosure; + lc.Slot = slot; + lc.Led = led; + lc.LedStatus = *ledmode; + + if ((fd = open(devctl, (set ? O_RDWR : O_RDONLY))) == -1) { + topo_mod_dprintf(mod, "devctl open failed: %s", + strerror(errno)); + return (-1); + } + + if (ioctl(fd, MPTIOCTL_LED_CONTROL, &lc) == -1) { + if (errno == ENOENT) { + /* + * If there is not presently a target attached for + * a particular enclosure/slot pair then the driver + * does not track LED status for this bay. Assume + * all LEDs are off. + */ + lc.LedStatus = 0; + } else { + topo_mod_dprintf(mod, "led control ioctl failed: %s", + strerror(errno)); + (void) close(fd); + return (-1); + } + } + + *ledmode = lc.LedStatus ? TOPO_LED_STATE_ON : TOPO_LED_STATE_OFF; + + (void) close(fd); + return (0); +} + +static int +mptsas_led_mode(topo_mod_t *mod, tnode_t *node, topo_version_t vers, + nvlist_t *in, nvlist_t **nvout) +{ + int err, ret = 0; + tnode_t *pnode = topo_node_parent(node); + uint32_t type, ledmode = 0; + nvlist_t *pargs, *nvl; + char *driver = NULL, *devctl = NULL; + uint32_t enclosure, slot; + uint8_t mptsas_led; + boolean_t set; + + if (vers > TOPO_METH_MPTSAS_LED_MODE_VERSION) + return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); + + if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING, + TOPO_BINDING_DRIVER, &driver, &err) != 0 || + strcmp("mpt_sas", driver) != 0) { + topo_mod_dprintf(mod, "%s: Facility driver was not mpt_sas", + __func__); + ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); + goto out; + } + if (topo_prop_get_uint32(node, TOPO_PGROUP_FACILITY, TOPO_FACILITY_TYPE, + &type, &err) != 0) { + topo_mod_dprintf(mod, "%s: Failed to lookup %s property " + "(%s)", __func__, TOPO_FACILITY_TYPE, topo_strerror(err)); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } + switch (type) { + case (TOPO_LED_TYPE_SERVICE): + mptsas_led = MPTSAS_LEDCTL_LED_FAIL; + break; + case (TOPO_LED_TYPE_LOCATE): + mptsas_led = MPTSAS_LEDCTL_LED_IDENT; + break; + case (TOPO_LED_TYPE_OK2RM): + mptsas_led = MPTSAS_LEDCTL_LED_OK2RM; + break; + default: + topo_mod_dprintf(mod, "%s: Invalid LED type: 0x%x\n", __func__, + type); + return (topo_mod_seterrno(mod, EMOD_NVL_INVAL)); + } + if (topo_prop_get_string(pnode, TOPO_PGROUP_BINDING, + TOPO_BINDING_DEVCTL, &devctl, &err) != 0 || + topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING, + TOPO_BINDING_ENCLOSURE, &enclosure, &err) != 0 || + topo_prop_get_uint32(pnode, TOPO_PGROUP_BINDING, + TOPO_BINDING_SLOT, &slot, &err) != 0) { + topo_mod_dprintf(mod, "%s: Facility was missing mpt_sas binding" + " properties\n", __func__); + ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); + goto out; + } + + if ((nvlist_lookup_nvlist(in, TOPO_PROP_PARGS, &pargs) == 0) && + nvlist_exists(pargs, TOPO_PROP_VAL_VAL)) { + /* + * Set the LED mode + */ + set = B_TRUE; + if ((ret = nvlist_lookup_uint32(pargs, TOPO_PROP_VAL_VAL, + &ledmode)) != 0) { + topo_mod_dprintf(mod, "%s: Failed to lookup %s nvpair " + "(%s)\n", __func__, TOPO_PROP_VAL_VAL, + strerror(ret)); + ret = topo_mod_seterrno(mod, EMOD_NVL_INVAL); + goto out; + } + topo_mod_dprintf(mod, "%s: Setting LED mode to %s\n", __func__, + ledmode ? "ON" : "OFF"); + } else { + /* + * Get the LED mode + */ + set = B_FALSE; + topo_mod_dprintf(mod, "%s: Getting LED mode\n", __func__); + } + + if (do_led_control(mod, devctl, enclosure, slot, mptsas_led, &ledmode, + set) != 0) { + topo_mod_dprintf(mod, "%s: do_led_control failed", __func__); + ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); + goto out; + } + + if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0 || + nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_LED_MODE) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_UINT32) != 0 || + nvlist_add_uint32(nvl, TOPO_PROP_VAL_VAL, ledmode) != 0) { + topo_mod_dprintf(mod, "%s: Failed to allocate 'out' nvlist\n", + __func__); + nvlist_free(nvl); + ret = topo_mod_seterrno(mod, EMOD_NOMEM); + goto out; + } + *nvout = nvl; + +out: + if (driver != NULL) + topo_mod_strfree(mod, driver); + if (devctl != NULL) + topo_mod_strfree(mod, devctl); + return (ret); +} + +/*ARGSUSED*/ +static int +fac_prov_mptsas_enum(topo_mod_t *mod, tnode_t *rnode, const char *name, + topo_instance_t min, topo_instance_t max, void *arg, void *unused) +{ + if (topo_node_flags(rnode) == TOPO_NODE_FACILITY) { + if (topo_method_register(mod, rnode, mptsas_fac_methods) != 0) { + topo_mod_dprintf(mod, "%s: topo_method_register() " + "failed: %s", __func__, topo_mod_errmsg(mod)); + return (-1); + } + return (0); + } + + topo_mod_dprintf(mod, "%s: unexpected node flags %x", __func__, + topo_node_flags(rnode)); + return (-1); +} diff --git a/usr/src/lib/libbe/common/be_list.c b/usr/src/lib/libbe/common/be_list.c index b9c7882d18..e669f24cc8 100644 --- a/usr/src/lib/libbe/common/be_list.c +++ b/usr/src/lib/libbe/common/be_list.c @@ -25,6 +25,7 @@ /* * Copyright 2011 Nexenta Systems, Inc. All rights reserved. + * Copyright 2011 Joyent, Inc. All rights reserved. */ #include <assert.h> @@ -872,7 +873,7 @@ be_get_node_data( } (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf, ZFS_MAXPROPLEN, - NULL); + NULL, B_FALSE); if (be_has_grub() && (be_default_grub_bootfs(rpool, &grub_default_bootfs) == BE_SUCCESS) && grub_default_bootfs != NULL) diff --git a/usr/src/lib/libbrand/Makefile.com b/usr/src/lib/libbrand/Makefile.com index cd7d83371a..0fceb70aac 100644 --- a/usr/src/lib/libbrand/Makefile.com +++ b/usr/src/lib/libbrand/Makefile.com @@ -34,7 +34,7 @@ include ../../Makefile.lib LIBS= $(DYNLIB) $(LINTLIB) LDLIBS += -lc $(LINTLIB) := SRCS= $(SRCDIR)/$(LINTSRC) -CPPFLAGS += -I/usr/include/libxml2 -I$(SRCDIR) -D_REENTRANT +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I$(SRCDIR) -D_REENTRANT $(DYNLIB) := LDLIBS += -lxml2 SRCDIR= ../common diff --git a/usr/src/lib/libbrand/common/libbrand.c b/usr/src/lib/libbrand/common/libbrand.c index 5034715a7e..baaaf33120 100644 --- a/usr/src/lib/libbrand/common/libbrand.c +++ b/usr/src/lib/libbrand/common/libbrand.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #include <assert.h> @@ -60,6 +61,7 @@ #define DTD_ELEM_FORCELOGIN_CMD ((const xmlChar *) "forcedlogin_cmd") #define DTD_ELEM_MODNAME ((const xmlChar *) "modname") #define DTD_ELEM_MOUNT ((const xmlChar *) "mount") +#define DTD_ELEM_RESTARTINIT ((const xmlChar *) "restartinit") #define DTD_ELEM_POSTATTACH ((const xmlChar *) "postattach") #define DTD_ELEM_POSTCLONE ((const xmlChar *) "postclone") #define DTD_ELEM_POSTINSTALL ((const xmlChar *) "postinstall") @@ -319,6 +321,7 @@ i_substitute_tokens(const char *sbuf, char *dbuf, int dbuf_size, const char *curr_zone) { int dst, src; + static char *env_pool = NULL; /* * Walk through the characters, substituting values as needed. @@ -335,6 +338,13 @@ i_substitute_tokens(const char *sbuf, char *dbuf, int dbuf_size, case '%': dst += strlcpy(dbuf + dst, "%", dbuf_size - dst); break; + case 'P': + if (env_pool == NULL) + env_pool = getenv("_ZONEADMD_ZPOOL"); + if (env_pool == NULL) + break; + dst += strlcpy(dbuf + dst, env_pool, dbuf_size - dst); + break; case 'R': if (zonepath == NULL) break; @@ -509,6 +519,21 @@ brand_get_initname(brand_handle_t bh, char *buf, size_t len) buf, len, DTD_ELEM_INITNAME, B_FALSE, B_FALSE)); } +boolean_t +brand_restartinit(brand_handle_t bh) +{ + struct brand_handle *bhp = (struct brand_handle *)bh; + char val[80]; + + if (brand_get_value(bhp, NULL, NULL, NULL, NULL, + val, 80, DTD_ELEM_RESTARTINIT, B_FALSE, B_FALSE) != 0) + return (B_TRUE); + + if (strcmp(val, "false") == 0) + return (B_FALSE); + return (B_TRUE); +} + int brand_get_login_cmd(brand_handle_t bh, const char *username, char *buf, size_t len) diff --git a/usr/src/lib/libbrand/common/libbrand.h b/usr/src/lib/libbrand/common/libbrand.h index 19231604a5..1ca9e9f36d 100644 --- a/usr/src/lib/libbrand/common/libbrand.h +++ b/usr/src/lib/libbrand/common/libbrand.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #ifndef _LIBBRAND_H @@ -57,6 +58,7 @@ extern int brand_get_detach(brand_handle_t, const char *, const char *, extern int brand_get_halt(brand_handle_t, const char *, const char *, char *, size_t); extern int brand_get_initname(brand_handle_t, char *, size_t); +extern boolean_t brand_restartinit(brand_handle_t); extern int brand_get_install(brand_handle_t, const char *, const char *, char *, size_t); extern int brand_get_installopts(brand_handle_t, char *, size_t); diff --git a/usr/src/lib/libbrand/common/mapfile-vers b/usr/src/lib/libbrand/common/mapfile-vers index 7b961c3c18..9bf21d2d26 100644 --- a/usr/src/lib/libbrand/common/mapfile-vers +++ b/usr/src/lib/libbrand/common/mapfile-vers @@ -20,6 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, Joyent, Inc. All rights reserved. # # @@ -76,6 +77,7 @@ SYMBOL_VERSION SUNWprivate { brand_platform_iter_gmounts; brand_platform_iter_link; brand_platform_iter_mounts; + brand_restartinit; local: *; }; diff --git a/usr/src/lib/libbrand/dtd/brand.dtd.1 b/usr/src/lib/libbrand/dtd/brand.dtd.1 index 15542102db..89719a6ae6 100644 --- a/usr/src/lib/libbrand/dtd/brand.dtd.1 +++ b/usr/src/lib/libbrand/dtd/brand.dtd.1 @@ -21,6 +21,7 @@ CDDL HEADER END Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, Joyent, Inc. All rights reserved. DO NOT EDIT THIS FILE. --> @@ -188,6 +189,19 @@ <!ATTLIST initname> <!-- + restartinit + + Boolean indicating that the program specified by the initname attr + should be restarted, or not, if it exits. By default, the init program + will be restarted if this attribute is not provided. Specifying false + for this attr will prevent that. + + It has no attributes. +--> +<!ELEMENT restartinit (#PCDATA) > +<!ATTLIST restartinit> + +<!-- login_cmd Path to the initial login binary that should be executed when @@ -605,8 +619,8 @@ directory in which the configuration file is stored. --> -<!ELEMENT brand (modname?, initname, login_cmd, forcedlogin_cmd, - user_cmd, install, +<!ELEMENT brand (modname?, initname, restartinit?, login_cmd, + forcedlogin_cmd, user_cmd, install, installopts?, boot?, sysboot?, halt?, verify_cfg?, verify_adm?, postattach?, postclone?, postinstall?, predetach?, attach?, detach?, clone?, diff --git a/usr/src/lib/libbsm/common/adt.c b/usr/src/lib/libbsm/common/adt.c index 8c7b299e32..4cf0dd7566 100644 --- a/usr/src/lib/libbsm/common/adt.c +++ b/usr/src/lib/libbsm/common/adt.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013, Joyent, Inc. All rights reserved. */ #include <bsm/adt.h> @@ -702,7 +703,37 @@ adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term) int tries = 3; char msg[512]; int eai_err; + struct ifaddrlist al; + int family; + boolean_t found = B_FALSE; + /* + * getaddrinfo can take a long time to timeout if it can't map the + * hostname to an IP address so try to get an IP address from a local + * interface first. + */ + family = AF_INET6; + if (adt_get_local_address(family, &al) == 0) { + found = B_TRUE; + } else { + family = AF_INET; + if (adt_get_local_address(family, &al) == 0) + found = B_TRUE; + } + + if (found) { + if (family == AF_INET) { + p_term->at_type = AU_IPv4; + (void) memcpy(p_term->at_addr, &al.addr.addr, AU_IPv4); + } else { + p_term->at_type = AU_IPv6; + (void) memcpy(p_term->at_addr, &al.addr.addr6, AU_IPv6); + } + + return (0); + } + + /* Now try getaddrinfo */ while ((tries-- > 0) && ((eai_err = getaddrinfo(hostname, NULL, NULL, &ai)) != 0)) { /* @@ -739,7 +770,9 @@ adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term) } freeaddrinfo(ai); return (0); - } else if (auditstate & (AUC_AUDITING | AUC_NOSPACE)) { + } + + if (auditstate & (AUC_AUDITING | AUC_NOSPACE)) { auditinfo_addr_t audit_info; /* @@ -747,58 +780,23 @@ adt_get_hostIP(const char *hostname, au_tid_addr_t *p_term) * kernel audit context */ if (auditon(A_GETKAUDIT, (caddr_t)&audit_info, - sizeof (audit_info)) < 0) { - adt_write_syslog("unable to get kernel audit context", - errno); - goto try_interface; + sizeof (audit_info)) >= 0) { + adt_write_syslog("setting Audit IP address to kernel", + 0); + *p_term = audit_info.ai_termid; + return (0); } - adt_write_syslog("setting Audit IP address to kernel", 0); - *p_term = audit_info.ai_termid; - return (0); + adt_write_syslog("unable to get kernel audit context", errno); } -try_interface: - { - struct ifaddrlist al; - int family; - char ntop[INET6_ADDRSTRLEN]; - - /* - * getaddrinfo has failed to map the hostname - * to an IP address, try to get an IP address - * from a local interface. If none up, default - * to loopback. - */ - family = AF_INET6; - if (adt_get_local_address(family, &al) != 0) { - family = AF_INET; - - if (adt_get_local_address(family, &al) != 0) { - adt_write_syslog("adt_get_local_address " - "failed, no Audit IP address available, " - "faking loopback and error", - errno); - IN_SET_LOOPBACK_ADDR( - (struct sockaddr_in *)&(al.addr.addr)); - (void) memcpy(p_term->at_addr, &al.addr.addr, - AU_IPv4); - p_term->at_type = AU_IPv4; - return (-1); - } - } - if (family == AF_INET) { - p_term->at_type = AU_IPv4; - (void) memcpy(p_term->at_addr, &al.addr.addr, AU_IPv4); - } else { - p_term->at_type = AU_IPv6; - (void) memcpy(p_term->at_addr, &al.addr.addr6, AU_IPv6); - } - (void) snprintf(msg, sizeof (msg), "mapping %s to %s", - hostname, inet_ntop(family, &(al.addr), ntop, - sizeof (ntop))); - adt_write_syslog(msg, 0); - return (0); - } + /* No mapping, default to loopback. */ + errno = ENETDOWN; + adt_write_syslog("adt_get_local_address failed, no Audit IP address " + "available, faking loopback and error", errno); + IN_SET_LOOPBACK_ADDR((struct sockaddr_in *)&(al.addr.addr)); + (void) memcpy(p_term->at_addr, &al.addr.addr, AU_IPv4); + p_term->at_type = AU_IPv4; + return (-1); } /* @@ -2093,8 +2091,8 @@ adt_selected(struct adt_event_state *event, au_event_t actual_id, int status) } /* - * Can't map the host name to an IP address in - * adt_get_hostIP. Get something off an interface + * Before trying to map the host name to an IP address in + * adt_get_hostIP, get something off an interface * to act as the hosts IP address for auditing. */ diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index eba3088869..2f37212a55 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -20,6 +20,7 @@ # # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Use is subject to license terms. @@ -796,6 +797,7 @@ THREADSOBJS= \ assfail.o \ cancel.o \ door_calls.o \ + tmem.o \ pthr_attr.o \ pthr_barrier.o \ pthr_cond.o \ diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 758b75a2dc..41721e4f3f 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -20,6 +20,7 @@ # # # Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Use is subject to license terms. @@ -838,6 +839,7 @@ THREADSOBJS= \ assfail.o \ cancel.o \ door_calls.o \ + tmem.o \ pthr_attr.o \ pthr_barrier.o \ pthr_cond.o \ diff --git a/usr/src/lib/libc/inc/thr_inlines.h b/usr/src/lib/libc/inc/thr_inlines.h index f7cdc6a6bd..66d811f25b 100644 --- a/usr/src/lib/libc/inc/thr_inlines.h +++ b/usr/src/lib/libc/inc/thr_inlines.h @@ -47,17 +47,19 @@ extern __GNU_INLINE ulwp_t * _curthread(void) { -#if defined(__amd64) ulwp_t *__value; - __asm__ __volatile__("movq %%fs:0, %0" : "=r" (__value)); + __asm__ __volatile__( +#if defined(__amd64) + "movq %%fs:0, %0\n\t" #elif defined(__i386) - ulwp_t *__value; - __asm__ __volatile__("movl %%gs:0, %0" : "=r" (__value)); + "movl %%gs:0, %0\n\t" #elif defined(__sparc) - register ulwp_t *__value __asm__("g7"); + ".register %%g7, #scratch\n\t" + "mov %%g7, %0\n\t" #else #error "port me" #endif + : "=r" (__value)); return (__value); } diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index af3083138d..2b8d000b29 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -22,6 +22,9 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ #ifndef _THR_UBERDATA_H #define _THR_UBERDATA_H @@ -488,6 +491,28 @@ typedef struct { #endif /* _SYSCALL32 */ /* + * As part of per-thread caching libumem (ptcumem), we add a small amount to the + * thread's uberdata to facilitate it. The tm_roots are the roots of linked + * lists which is used by libumem to chain together allocations. tm_size is used + * to track the total amount of data stored across those linked lists. + */ +#define NTMEMBASE 16 + +typedef struct { + size_t tm_size; + void *tm_roots[NTMEMBASE]; +} tumem_t; + +#ifdef _SYSCALL32 +typedef struct { + uint32_t tm_size; + caddr32_t tm_roots[NTMEMBASE]; +} tumem32_t; +#endif + +typedef void (*tmem_func_t)(void *, int); + +/* * Maximum number of read locks allowed for one thread on one rwlock. * This could be as large as INT_MAX, but the SUSV3 test suite would * take an inordinately long time to complete. This is big enough. @@ -653,6 +678,7 @@ typedef struct ulwp { #if defined(sparc) void *ul_unwind_ret; /* used only by _ex_clnup_handler() */ #endif + tumem_t ul_tmem; /* used only by umem */ } ulwp_t; #define ul_cursig ul_cp.s.cursig /* deferred signal number */ @@ -1074,6 +1100,7 @@ typedef struct ulwp32 { #if defined(sparc) caddr32_t ul_unwind_ret; /* used only by _ex_clnup_handler() */ #endif + tumem32_t ul_tmem; /* used only by umem */ } ulwp32_t; #define REPLACEMENT_SIZE32 ((size_t)&((ulwp32_t *)NULL)->ul_sigmask) @@ -1196,6 +1223,7 @@ extern ulwp_t *find_lwp(thread_t); extern void finish_init(void); extern void update_sched(ulwp_t *); extern void queue_alloc(void); +extern void tmem_exit(void); extern void tsd_exit(void); extern void tsd_free(ulwp_t *); extern void tls_setup(void); diff --git a/usr/src/lib/libc/port/gen/getlogin.c b/usr/src/lib/libc/port/gen/getlogin.c index a3d7b4cf3b..e96d294fd0 100644 --- a/usr/src/lib/libc/port/gen/getlogin.c +++ b/usr/src/lib/libc/port/gen/getlogin.c @@ -27,7 +27,9 @@ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2013 Joyent, Inc. All rights reserved. + */ #pragma weak _getlogin = getlogin #pragma weak _getlogin_r = getlogin_r @@ -35,6 +37,7 @@ #include "lint.h" #include <sys/types.h> #include <sys/stat.h> +#include <sys/sysmacros.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> @@ -51,40 +54,55 @@ * XXX - _POSIX_LOGIN_NAME_MAX limits the length of a login name. The utmpx * interface provides for a 32 character login name, but for the sake of * compatibility, we are still using the old utmp-imposed limit. + * + * If you want the full name, use the Consolidation Private getxlogin(). */ -/* - * POSIX.1c Draft-6 version of the function getlogin_r. - * It was implemented by Solaris 2.3. - */ -char * -getlogin_r(char *answer, int namelen) +static int +generic_getlogin(char *answer, int namelen, boolean_t truncate) { int uf; off64_t me; struct futmpx ubuf; - if (namelen < _POSIX_LOGIN_NAME_MAX) { - errno = ERANGE; - return (NULL); - } - if ((me = (off64_t)ttyslot()) < 0) - return (NULL); + return (-1); if ((uf = open64(UTMPX_FILE, 0)) < 0) - return (NULL); + return (-1); (void) lseek64(uf, me * sizeof (ubuf), SEEK_SET); if (read(uf, &ubuf, sizeof (ubuf)) != sizeof (ubuf)) { (void) close(uf); - return (NULL); + return (-1); } (void) close(uf); if (ubuf.ut_user[0] == '\0') + return (-1); + if (strnlen(ubuf.ut_user, sizeof (ubuf.ut_user)) >= namelen && + !truncate) { + errno = ERANGE; + return (-1); + } + (void) strlcpy(answer, ubuf.ut_user, namelen); + + return (0); +} + +/* + * POSIX.1c Draft-6 version of the function getlogin_r. + * It was implemented by Solaris 2.3. + */ +char * +getlogin_r(char *answer, int namelen) +{ + if (namelen < _POSIX_LOGIN_NAME_MAX) { + errno = ERANGE; return (NULL); - (void) strncpy(&answer[0], &ubuf.ut_user[0], - _POSIX_LOGIN_NAME_MAX - 1); - answer[_POSIX_LOGIN_NAME_MAX - 1] = '\0'; - return (&answer[0]); + } + + if (generic_getlogin(answer, _POSIX_LOGIN_NAME_MAX, B_TRUE) == 0) + return (answer); + + return (NULL); } /* @@ -98,7 +116,7 @@ __posix_getlogin_r(char *name, int namelen) int oerrno = errno; errno = 0; - if (getlogin_r(name, namelen) == NULL) { + if (getlogin_r(name, namelen) != 0) { if (errno == 0) nerrno = EINVAL; else @@ -111,9 +129,28 @@ __posix_getlogin_r(char *name, int namelen) char * getlogin(void) { - char *answer = tsdalloc(_T_LOGIN, _POSIX_LOGIN_NAME_MAX, NULL); + struct futmpx fu; + char *answer = tsdalloc(_T_LOGIN, + MAX(sizeof (fu.ut_user), _POSIX_LOGIN_NAME_MAX), NULL); if (answer == NULL) return (NULL); return (getlogin_r(answer, _POSIX_LOGIN_NAME_MAX)); } + +char * +getxlogin(void) +{ + struct futmpx fu; + char *answer = tsdalloc(_T_LOGIN, + MAX(sizeof (fu.ut_user), _POSIX_LOGIN_NAME_MAX), NULL); + + if (answer == NULL) + return (NULL); + + if (generic_getlogin(answer, + MAX(sizeof (fu.ut_user), _POSIX_LOGIN_NAME_MAX), B_FALSE) != 0) + return (NULL); + + return (answer); +} diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 9dc147a35b..c5587adf3d 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -24,6 +24,7 @@ # Copyright 2010 Nexenta Systems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # Copyright (c) 2012 by Delphix. All rights reserved. # @@ -2724,6 +2725,7 @@ $endif getvmusage; __getwchar_xpg5; __getwc_xpg5; + getxlogin; gtty; __idmap_flush_kcache; __idmap_reg; @@ -2869,6 +2871,9 @@ $endif thr_wait_mutator; _thr_wait_mutator; __tls_get_addr; + _tmem_get_base; + _tmem_get_nentries; + _tmem_set_cleanup; tpool_create; tpool_dispatch; tpool_destroy; diff --git a/usr/src/lib/libc/port/sys/zone.c b/usr/src/lib/libc/port/sys/zone.c index 4a4c70043d..182a7f22f7 100644 --- a/usr/src/lib/libc/port/sys/zone.c +++ b/usr/src/lib/libc/port/sys/zone.c @@ -22,6 +22,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2011 Joyent Inc. All rights reserved. */ #include "lint.h" @@ -39,7 +40,8 @@ zoneid_t zone_create(const char *name, const char *root, const struct priv_set *privs, const char *rctls, size_t rctlsz, const char *zfs, size_t zfssz, - int *extended_error, int match, int doi, const bslabel_t *label, int flags) + int *extended_error, int match, int doi, const bslabel_t *label, int flags, + zoneid_t req_zoneid) { zone_def zd; priv_data_t *d; @@ -59,6 +61,7 @@ zone_create(const char *name, const char *root, const struct priv_set *privs, zd.doi = doi; zd.label = label; zd.flags = flags; + zd.zoneid = req_zoneid; return ((zoneid_t)syscall(SYS_zone, ZONE_CREATE, &zd)); } diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c index ae55fbddf5..b5d848449d 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -22,6 +22,9 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. */ +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ #include "lint.h" #include "thr_uberdata.h" @@ -771,6 +774,7 @@ _thrp_exit() } lmutex_unlock(&udp->link_lock); + tmem_exit(); /* deallocate tmem allocations */ tsd_exit(); /* deallocate thread-specific data */ tls_exit(); /* deallocate thread-local storage */ heldlock_exit(); /* deal with left-over held locks */ diff --git a/usr/src/lib/libc/port/threads/tmem.c b/usr/src/lib/libc/port/threads/tmem.c new file mode 100644 index 0000000000..00203de593 --- /dev/null +++ b/usr/src/lib/libc/port/threads/tmem.c @@ -0,0 +1,85 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + +#include "lint.h" +#include "thr_uberdata.h" + +/* + * This file implements the private interface with libumem for per-thread + * caching umem (ptcumem). For the full details on how tcumem works and how + * these functions work, see section 8.4 of the big theory statement in + * lib/libumem/common/umem.c. + */ +static tmem_func_t tmem_cleanup = NULL; + +uintptr_t +_tmem_get_base(void) +{ + return ((uintptr_t)&curthread->ul_tmem - (uintptr_t)curthread); +} + +int +_tmem_get_nentries(void) +{ + return (NTMEMBASE); +} + +void +_tmem_set_cleanup(tmem_func_t f) +{ + tmem_cleanup = f; +} + +/* + * This is called by _thrp_exit() to clean up any per-thread allocations that + * are still hanging around and haven't been cleaned up. + */ +void +tmem_exit(void) +{ + int ii; + void *buf, *next; + tumem_t *tp = &curthread->ul_tmem; + + + if (tp->tm_size == 0) + return; + + /* + * Since we have something stored here, we need to ensure we declared a + * clean up handler. If we haven't that's broken and our single private + * consumer should be shot. + */ + if (tmem_cleanup == NULL) + abort(); + for (ii = 0; ii < NTMEMBASE; ii++) { + buf = tp->tm_roots[ii]; + while (buf != NULL) { + next = *(void **)buf; + tmem_cleanup(buf, ii); + buf = next; + } + } +} diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com index 0edfd64067..8b27e58b92 100644 --- a/usr/src/lib/libc/sparc/Makefile.com +++ b/usr/src/lib/libc/sparc/Makefile.com @@ -20,6 +20,7 @@ # # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Use is subject to license terms. @@ -873,6 +874,7 @@ THREADSOBJS= \ assfail.o \ cancel.o \ door_calls.o \ + tmem.o \ pthr_attr.o \ pthr_barrier.o \ pthr_cond.o \ diff --git a/usr/src/lib/libc/sparc/crt/_rtld.c b/usr/src/lib/libc/sparc/crt/_rtld.c index a9e9c6d98a..843cfe03a5 100644 --- a/usr/src/lib/libc/sparc/crt/_rtld.c +++ b/usr/src/lib/libc/sparc/crt/_rtld.c @@ -62,6 +62,15 @@ #define SYSCONFIG (*(funcs[SYSCONFIG_F])) /* + * GCC will not emit unused static functions unless specifically told it must + */ +#ifdef __GNUC__ +#define __USED __attribute__((used)) +#else +#define __USED +#endif + +/* * Alias ld.so entry point -- receives a bootstrap structure and a vector * of strings. The vector is "well-known" to us, and consists of pointers * to string constants. This aliasing bootstrap requires no relocation in diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com index b00e69be99..fa727d133c 100644 --- a/usr/src/lib/libc/sparcv9/Makefile.com +++ b/usr/src/lib/libc/sparcv9/Makefile.com @@ -20,6 +20,7 @@ # # # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Use is subject to license terms. @@ -820,6 +821,7 @@ THREADSOBJS= \ assfail.o \ cancel.o \ door_calls.o \ + tmem.o \ pthr_attr.o \ pthr_barrier.o \ pthr_cond.o \ diff --git a/usr/src/lib/libctf/common/mapfile-vers b/usr/src/lib/libctf/common/mapfile-vers index c218edc37c..0873de319e 100644 --- a/usr/src/lib/libctf/common/mapfile-vers +++ b/usr/src/lib/libctf/common/mapfile-vers @@ -60,6 +60,7 @@ SYMBOL_VERSION SUNWprivate_1.2 { ctf_add_union; ctf_add_volatile; ctf_create; + ctf_delete_type; ctf_discard; ctf_enum_value; ctf_label_info; diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h index 0f782bc383..5e44ba437a 100644 --- a/usr/src/lib/libdiskmgt/common/disks_private.h +++ b/usr/src/lib/libdiskmgt/common/disks_private.h @@ -109,6 +109,7 @@ typedef struct disk { int rpm; int wide; int cd_rom; + int solid_state; } disk_t; typedef struct descriptor { diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c index 825348ce9f..f1b2d49961 100644 --- a/usr/src/lib/libdiskmgt/common/drive.c +++ b/usr/src/lib/libdiskmgt/common/drive.c @@ -350,6 +350,7 @@ static int get_io_kstats(kstat_ctl_t *kc, char *diskname, static int get_kstat_vals(kstat_t *ksp, nvlist_t *stats); static char *get_err_attr_name(char *kstat_name); static int get_rpm(disk_t *dp, int fd); +static int get_solidstate(disk_t *dp, int fd); static int update_stat64(nvlist_t *stats, char *attr, uint64_t value); static int update_stat32(nvlist_t *stats, char *attr, @@ -943,6 +944,16 @@ get_attrs(disk_t *diskp, int fd, char *opath, nvlist_t *attrs) } } + if (diskp->solid_state < 0) { + diskp->solid_state = get_solidstate(diskp, fd); + } + + if (diskp->solid_state > 0) { + if (nvlist_add_boolean(attrs, DM_SOLIDSTATE) != 0) { + return (ENOMEM); + } + } + return (0); } @@ -1197,6 +1208,31 @@ get_rpm(disk_t *dp, int fd) return (rpm); } +static int +get_solidstate(disk_t *dp, int fd) +{ + int opened_here = 0; + int solid_state = -1; + + /* We may have already opened the device. */ + if (fd < 0) { + fd = drive_open_disk(dp, NULL, 0); + opened_here = 1; + } + + if (fd >= 0) { + if (ioctl(fd, DKIOCSOLIDSTATE, &solid_state) < 0) { + solid_state = -1; + } + } + + if (opened_here) { + (void) close(fd); + } + + return (solid_state); +} + /* * ******** the rest of this is uscsi stuff for the drv type ******** */ diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c index 9728eab65e..19089e8531 100644 --- a/usr/src/lib/libdiskmgt/common/findevs.c +++ b/usr/src/lib/libdiskmgt/common/findevs.c @@ -997,6 +997,7 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args) diskp->cd_rom = 0; diskp->rpm = 0; + diskp->solid_state = -1; type = di_minor_nodetype(args->minor); prod_id = get_str_prop(PROD_ID_PROP, args->node); diff --git a/usr/src/lib/libdiskmgt/common/libdiskmgt.h b/usr/src/lib/libdiskmgt/common/libdiskmgt.h index d075746122..2c42f6e8cc 100644 --- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h +++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h @@ -21,6 +21,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _LIBDISKMGT_H @@ -35,6 +36,144 @@ extern "C" { /* + * Disk Management Library + * + * This library provides a common way to gather information about a system's + * disks, controllers, and related components. + * + * + * THREADS + * ------- + * + * In general all of the functions are thread safe, however there are some + * specific considerations for getting events. The dm_get_event function may + * block the calling thread if no event is currently available. If another + * thread calls dm_get_event while a thread is already blocked in this function, + * the second thread will also block. When an event arrives and multiple + * threads are waiting for events, it is undefined which thread will be + * unblocked and receive the event. If a callback is used for handling events, + * this is equivalent to the dm_get_event function, so mixing callbacks and + * dm_get_event is also nondeterministic. + * + * + * ERRORS + * ------ + * + * In general all of the functions take an errno pointer. This is an integer + * that will contain 0 if the function succeeded or contains an errno (see + * errno.h) if there was an error. If the function returns some data, that + * return data will generally be null if an error occured (see the API comment + * for the specific function for details). Many of the functions take a + * descriptor and provide more information for that descriptor. These functions + * may return an error if the object was removed between the call which obtained + * the descriptor and the call to get more information about the object (errno + * will be ENODEV). Only a few of the possible errno values will be returned; + * typically: + * EPERM not super-user + * ENOMEM not enough memory + * ENODEV no such device + * EINVAL invalid argument + * ENOENT no event queue has been created + * + * Many of the functions require the application to be running as root in order + * to get complete information. EPERM will be returned if the application is + * not running as root. However, not all of the functions have this requirement + * (i.e. event handling). + * + * It is possible for the system to run out of memory while receiving events. + * Since event receipt is asyncronous from the dm_get_event call there may not + * be a thread waiting when the event occurs and ENOMEM is detected. In this + * case the event will be lost. The first call to dm_get_event following this + * condition will immediately return ENOMEM, even if events are queued. + * Subsequent calls can return events. The dm_get_event call will clear the + * pending ENOMEM condition. There is no way to know how many events were lost + * when this situation occurs. If a thread is waiting when the event arrives + * and the ENOMEM condition occurs, the call will also return with ENOMEM. + * There is no way to determine if the system ran out of memory before the + * dm_get_event call or while the thread was blocked in the dm_get_event call + * since both conditions cause dm_get_event to return ENOMEM. + * + * + * MEMORY MANAGEMENT + * ----------------- + * + * Most of the functions that return data are returning memory that has been + * allocated and must be freed by the application when no longer needed. The + * application should call the proper free function to free the memory. Most of + * the functions return either a nvlist or an array of descriptors. The normal + * nvlist function (nvlist_free; see libnvpair(3LIB)) can be used to free the + * simple nvlists. Other functions are provided to free the more complex data + * structures. + * + * The following list shows the functions that return allocated memory and the + * corresponding function to free the memory: + * dm_get_descriptors dm_free_descriptors + * dm_get_associated_descriptors dm_free_descriptors + * dm_get_descriptor_by_name dm_free_descriptor + * dm_get_name dm_free_name + * dm_get_attributes nvlist_free + * dm_get_stats nvlist_free + * dm_get_event nvlist_free + * + * + * EVENTS + * ------ + * + * Event information is returned as a nvlist. It may be possible to return more + * information about events over time, especially information about what has + * changed. However, that may not always be the case, so by using an nvlist we + * have a very generic event indication. At a minimum the event will return the + * name of the device, the type of device (see dm_desc_type_t) and the type of + * event. The event type is a string which can currently be; add, remove, + * change. + * + * If a drive goes up or down this could be returned as event type "change". + * The application could get the drive information to see that the "status" + * attribute has changed value (ideally the event would include an attribute + * with the name of the changed attribute as the value). Although the API can + * return events for all drive related changes, events will not necessarily be + * delivered for all changes unless the system generates those events. + * + * + * Controller/HBAs + * --------------- + * + * In general the API means "the parent node of the drive in the device tree" + * where the word "controller" is used. This can actually be either the HBA or + * the drive controller depending on the type of the drive. + * + * Drives can be connected to their controller(s) in three different ways: + * single controller + * multiple controllers + * multiple controllers with mpxio + * These cases will lead to different information being available for the + * configuration. The two interesting cases are multi-path with and without + * mpxio. With mpxio the drive will have a unique name and a single controller + * (scsi_vhci). The physical controllers, the paths to the drive, can be + * obtained by calling dm_get_associated_descriptors with a drive descriptor and + * a type of DM_PATH. This will only return these physical paths when MPXIO, or + * possibly some future similar feature, is controlling the drive. + * + * Without mpxio the drive does not have a unique public name (in all cases the + * alias(es) of the drive can be determined by calling + * dm_get_associated_descriptors to get the DM_ALIAS descriptors. There will be + * more than one controller returned from dm_get_associated_descriptors when + * called with a type of DM_CONTROLLER. The controllers for each of the aliases + * will be returned in the same order as the aliases descriptors. For example, + * a drive with two paths has the aliases c5t3d2 and c7t1d0. There will be two + * controllers returned; the first corresponds to c5 and the second corresponds + * to c7. + * + * In the multi-path, non-mpxio case the drive has more than one alias. + * Although most of the drive attributes are represented on the drive (see + * dm_get_attributes) there can be some different attributes for the different + * aliases for the drive. Use dm_get_associated_descriptors to get the DM_ALIAS + * descriptors which can then be used to obtain these attributes. Use of this + * algorithm is not restricted to the multi-path, non-mpxio case. For example, + * it can be used to get the target/lun for a SCSI drive with a single path. + */ + +/* * Holds all the data regarding the device. * Private to libdiskmgt. Must use dm_xxx functions to set/get data. */ @@ -50,6 +189,17 @@ typedef enum { DM_WHO_ZPOOL_SPARE } dm_who_type_t; +/* + * The API uses a "descriptor" to identify the managed objects such as drives, + * controllers, media, slices, partitions, paths and buses. The descriptors are + * opaque and are only returned or used as parameters to the other functions in + * the API. The descriptor definition is a typedef to dm_descriptor_t. + * + * Applications call either the dm_get_descriptors or + * dm_get_associated_descriptors function to obtain a list of descriptors of a + * specific type. The application specifies the desired type from the following + * enumeration: + */ typedef enum { DM_DRIVE = 0, DM_CONTROLLER, @@ -61,6 +211,31 @@ typedef enum { DM_BUS } dm_desc_type_t; +/* + * These descriptors are associated with each other in the following way: + * + * alias partition + * _ \ / | + * / \ \ / | + * \ / \ / | + * bus --- controller --- drive --- media | + * | / \ | + * | / \ | + * | / \ | + * path slice + * + * The dm_get_associated_descriptors function can be used get the descriptors + * associated with a given descriptor. The dm_get_associated_types function can + * be used to find the types that can be associated with a given type. + * + * The attributes and values for these objects are described using a list of + * name/value pairs (see libnvpair(3LIB) and the specific comments for each + * function in the API section of this document). + * + * Drives and media have a type which are defined as the following enumerations. + * There could be additional types added to these enumerations as new drive and + * media types are supported by the system. + */ typedef enum { DM_DT_UNKNOWN = 0, @@ -102,6 +277,11 @@ typedef enum { #define DM_FILTER_END -1 +/* + * The dm_get_stats function takes a stat_type argument for the specific sample + * to get for the descriptor. The following enums specify the drive and slice + * stat types. + */ /* drive stat name */ typedef enum { DM_DRV_STAT_PERFORMANCE = 0, @@ -147,6 +327,7 @@ typedef enum { #define DM_PRODUCT_ID "product_id" #define DM_REMOVABLE "removable" /* also in media */ #define DM_RPM "rpm" +#define DM_SOLIDSTATE "solid_state" #define DM_STATUS "status" #define DM_SYNC_SPEED "sync_speed" #define DM_TEMPERATURE "temperature" diff --git a/usr/src/lib/libdladm/common/libdladm.h b/usr/src/lib/libdladm/common/libdladm.h index f0811ae5df..1cfb927a41 100644 --- a/usr/src/lib/libdladm/common/libdladm.h +++ b/usr/src/lib/libdladm/common/libdladm.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. */ #ifndef _LIBDLADM_H @@ -71,6 +72,10 @@ extern "C" { * - DLADM_OPT_BOOT: * Bypass check functions during boot (used by pool property since pools * can come up after link properties are set) + * + * - DLADM_OPT_TRANSIENT: + * Indicates that the link assigned to a zone is transient and will be + * removed when the zone shuts down. */ #define DLADM_OPT_ACTIVE 0x00000001 #define DLADM_OPT_PERSIST 0x00000002 @@ -81,6 +86,7 @@ extern "C" { #define DLADM_OPT_VLAN 0x00000040 #define DLADM_OPT_NOREFRESH 0x00000080 #define DLADM_OPT_BOOT 0x00000100 +#define DLADM_OPT_TRANSIENT 0x00000200 #define DLADM_WALK_TERMINATE 0 #define DLADM_WALK_CONTINUE -1 diff --git a/usr/src/lib/libdladm/common/libdllink.c b/usr/src/lib/libdladm/common/libdllink.c index 8a3c5759ee..303885e929 100644 --- a/usr/src/lib/libdladm/common/libdllink.c +++ b/usr/src/lib/libdladm/common/libdllink.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <sys/types.h> @@ -386,10 +387,14 @@ dladm_linkduplex2str(link_duplex_t duplex, char *buf) /* * Case 1: rename an existing link1 to a link2 that does not exist. * Result: <linkid1, link2> + * The zonename parameter is used to allow us to create a VNIC in the global + * zone which is assigned to a non-global zone. Since there is a race condition + * in the create process if two VNICs have the same name, we need to rename it + * after it has been assigned to the zone. */ static dladm_status_t i_dladm_rename_link_c1(dladm_handle_t handle, datalink_id_t linkid1, - const char *link1, const char *link2, uint32_t flags) + const char *link1, const char *link2, uint32_t flags, const char *zonename) { dld_ioc_rename_t dir; dladm_status_t status = DLADM_STATUS_OK; @@ -402,6 +407,10 @@ i_dladm_rename_link_c1(dladm_handle_t handle, datalink_id_t linkid1, dir.dir_linkid1 = linkid1; dir.dir_linkid2 = DATALINK_INVALID_LINKID; (void) strlcpy(dir.dir_link, link2, MAXLINKNAMELEN); + if (zonename != NULL) + dir.dir_zoneinit = B_TRUE; + else + dir.dir_zoneinit = B_FALSE; if (ioctl(dladm_dld_fd(handle), DLDIOC_RENAME, &dir) < 0) { status = dladm_errno2status(errno); @@ -412,6 +421,7 @@ i_dladm_rename_link_c1(dladm_handle_t handle, datalink_id_t linkid1, status = dladm_remap_datalink_id(handle, linkid1, link2); if (status != DLADM_STATUS_OK && (flags & DLADM_OPT_ACTIVE)) { (void) strlcpy(dir.dir_link, link1, MAXLINKNAMELEN); + dir.dir_zoneinit = B_FALSE; (void) ioctl(dladm_dld_fd(handle), DLDIOC_RENAME, &dir); } return (status); @@ -508,6 +518,7 @@ i_dladm_rename_link_c2(dladm_handle_t handle, datalink_id_t linkid1, */ dir.dir_linkid1 = linkid1; dir.dir_linkid2 = linkid2; + dir.dir_zoneinit = B_FALSE; if (ioctl(dladm_dld_fd(handle), DLDIOC_RENAME, &dir) < 0) status = dladm_errno2status(errno); @@ -617,7 +628,8 @@ done: } dladm_status_t -dladm_rename_link(dladm_handle_t handle, const char *link1, const char *link2) +dladm_rename_link(dladm_handle_t handle, const char *zonename, + const char *link1, const char *link2) { datalink_id_t linkid1 = DATALINK_INVALID_LINKID; datalink_id_t linkid2 = DATALINK_INVALID_LINKID; @@ -627,11 +639,11 @@ dladm_rename_link(dladm_handle_t handle, const char *link1, const char *link2) boolean_t remphy2 = B_FALSE; dladm_status_t status; - (void) dladm_name2info(handle, link1, &linkid1, &flags1, &class1, - &media1); - if ((dladm_name2info(handle, link2, &linkid2, &flags2, &class2, - &media2) == DLADM_STATUS_OK) && (class2 == DATALINK_CLASS_PHYS) && - (flags2 == DLADM_OPT_PERSIST)) { + (void) dladm_zname2info(handle, zonename, link1, &linkid1, &flags1, + &class1, &media1); + if ((dladm_zname2info(handle, zonename, link2, &linkid2, &flags2, + &class2, &media2) == DLADM_STATUS_OK) && + (class2 == DATALINK_CLASS_PHYS) && (flags2 == DLADM_OPT_PERSIST)) { /* * see whether link2 is a removed physical link. */ @@ -645,7 +657,7 @@ dladm_rename_link(dladm_handle_t handle, const char *link1, const char *link2) * does not exist. */ status = i_dladm_rename_link_c1(handle, linkid1, link1, - link2, flags1); + link2, flags1, zonename); } else if (remphy2) { /* * case 2: rename an available link to a REMOVED diff --git a/usr/src/lib/libdladm/common/libdllink.h b/usr/src/lib/libdladm/common/libdllink.h index a2830b5e37..a858e78aa3 100644 --- a/usr/src/lib/libdladm/common/libdllink.h +++ b/usr/src/lib/libdladm/common/libdllink.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #ifndef _LIBDLLINK_H @@ -121,7 +122,7 @@ extern dladm_status_t dladm_info(dladm_handle_t, datalink_id_t, dladm_attr_t *); extern dladm_status_t dladm_rename_link(dladm_handle_t, const char *, - const char *); + const char *, const char *); extern dladm_status_t dladm_set_linkprop(dladm_handle_t, datalink_id_t, const char *, char **, uint_t, uint_t); @@ -170,6 +171,9 @@ extern dladm_status_t dladm_up_datalink_id(dladm_handle_t, datalink_id_t); extern dladm_status_t dladm_name2info(dladm_handle_t, const char *, datalink_id_t *, uint32_t *, datalink_class_t *, uint32_t *); +extern dladm_status_t dladm_zname2info(dladm_handle_t, const char *, + const char *, datalink_id_t *, uint32_t *, + datalink_class_t *, uint32_t *); extern dladm_status_t dladm_datalink_id2info(dladm_handle_t, datalink_id_t, uint32_t *, datalink_class_t *, uint32_t *, char *, size_t); diff --git a/usr/src/lib/libdladm/common/libdlmgmt.c b/usr/src/lib/libdladm/common/libdlmgmt.c index 4b0753417c..c9c7906934 100644 --- a/usr/src/lib/libdladm/common/libdlmgmt.c +++ b/usr/src/lib/libdladm/common/libdlmgmt.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <door.h> @@ -528,12 +529,24 @@ dladm_getnext_conf_linkprop(dladm_handle_t handle, dladm_conf_t conf, } /* - * Get the link ID that is associated with the given name. + * Get the link ID that is associated with the given name in the current zone. */ dladm_status_t dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp, uint32_t *flagp, datalink_class_t *classp, uint32_t *mediap) { + return (dladm_zname2info(handle, NULL, link, linkidp, flagp, classp, + mediap)); +} + +/* + * Get the link ID that is associated with the given zone/name pair. + */ +dladm_status_t +dladm_zname2info(dladm_handle_t handle, const char *zonename, const char *link, + datalink_id_t *linkidp, uint32_t *flagp, datalink_class_t *classp, + uint32_t *mediap) +{ dlmgmt_door_getlinkid_t getlinkid; dlmgmt_getlinkid_retval_t retval; datalink_id_t linkid; @@ -542,6 +555,10 @@ dladm_name2info(dladm_handle_t handle, const char *link, datalink_id_t *linkidp, getlinkid.ld_cmd = DLMGMT_CMD_GETLINKID; (void) strlcpy(getlinkid.ld_link, link, MAXLINKNAMELEN); + if (zonename != NULL) + getlinkid.ld_zoneid = getzoneidbyname(zonename); + else + getlinkid.ld_zoneid = -1; if ((status = dladm_door_call(handle, &getlinkid, sizeof (getlinkid), &retval, &sz)) != DLADM_STATUS_OK) { diff --git a/usr/src/lib/libdladm/common/libdlvnic.c b/usr/src/lib/libdladm/common/libdlvnic.c index 6dba8d6fad..1a866dcb06 100644 --- a/usr/src/lib/libdladm/common/libdlvnic.c +++ b/usr/src/lib/libdladm/common/libdlvnic.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ #include <stdio.h> @@ -537,27 +538,35 @@ dladm_vnic_create(dladm_handle_t handle, const char *vnic, datalink_id_t linkid, vnic_created = B_TRUE; /* Save vnic configuration and its properties */ - if (!(flags & DLADM_OPT_PERSIST)) - goto done; + if (flags & DLADM_OPT_PERSIST) { + status = dladm_vnic_persist_conf(handle, name, &attr, class); + if (status == DLADM_STATUS_OK) + conf_set = B_TRUE; + } - status = dladm_vnic_persist_conf(handle, name, &attr, class); - if (status != DLADM_STATUS_OK) - goto done; - conf_set = B_TRUE; +done: + if (status == DLADM_STATUS_OK && proplist != NULL) { + uint32_t flg; + + flg = (flags & DLADM_OPT_PERSIST) ? + DLADM_OPT_PERSIST : DLADM_OPT_ACTIVE; - if (proplist != NULL) { for (i = 0; i < proplist->al_count; i++) { dladm_arg_info_t *aip = &proplist->al_info[i]; + if (strcmp(aip->ai_name, "zone") == 0 && + flags & DLADM_OPT_TRANSIENT) + flg |= DLADM_OPT_TRANSIENT; + else + flg &= ~DLADM_OPT_TRANSIENT; + status = dladm_set_linkprop(handle, vnic_id, - aip->ai_name, aip->ai_val, aip->ai_count, - DLADM_OPT_PERSIST); + aip->ai_name, aip->ai_val, aip->ai_count, flg); if (status != DLADM_STATUS_OK) break; } } -done: if (status != DLADM_STATUS_OK) { if (conf_set) (void) dladm_remove_conf(handle, vnic_id); diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index 229a5fd83f..d46054e686 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <stdlib.h> @@ -151,11 +152,13 @@ static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate, get_bridge_pvid, get_protection, get_rxrings, get_txrings, get_cntavail, get_allowedips, get_allowedcids, get_pool, - get_rings_range, get_linkmode_prop; + get_rings_range, get_linkmode_prop, + get_promisc_filtered; static pd_setf_t set_zone, set_rate, set_powermode, set_radio, set_public_prop, set_resource, set_stp_prop, - set_bridge_forward, set_bridge_pvid; + set_bridge_forward, set_bridge_pvid, + set_promisc_filtered; static pd_checkf_t check_zone, check_autopush, check_rate, check_hoplimit, check_encaplim, check_uint32, check_maxbw, check_cpus, @@ -363,6 +366,8 @@ static link_attr_t link_attr[] = { { MAC_PROP_IB_LINKMODE, sizeof (uint32_t), "linkmode"}, + { MAC_PROP_VN_PROMISC_FILTERED, sizeof (boolean_t), "promisc-filtered"}, + { MAC_PROP_PRIVATE, 0, "driver-private"} }; @@ -417,6 +422,11 @@ static val_desc_t link_protect_vals[] = { { "dhcp-nospoof", MPT_DHCPNOSPOOF }, }; +static val_desc_t link_promisc_filtered_vals[] = { + { "off", B_FALSE }, + { "on", B_TRUE }, +}; + static val_desc_t dladm_wlan_radio_vals[] = { { "on", DLADM_WLAN_RADIO_ON }, { "off", DLADM_WLAN_RADIO_OFF } @@ -682,6 +692,12 @@ static prop_desc_t prop_table[] = { set_resource, NULL, get_protection, check_prop, 0, DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE }, + { "promisc-filtered", { "on", 1 }, + link_promisc_filtered_vals, VALCNT(link_promisc_filtered_vals), + set_promisc_filtered, NULL, get_promisc_filtered, check_prop, 0, + DATALINK_CLASS_VNIC, DATALINK_ANY_MEDIATYPE }, + + { "allowed-ips", { "--", 0 }, NULL, 0, set_resource, NULL, get_allowedips, check_allowedips, PD_CHECK_ALLOC, @@ -1513,6 +1529,9 @@ set_zone(dladm_handle_t handle, prop_desc_t *pdp, datalink_id_t linkid, if (zid_new == zid_old) return (DLADM_STATUS_OK); + if (flags & DLADM_OPT_TRANSIENT) + dzp->diz_transient = B_TRUE; + if ((status = set_public_prop(handle, pdp, linkid, vdp, val_cnt, flags, media)) != DLADM_STATUS_OK) return (status); @@ -4583,3 +4602,50 @@ get_linkmode_prop(dladm_handle_t handle, prop_desc_t *pdp, *val_cnt = 1; return (DLADM_STATUS_OK); } + +/*ARGSUSED*/ +static dladm_status_t +get_promisc_filtered(dladm_handle_t handle, prop_desc_t *pdp, + datalink_id_t linkid, char **prop_val, uint_t *val_cnt, + datalink_media_t media, uint_t flags, uint_t *perm_flags) +{ + char *s; + dladm_status_t status; + boolean_t filt; + + status = i_dladm_get_public_prop(handle, linkid, pdp->pd_name, flags, + perm_flags, &filt, sizeof (filt)); + if (status != DLADM_STATUS_OK) + return (status); + + if (filt != 0) + s = link_promisc_filtered_vals[1].vd_name; + else + s = link_promisc_filtered_vals[0].vd_name; + (void) snprintf(prop_val[0], DLADM_STRSIZE, "%s", s); + + *val_cnt = 1; + return (DLADM_STATUS_OK); +} + +/* ARGSUSED */ +static dladm_status_t +set_promisc_filtered(dladm_handle_t handle, prop_desc_t *pdp, + datalink_id_t linkid, val_desc_t *vdp, uint_t val_cnt, uint_t flags, + datalink_media_t media) +{ + dld_ioc_macprop_t *dip; + dladm_status_t status = DLADM_STATUS_OK; + + dip = i_dladm_buf_alloc_by_name(0, linkid, pdp->pd_name, + 0, &status); + + if (dip == NULL) + return (status); + + (void) memcpy(dip->pr_val, &vdp->vd_val, dip->pr_valsize); + status = i_dladm_macprop(handle, dip, B_TRUE); + + free(dip); + return (status); +} diff --git a/usr/src/lib/libdladm/common/mapfile-vers b/usr/src/lib/libdladm/common/mapfile-vers index b781c93aff..3eaeea656e 100644 --- a/usr/src/lib/libdladm/common/mapfile-vers +++ b/usr/src/lib/libdladm/common/mapfile-vers @@ -20,6 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, Joyent Inc. All rights reserved. # # @@ -134,6 +135,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { dladm_remap_datalink_id; dladm_up_datalink_id; dladm_name2info; + dladm_zname2info; dladm_datalink_id2info; dladm_walk_datalink_id; dladm_create_conf; diff --git a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java index 366d83476b..6983e279fa 100644 --- a/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java +++ b/usr/src/lib/libdns_sd/java/com/apple/dnssd/DNSSDRecordRegistrar.java @@ -5,9 +5,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -25,9 +25,6 @@ Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0 Revision 1.1 2006/06/20 23:00:12 rpantos <rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent - -ident "%Z%%M% %I% %E% SMI" - */ @@ -38,7 +35,7 @@ package com.apple.dnssd; public interface DNSSDRecordRegistrar extends DNSSDService { - /** Register an independent {@link DNSRecord}.<P> + /** Register an independent {@link DNSRecord}.<P> @param flags Possible values are SHARED or UNIQUE (see flag type definitions for details). <P> @@ -55,25 +52,22 @@ public interface DNSSDRecordRegistrar extends DNSSDService as defined in nameser.h. <P> @param rrclass - The class of the resource record, as defined in nameser.h + The class of the resource record, as defined in nameser.h (usually 1 for the Internet class). <P> - @param rData + @param rdata The new rdata as it is to appear in the DNS record. <P> @param ttl The time to live of the resource record, in seconds. Pass 0 to use a default value. <P> - @param listener - This object will get called when the service is registered. - <P> @return A {@link DNSSDService} that can be used to abort the record registration. @throws SecurityException If a security manager is present and denies <tt>RuntimePermission("getDNSSDInstance")</tt>. @see RuntimePermission */ - public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype, + public DNSRecord registerRecord( int flags, int ifIndex, String fullname, int rrtype, int rrclass, byte[] rdata, int ttl) throws DNSSDException; -} +} diff --git a/usr/src/lib/libdtrace/Makefile.com b/usr/src/lib/libdtrace/Makefile.com index 8952f8db06..d92d33dff7 100644 --- a/usr/src/lib/libdtrace/Makefile.com +++ b/usr/src/lib/libdtrace/Makefile.com @@ -131,7 +131,7 @@ CERRWARN += -_gcc=-Wno-uninitialized CERRWARN += -_gcc=-Wno-switch YYCFLAGS = -LDLIBS += -lgen -lproc -lrtld_db -lnsl -lsocket -lctf -lelf -lc +LDLIBS += -lgen -lproc -lrtld_db -lnsl -lsocket -lctf -lelf -lc -lzonecfg DRTILDLIBS = $(LDLIBS.lib) -lc yydebug := YYCFLAGS += -DYYDEBUG diff --git a/usr/src/lib/libdtrace/common/dt_cc.c b/usr/src/lib/libdtrace/common/dt_cc.c index 9661ad9d0b..f4b0509b4a 100644 --- a/usr/src/lib/libdtrace/common/dt_cc.c +++ b/usr/src/lib/libdtrace/common/dt_cc.c @@ -2149,7 +2149,7 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path) (void) snprintf(fname, sizeof (fname), "%s/%s", path, dp->d_name); - if ((fp = fopen(fname, "r")) == NULL) { + if ((fp = fopen(fname, "rF")) == NULL) { dt_dprintf("skipping library %s: %s\n", fname, strerror(errno)); continue; @@ -2171,12 +2171,15 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path) dt_dprintf("skipping library %s, already processed " "library with the same name: %s", dp->d_name, dld->dtld_library); + (void) fclose(fp); continue; } dtp->dt_filetag = fname; - if (dt_lib_depend_add(dtp, &dtp->dt_lib_dep, fname) != 0) + if (dt_lib_depend_add(dtp, &dtp->dt_lib_dep, fname) != 0) { + (void) fclose(fp); return (-1); /* preserve dt_errno */ + } rv = dt_compile(dtp, DT_CTX_DPROG, DTRACE_PROBESPEC_NAME, NULL, @@ -2184,8 +2187,10 @@ dt_load_libs_dir(dtrace_hdl_t *dtp, const char *path) if (rv != NULL && dtp->dt_errno && (dtp->dt_errno != EDT_COMPILER || - dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND))) + dtp->dt_errtag != dt_errtag(D_PRAGMA_DEPEND))) { + (void) fclose(fp); return (-1); /* preserve dt_errno */ + } if (dtp->dt_errno) dt_dprintf("error parsing library %s: %s\n", diff --git a/usr/src/lib/libdtrace/common/dt_cg.c b/usr/src/lib/libdtrace/common/dt_cg.c index 3103106d27..28db9b2262 100644 --- a/usr/src/lib/libdtrace/common/dt_cg.c +++ b/usr/src/lib/libdtrace/common/dt_cg.c @@ -476,7 +476,7 @@ dt_cg_typecast(const dt_node_t *src, const dt_node_t *dst, if (!dt_node_is_scalar(dst)) return; /* not a scalar */ if (dstsize == srcsize && - ((src->dn_flags ^ dst->dn_flags) & DT_NF_SIGNED) != 0) + ((src->dn_flags ^ dst->dn_flags) & DT_NF_SIGNED) == 0) return; /* not narrowing or changing signed-ness */ if (dstsize > srcsize && (src->dn_flags & DT_NF_SIGNED) == 0) return; /* nothing to do in this case */ diff --git a/usr/src/lib/libdtrace/common/dt_dof.c b/usr/src/lib/libdtrace/common/dt_dof.c index 04c4c89cdb..c1f5dc827e 100644 --- a/usr/src/lib/libdtrace/common/dt_dof.c +++ b/usr/src/lib/libdtrace/common/dt_dof.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <sys/types.h> @@ -482,7 +483,7 @@ dof_add_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data) return (0); } -static void +static int dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) { dtrace_hdl_t *dtp = ddo->ddo_hdl; @@ -493,8 +494,12 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) size_t sz; id_t i; - if (pvp->pv_flags & DT_PROVIDER_IMPL) - return; /* ignore providers that are exported by dtrace(7D) */ + if (pvp->pv_flags & DT_PROVIDER_IMPL) { + /* + * ignore providers that are exported by dtrace(7D) + */ + return (0); + } nxr = dt_popcb(pvp->pv_xrefs, pvp->pv_xrmax); dofs = alloca(sizeof (dof_secidx_t) * (nxr + 1)); @@ -521,6 +526,9 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) (void) dt_idhash_iter(pvp->pv_probes, dof_add_probe, ddo); + if (dt_buf_len(&ddo->ddo_probes) == 0) + return (dt_set_errno(dtp, EDT_NOPROBES)); + dofpv.dofpv_probes = dof_add_lsect(ddo, NULL, DOF_SECT_PROBES, sizeof (uint64_t), 0, sizeof (dof_probe_t), dt_buf_len(&ddo->ddo_probes)); @@ -575,6 +583,8 @@ dof_add_provider(dt_dof_t *ddo, const dt_provider_t *pvp) sizeof (dof_secidx_t), 0, sizeof (dof_secidx_t), sizeof (dof_secidx_t) * (nxr + 1)); } + + return (0); } static int @@ -818,8 +828,10 @@ dtrace_dof_create(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, uint_t flags) */ if (flags & DTRACE_D_PROBES) { for (pvp = dt_list_next(&dtp->dt_provlist); - pvp != NULL; pvp = dt_list_next(pvp)) - dof_add_provider(ddo, pvp); + pvp != NULL; pvp = dt_list_next(pvp)) { + if (dof_add_provider(ddo, pvp) != 0) + return (NULL); + } } /* diff --git a/usr/src/lib/libdtrace/common/dt_error.c b/usr/src/lib/libdtrace/common/dt_error.c index 9c1cbd73bc..f7ad28ebae 100644 --- a/usr/src/lib/libdtrace/common/dt_error.c +++ b/usr/src/lib/libdtrace/common/dt_error.c @@ -26,6 +26,7 @@ /* * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <strings.h> @@ -108,7 +109,8 @@ static const struct { { EDT_BADSTACKPC, "Invalid stack program counter size" }, { EDT_BADAGGVAR, "Invalid aggregation variable identifier" }, { EDT_OVERSION, "Client requested deprecated version of library" }, - { EDT_ENABLING_ERR, "Failed to enable probe" } + { EDT_ENABLING_ERR, "Failed to enable probe" }, + { EDT_NOPROBES, "No probe sites found for declared provider" } }; static const int _dt_nerr = sizeof (_dt_errlist) / sizeof (_dt_errlist[0]); diff --git a/usr/src/lib/libdtrace/common/dt_impl.h b/usr/src/lib/libdtrace/common/dt_impl.h index fa4c66540d..6420524701 100644 --- a/usr/src/lib/libdtrace/common/dt_impl.h +++ b/usr/src/lib/libdtrace/common/dt_impl.h @@ -25,7 +25,7 @@ */ /* - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -260,6 +260,7 @@ struct dtrace_hdl { uint_t dt_droptags; /* boolean: set via -xdroptags */ uint_t dt_active; /* boolean: set once tracing is active */ uint_t dt_stopped; /* boolean: set once tracing is stopped */ + uint_t dt_optset; /* boolean: set once options have been set */ processorid_t dt_beganon; /* CPU that executed BEGIN probe (if any) */ processorid_t dt_endedon; /* CPU that executed END probe (if any) */ uint_t dt_oflags; /* dtrace open-time options (see dtrace.h) */ @@ -512,7 +513,8 @@ enum { EDT_BADSTACKPC, /* invalid stack program counter size */ EDT_BADAGGVAR, /* invalid aggregation variable identifier */ EDT_OVERSION, /* client is requesting deprecated version */ - EDT_ENABLING_ERR /* failed to enable probe */ + EDT_ENABLING_ERR, /* failed to enable probe */ + EDT_NOPROBES /* no probes sites for declared provider */ }; /* diff --git a/usr/src/lib/libdtrace/common/dt_open.c b/usr/src/lib/libdtrace/common/dt_open.c index dd83370ee8..af3bc17b2c 100644 --- a/usr/src/lib/libdtrace/common/dt_open.c +++ b/usr/src/lib/libdtrace/common/dt_open.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, Joyent, Inc. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -110,9 +110,10 @@ #define DT_VERS_1_8 DT_VERSION_NUMBER(1, 8, 0) #define DT_VERS_1_8_1 DT_VERSION_NUMBER(1, 8, 1) #define DT_VERS_1_9 DT_VERSION_NUMBER(1, 9, 0) -#define DT_VERS_1_9_1 DT_VERSION_NUMBER(1, 9, 1) -#define DT_VERS_LATEST DT_VERS_1_9_1 -#define DT_VERS_STRING "Sun D 1.9.1" +#define DT_VERS_1_10 DT_VERSION_NUMBER(1, 10, 0) +#define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0) +#define DT_VERS_LATEST DT_VERS_1_11 +#define DT_VERS_STRING "Sun D 1.11" const dt_version_t _dtrace_versions[] = { DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */ @@ -133,7 +134,8 @@ const dt_version_t _dtrace_versions[] = { DT_VERS_1_8, /* D API 1.8 */ DT_VERS_1_8_1, /* D API 1.8.1 */ DT_VERS_1_9, /* D API 1.9 */ - DT_VERS_1_9_1, /* D API 1.9.1 */ + DT_VERS_1_10, /* D API 1.10 */ + DT_VERS_1_11, /* D API 1.11 */ 0 }; @@ -247,6 +249,8 @@ static const dt_ident_t _dtrace_globals[] = { &dt_idops_func, "uint64_t(uint64_t)" }, { "htons", DT_IDENT_FUNC, 0, DIF_SUBR_HTONS, DT_ATTR_EVOLCMN, DT_VERS_1_3, &dt_idops_func, "uint16_t(uint16_t)" }, +{ "getf", DT_IDENT_FUNC, 0, DIF_SUBR_GETF, DT_ATTR_STABCMN, DT_VERS_1_10, + &dt_idops_func, "file_t *(int)" }, { "gid", DT_IDENT_SCALAR, 0, DIF_VAR_GID, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "gid_t" }, { "id", DT_IDENT_SCALAR, 0, DIF_VAR_ID, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -261,6 +265,8 @@ static const dt_ident_t _dtrace_globals[] = { DT_VERS_1_5, &dt_idops_func, "string(int, void *)" }, { "ipl", DT_IDENT_SCALAR, 0, DIF_VAR_IPL, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_type, "uint_t" }, +{ "json", DT_IDENT_FUNC, 0, DIF_SUBR_JSON, DT_ATTR_STABCMN, DT_VERS_1_11, + &dt_idops_func, "string(const char *, const char *)" }, { "jstack", DT_IDENT_ACTFUNC, 0, DT_ACT_JSTACK, DT_ATTR_STABCMN, DT_VERS_1_0, &dt_idops_func, "stack(...)" }, { "lltostr", DT_IDENT_FUNC, 0, DIF_SUBR_LLTOSTR, DT_ATTR_STABCMN, DT_VERS_1_0, @@ -375,6 +381,8 @@ static const dt_ident_t _dtrace_globals[] = { &dt_idops_func, "string(const char *, const char *)" }, { "strtok", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOK, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "string(const char *, const char *)" }, +{ "strtoll", DT_IDENT_FUNC, 0, DIF_SUBR_STRTOLL, DT_ATTR_STABCMN, DT_VERS_1_11, + &dt_idops_func, "int64_t(const char *, [int])" }, { "substr", DT_IDENT_FUNC, 0, DIF_SUBR_SUBSTR, DT_ATTR_STABCMN, DT_VERS_1_1, &dt_idops_func, "string(const char *, int, [int])" }, { "sum", DT_IDENT_AGGFUNC, 0, DTRACEAGG_SUM, DT_ATTR_STABCMN, DT_VERS_1_0, diff --git a/usr/src/lib/libdtrace/common/dt_options.c b/usr/src/lib/libdtrace/common/dt_options.c index cc3ae7b9d3..71bd508ecd 100644 --- a/usr/src/lib/libdtrace/common/dt_options.c +++ b/usr/src/lib/libdtrace/common/dt_options.c @@ -25,6 +25,7 @@ */ /* + * Copyright (c) 2011, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -40,6 +41,8 @@ #include <alloca.h> #include <errno.h> #include <fcntl.h> +#include <zone.h> +#include <libzonecfg.h> #include <dt_impl.h> #include <dt_string.h> @@ -836,6 +839,44 @@ dt_opt_bufresize(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) return (0); } +/*ARGSUSED*/ +static int +dt_opt_zone(dtrace_hdl_t *dtp, const char *arg, uintptr_t option) +{ + zoneid_t z, did; + + if (arg == NULL) + return (dt_set_errno(dtp, EDT_BADOPTVAL)); + + /* + * If the specified zone is currently running, we'll query the kernel + * for its debugger ID. If it doesn't appear to be running, we'll look + * for it for among all installed zones (thereby allowing a zdefs + * enabling against a halted zone). + */ + if ((z = getzoneidbyname(arg)) != -1) { + if (zone_getattr(z, ZONE_ATTR_DID, &did, sizeof (did)) < 0) + return (dt_set_errno(dtp, EDT_BADOPTVAL)); + } else { + zone_dochandle_t handle; + + if ((handle = zonecfg_init_handle()) == NULL) + return (dt_set_errno(dtp, errno)); + + if (zonecfg_get_handle(arg, handle) != Z_OK) { + zonecfg_fini_handle(handle); + return (dt_set_errno(dtp, EDT_BADOPTVAL)); + } + + did = zonecfg_get_did(handle); + zonecfg_fini_handle(handle); + } + + dtp->dt_options[DTRACEOPT_ZONE] = did; + + return (0); +} + int dt_options_load(dtrace_hdl_t *dtp) { @@ -969,6 +1010,7 @@ static const dt_option_t _dtrace_rtoptions[] = { { "statusrate", dt_opt_rate, DTRACEOPT_STATUSRATE }, { "strsize", dt_opt_strsize, DTRACEOPT_STRSIZE }, { "ustackframes", dt_opt_runtime, DTRACEOPT_USTACKFRAMES }, + { "zone", dt_opt_zone, DTRACEOPT_ZONE }, { "temporal", dt_opt_runtime, DTRACEOPT_TEMPORAL }, { NULL } }; @@ -1046,9 +1088,41 @@ dtrace_setopt(dtrace_hdl_t *dtp, const char *opt, const char *val) if (dtp->dt_active) return (dt_set_errno(dtp, EDT_ACTIVE)); + /* + * If our options had been previously ioctl'd down, + * clear dt_optset to indicate that a run-time option + * has since been set. + */ + dtp->dt_optset = B_FALSE; + return (op->o_func(dtp, val, op->o_option)); } } return (dt_set_errno(dtp, EDT_BADOPTNAME)); } + +int +dtrace_setopts(dtrace_hdl_t *dtp) +{ + void *dof; + int err; + + if (dtp->dt_optset) + return (0); + + if ((dof = dtrace_getopt_dof(dtp)) == NULL) + return (-1); /* dt_errno has been set for us */ + + if ((err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof)) == -1) + (void) dt_set_errno(dtp, errno); + + dtrace_dof_destroy(dtp, dof); + + if (err == -1) + return (-1); + + dtp->dt_optset = B_TRUE; + + return (0); +} diff --git a/usr/src/lib/libdtrace/common/dt_program.c b/usr/src/lib/libdtrace/common/dt_program.c index 7d725bd0af..e4f9d8dd1c 100644 --- a/usr/src/lib/libdtrace/common/dt_program.c +++ b/usr/src/lib/libdtrace/common/dt_program.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent, Inc. All rights reserved. * Copyright (c) 2011 by Delphix. All rights reserved. */ @@ -154,6 +155,14 @@ dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, void *dof; int n, err; + /* + * If we have not yet ioctl'd down our options DOF, we'll do that + * before enabling any probes (some options will affect which probes + * we match). + */ + if (dtrace_setopts(dtp) != 0) + return (-1); + dtrace_program_info(dtp, pgp, pip); if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL) diff --git a/usr/src/lib/libdtrace/common/dt_work.c b/usr/src/lib/libdtrace/common/dt_work.c index 97a7f62d69..c330394027 100644 --- a/usr/src/lib/libdtrace/common/dt_work.c +++ b/usr/src/lib/libdtrace/common/dt_work.c @@ -25,7 +25,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2011, Joyent, Inc. All rights reserved. + */ #include <dt_impl.h> #include <stddef.h> @@ -164,13 +166,22 @@ dtrace_status(dtrace_hdl_t *dtp) int dtrace_go(dtrace_hdl_t *dtp) { - void *dof; - int err; - if (dtp->dt_active) return (dt_set_errno(dtp, EINVAL)); /* + * In most cases, we will have already ioctl'd down our options DOF + * by this point -- but if a libdtrace does a dtrace_setopt() after + * calling dtrace_program_exec() but before calling dtrace_go(), + * dt_optset will be cleared and we need to ioctl down the options + * DOF now. + */ + if (dtrace_setopts(dtp) != 0 && + (dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL)) { + return (-1); + } + + /* * If a dtrace:::ERROR program and callback are registered, enable the * program before we start tracing. If this fails for a vector open * with ENOTTY, we permit dtrace_go() to succeed so that vector clients @@ -178,19 +189,10 @@ dtrace_go(dtrace_hdl_t *dtp) * though they do not provide support for the DTRACEIOC_ENABLE ioctl. */ if (dtp->dt_errprog != NULL && - dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && ( - dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL)) - return (-1); /* dt_errno has been set for us */ - - if ((dof = dtrace_getopt_dof(dtp)) == NULL) + dtrace_program_exec(dtp, dtp->dt_errprog, NULL) == -1 && + (dtp->dt_errno != ENOTTY || dtp->dt_vector == NULL)) return (-1); /* dt_errno has been set for us */ - err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof); - dtrace_dof_destroy(dtp, dof); - - if (err == -1 && (errno != ENOTTY || dtp->dt_vector == NULL)) - return (dt_set_errno(dtp, errno)); - if (dt_ioctl(dtp, DTRACEIOC_GO, &dtp->dt_beganon) == -1) { if (errno == EACCES) return (dt_set_errno(dtp, EDT_DESTRUCTIVE)); diff --git a/usr/src/lib/libdtrace/common/dtrace.h b/usr/src/lib/libdtrace/common/dtrace.h index 87df1ca440..d3031d8c4c 100644 --- a/usr/src/lib/libdtrace/common/dtrace.h +++ b/usr/src/lib/libdtrace/common/dtrace.h @@ -81,6 +81,7 @@ extern const char *dtrace_subrstr(dtrace_hdl_t *, int); extern int dtrace_setopt(dtrace_hdl_t *, const char *, const char *); extern int dtrace_getopt(dtrace_hdl_t *, const char *, dtrace_optval_t *); +extern int dtrace_setopts(dtrace_hdl_t *); extern void dtrace_update(dtrace_hdl_t *); extern int dtrace_ctlfd(dtrace_hdl_t *); diff --git a/usr/src/lib/libdtrace/common/io.d.in b/usr/src/lib/libdtrace/common/io.d.in index cb1e32cffe..5f676b9546 100644 --- a/usr/src/lib/libdtrace/common/io.d.in +++ b/usr/src/lib/libdtrace/common/io.d.in @@ -23,7 +23,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ #pragma D depends_on module unix #pragma D depends_on provider io @@ -197,9 +199,7 @@ translator fileinfo_t < struct file *F > { fi_oflags = F == NULL ? 0 : F->f_flag + (int)@FOPEN@; }; -inline fileinfo_t fds[int fd] = xlate <fileinfo_t> ( - fd >= 0 && fd < curthread->t_procp->p_user.u_finfo.fi_nfiles ? - curthread->t_procp->p_user.u_finfo.fi_list[fd].uf_file : NULL); +inline fileinfo_t fds[int fd] = xlate <fileinfo_t> (getf(fd)); #pragma D attributes Stable/Stable/Common fds #pragma D binding "1.1" fds diff --git a/usr/src/lib/libgrubmgmt/common/libgrub_fs.c b/usr/src/lib/libgrubmgmt/common/libgrub_fs.c index 51f7cc0e17..db1576b828 100644 --- a/usr/src/lib/libgrubmgmt/common/libgrub_fs.c +++ b/usr/src/lib/libgrubmgmt/common/libgrub_fs.c @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2011 Joyent, Inc. All rights reserved. */ /* @@ -129,7 +131,8 @@ get_zfs_root(zfs_handle_t *zfh, grub_fs_t *fs, grub_root_t *root) sizeof (root->gr_physpath))) == 0 && (ret = zpool_get_prop(zph, ZPOOL_PROP_BOOTFS, root->gr_fs[GRBM_ZFS_BOOTFS].gfs_dev, - sizeof (root->gr_fs[GRBM_ZFS_BOOTFS].gfs_dev), NULL)) == 0) { + sizeof (root->gr_fs[GRBM_ZFS_BOOTFS].gfs_dev), NULL, + B_FALSE)) == 0) { (void) strlcpy(root->gr_fs[GRBM_ZFS_TOPFS].gfs_dev, name, sizeof (root->gr_fs[GRBM_ZFS_TOPFS].gfs_dev)); diff --git a/usr/src/lib/libipd/Makefile b/usr/src/lib/libipd/Makefile new file mode 100644 index 0000000000..feab972218 --- /dev/null +++ b/usr/src/lib/libipd/Makefile @@ -0,0 +1,42 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2012 Joyent, Inc. All rights reserved. +# + +include ../Makefile.lib + +HDRS = libipd.h +HDRDIR = common +SUBDIRS = $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +install_h: $(ROOTHDRS) + +check: $(CHECKHDRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/libipd/Makefile.com b/usr/src/lib/libipd/Makefile.com new file mode 100644 index 0000000000..f118aa6cc3 --- /dev/null +++ b/usr/src/lib/libipd/Makefile.com @@ -0,0 +1,36 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2012 Joyent, Inc. All rights reserved. +# + +include ../../Makefile.lib + +LIBRARY = libipd.a +VERS = .1 +OBJECTS = libipd.o + +include ../../Makefile.lib + +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc +CPPFLAGS += -I../common + +SRCDIR = ../common + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/libipd/amd64/Makefile b/usr/src/lib/libipd/amd64/Makefile new file mode 100644 index 0000000000..0ff7206916 --- /dev/null +++ b/usr/src/lib/libipd/amd64/Makefile @@ -0,0 +1,19 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2012 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libipd/common/libipd.c b/usr/src/lib/libipd/common/libipd.c new file mode 100644 index 0000000000..c580fdf61e --- /dev/null +++ b/usr/src/lib/libipd/common/libipd.c @@ -0,0 +1,303 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/types.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> + +#include <libipd.h> +#include <sys/ipd.h> + +__thread ipd_errno_t ipd_errno = 0; +__thread char ipd_errmsg[512]; + +struct ipd_stat { + uint_t is_nzones; + zoneid_t *is_zoneids; + struct ipd_config *is_configs; +}; + +static ipd_errno_t +xlate_errno(int e) +{ + switch (e) { + case 0: + return (EIPD_NOERROR); + case ENOMEM: + case EAGAIN: + return (EIPD_NOMEM); + case ERANGE: + return (EIPD_RANGE); + case EPERM: + return (EIPD_PERM); + case EFAULT: + return (EIPD_FAULT); + case ENOTTY: + return (EIPD_INTERNAL); + default: + return (EIPD_UNKNOWN); + } +} + +const char * +ipd_strerror(ipd_errno_t e) +{ + switch (e) { + case EIPD_NOERROR: + return ("no error"); + case EIPD_NOMEM: + return ("out of memory"); + case EIPD_ZC_NOENT: + return ("zone does not exist or is not using ipd"); + case EIPD_RANGE: + return ("argument out of range"); + case EIPD_PERM: + return ("permission denied"); + case EIPD_FAULT: + return ("bad pointer"); + case EIPD_INTERNAL: + return ("internal library error"); + case EIPD_UNKNOWN: + default: + return ("unknown error"); + } +} + +static int +ipd_set_errno(ipd_errno_t e, const char *fmt, ...) +{ + va_list ap; + + ipd_errno = e; + if (fmt != NULL) { + va_start(ap, fmt); + (void) vsnprintf(ipd_errmsg, sizeof (ipd_errmsg), fmt, ap); + va_end(ap); + } else { + (void) strlcpy(ipd_errmsg, + ipd_strerror(e), sizeof (ipd_errmsg)); + } + + return (-1); +} + +int +ipd_open(const char *path) +{ + int fd; + + if (path == NULL) + path = IPD_DEV_PATH; + + fd = open(path, O_RDWR); + if (fd < 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to open %s: %s", path, strerror(errno))); + } + + return (fd); +} + +int +ipd_close(int fd) +{ + (void) close(fd); + return (0); +} + +int +ipd_status_read(int fd, ipd_stathdl_t *ispp) +{ + struct ipd_stat *isp = NULL; + ipd_ioc_list_t ipil; + uint_t rzones; + uint_t i; + + bzero(&ipil, sizeof (ipil)); + if (ioctl(fd, IPDIOC_LIST, &ipil) != 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to retrieve ipd zone list: %s", strerror(errno))); + } + + for (;;) { + if ((rzones = ipil.ipil_nzones) == 0) + break; + + ipil.ipil_info = + malloc(sizeof (ipd_ioc_info_t) * ipil.ipil_nzones); + if (ipil.ipil_info == NULL) + return (ipd_set_errno(EIPD_NOMEM, NULL)); + + if (ioctl(fd, IPDIOC_LIST, &ipil) != 0) { + free(ipil.ipil_info); + return (ipd_set_errno(xlate_errno(errno), + "unable to retrieve ipd zone list: %s", + strerror(errno))); + } + + if (ipil.ipil_nzones <= rzones) + break; + + free(ipil.ipil_info); + } + + if ((isp = malloc(sizeof (struct ipd_stat))) == NULL) { + free(ipil.ipil_info); + return (ipd_set_errno(EIPD_NOMEM, NULL)); + } + + isp->is_nzones = ipil.ipil_nzones; + + if (isp->is_nzones == 0) { + isp->is_zoneids = NULL; + isp->is_configs = NULL; + *ispp = isp; + return (0); + } + + isp->is_zoneids = malloc(sizeof (zoneid_t) * ipil.ipil_nzones); + if (isp->is_zoneids == NULL) { + free(ipil.ipil_info); + free(isp); + return (ipd_set_errno(EIPD_NOMEM, NULL)); + } + isp->is_configs = malloc(sizeof (struct ipd_config) * ipil.ipil_nzones); + if (isp->is_configs == NULL) { + free(ipil.ipil_info); + free(isp->is_zoneids); + free(isp); + return (ipd_set_errno(EIPD_NOMEM, NULL)); + } + + for (i = 0; i < isp->is_nzones; i++) { + isp->is_zoneids[i] = ipil.ipil_info[i].ipii_zoneid; + + isp->is_configs[i].ic_corrupt = ipil.ipil_info[i].ipii_corrupt; + isp->is_configs[i].ic_drop = ipil.ipil_info[i].ipii_drop; + isp->is_configs[i].ic_delay = ipil.ipil_info[i].ipii_delay; + + isp->is_configs[i].ic_mask = + ((!!isp->is_configs[i].ic_corrupt) * IPDM_CORRUPT) | + ((!!isp->is_configs[i].ic_drop) * IPDM_DROP) | + ((!!isp->is_configs[i].ic_delay) * IPDM_DELAY); + } + + *ispp = isp; + return (0); +} + +void +ipd_status_foreach_zone(const ipd_stathdl_t hdl, ipd_status_cb_f f, void *arg) +{ + const struct ipd_stat *isp = hdl; + uint_t i; + + for (i = 0; i < isp->is_nzones; i++) + f(isp->is_zoneids[i], &isp->is_configs[i], arg); +} + +int +ipd_status_get_config(const ipd_stathdl_t hdl, zoneid_t z, ipd_config_t **icpp) +{ + const struct ipd_stat *isp = hdl; + uint_t i; + + for (i = 0; i < isp->is_nzones; i++) { + if (isp->is_zoneids[i] == z) { + *icpp = &isp->is_configs[i]; + return (0); + } + } + + return (ipd_set_errno(EIPD_ZC_NOENT, + "zone %d does not exist or has no ipd configuration", z)); +} + +void +ipd_status_free(ipd_stathdl_t hdl) +{ + struct ipd_stat *isp = hdl; + + if (isp != NULL) { + free(isp->is_zoneids); + free(isp->is_configs); + } + free(isp); +} + +int +ipd_ctl(int fd, zoneid_t z, const ipd_config_t *icp) +{ + ipd_ioc_perturb_t ipip; + + bzero(&ipip, sizeof (ipd_ioc_perturb_t)); + ipip.ipip_zoneid = z; + + if (icp->ic_mask & IPDM_CORRUPT) { + if (icp->ic_corrupt == 0) + ipip.ipip_arg |= IPD_CORRUPT; + } + if (icp->ic_mask & IPDM_DELAY) { + if (icp->ic_delay == 0) + ipip.ipip_arg |= IPD_DELAY; + } + if (icp->ic_mask & IPDM_DROP) { + if (icp->ic_drop == 0) + ipip.ipip_arg |= IPD_DROP; + } + + if (ipip.ipip_arg != 0 && ioctl(fd, IPDIOC_REMOVE, &ipip) != 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to remove cleared ipd settings: %s", + strerror(errno))); + } + + if ((icp->ic_mask & IPDM_CORRUPT) && icp->ic_corrupt != 0) { + ipip.ipip_zoneid = z; + ipip.ipip_arg = icp->ic_corrupt; + if (ioctl(fd, IPDIOC_CORRUPT, &ipip) != 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to set corruption rate to %d: %s", + ipip.ipip_arg, strerror(errno))); + } + } + if ((icp->ic_mask & IPDM_DELAY) && icp->ic_delay != 0) { + ipip.ipip_zoneid = z; + ipip.ipip_arg = icp->ic_delay; + if (ioctl(fd, IPDIOC_DELAY, &ipip) != 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to set delay time to %d: %s", + ipip.ipip_arg, strerror(errno))); + } + } + if ((icp->ic_mask & IPDM_DROP) && icp->ic_drop != 0) { + ipip.ipip_zoneid = z; + ipip.ipip_arg = icp->ic_drop; + if (ioctl(fd, IPDIOC_DROP, &ipip) != 0) { + return (ipd_set_errno(xlate_errno(errno), + "unable to set drop probability to %d: %s", + ipip.ipip_arg, strerror(errno))); + } + } + + return (0); +} diff --git a/usr/src/lib/libipd/common/libipd.h b/usr/src/lib/libipd/common/libipd.h new file mode 100644 index 0000000000..ebf56aea1e --- /dev/null +++ b/usr/src/lib/libipd/common/libipd.h @@ -0,0 +1,74 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _LIBIPD_H +#define _LIBIPD_H + +#include <sys/types.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Bitmask values for ic_mask. + */ +#define IPDM_CORRUPT 0x1000 +#define IPDM_DELAY 0x2000 +#define IPDM_DROP 0x4000 + +typedef enum ipd_errno { + EIPD_NOERROR = 0, + EIPD_NOMEM, + EIPD_ZC_NOENT, + EIPD_RANGE, + EIPD_PERM, + EIPD_FAULT, + EIPD_INTERNAL, + EIPD_UNKNOWN +} ipd_errno_t; + +typedef struct ipd_config { + uint32_t ic_mask; + uint32_t ic_corrupt; + uint32_t ic_drop; + uint32_t ic_delay; +} ipd_config_t; + +struct ipd_stat; +typedef struct ipd_stat *ipd_stathdl_t; + +typedef void (*ipd_status_cb_f)(zoneid_t, const ipd_config_t *, void *); + +extern __thread ipd_errno_t ipd_errno; +extern __thread char ipd_errmsg[]; + +extern const char *ipd_strerror(ipd_errno_t); +extern int ipd_open(const char *); +extern int ipd_close(int); +extern int ipd_status_read(int, ipd_stathdl_t *); +extern void ipd_status_foreach_zone(const ipd_stathdl_t, + ipd_status_cb_f, void *); +extern int ipd_status_get_config(const ipd_stathdl_t, + zoneid_t, ipd_config_t **); +extern void ipd_status_free(ipd_stathdl_t); +extern int ipd_ctl(int, zoneid_t, const ipd_config_t *); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBIPD_H */ diff --git a/usr/src/lib/libipd/common/llib-lipd b/usr/src/lib/libipd/common/llib-lipd new file mode 100644 index 0000000000..79a3521301 --- /dev/null +++ b/usr/src/lib/libipd/common/llib-lipd @@ -0,0 +1,20 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* LINTLIBRARY */ +/* PROTOLIB1 */ + +#include <libipd.h> diff --git a/usr/src/lib/libipd/common/mapfile-vers b/usr/src/lib/libipd/common/mapfile-vers new file mode 100644 index 0000000000..fec8c56859 --- /dev/null +++ b/usr/src/lib/libipd/common/mapfile-vers @@ -0,0 +1,46 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2011 <contributor>. All rights reserved. +# + +# +# MAPFILE HEADER START +# +# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. +# Object versioning must comply with the rules detailed in +# +# usr/src/lib/README.mapfiles +# +# You should not be making modifications here until you've read the most current +# copy of that file. If you need help, contact a gatekeeper for guidance. +# +# MAPFILE HEADER END +# + +$mapfile_version 2 + +SYMBOL_VERSION SUNWprivate_1.1 { + global: + ipd_errno; + ipd_errmsg; + ipd_strerror; + ipd_open; + ipd_close; + ipd_status_read; + ipd_status_foreach_zone; + ipd_status_get_config; + ipd_status_free; + ipd_ctl; + local: + *; +}; diff --git a/usr/src/lib/libipd/i386/Makefile b/usr/src/lib/libipd/i386/Makefile new file mode 100644 index 0000000000..6a668fb98f --- /dev/null +++ b/usr/src/lib/libipd/i386/Makefile @@ -0,0 +1,18 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2012 Joyent, Inc. All rights reserved. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libkmf/ber_der/Makefile.com b/usr/src/lib/libkmf/ber_der/Makefile.com index e056b6cfa7..6654e7cfde 100644 --- a/usr/src/lib/libkmf/ber_der/Makefile.com +++ b/usr/src/lib/libkmf/ber_der/Makefile.com @@ -43,8 +43,10 @@ $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) CFLAGS += $(CCVERBOSE) -xCC CFLAGS64 += $(CCVERBOSE) -xCC -CPPFLAGS += -I/usr/include/libxml2 -I$(INCDIR) -I../../include -CPPFLAGS64 += -I/usr/include/libxml2 -I$(INCDIR) -I../../include +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/libxml2 \ + -I$(INCDIR) -I../../include +CPPFLAGS64 += -I$(ADJUNCT_PROTO)/usr/include/libxml2 \ + -I$(INCDIR) -I../../include LDLIBS += -lc CERRWARN += -_gcc=-Wno-unused-label diff --git a/usr/src/lib/libkmf/libkmf/Makefile.com b/usr/src/lib/libkmf/libkmf/Makefile.com index 4091ae09c1..a704d1e5a8 100644 --- a/usr/src/lib/libkmf/libkmf/Makefile.com +++ b/usr/src/lib/libkmf/libkmf/Makefile.com @@ -63,7 +63,8 @@ LDLIBS6 += $(BERDERLIB64) $(CRYPTOUTILLIB64) -lmd -lpkcs11 -lnsl -lsocket -lc $(DYNLIB) := LDLIBS += -lxml2 $(DYNLIB64) := LDLIBS64 += -lxml2 -CPPFLAGS += -I$(INCDIR) -I/usr/include/libxml2 -I../../ber_der/inc -I$(SRCDIR) +CPPFLAGS += -I$(INCDIR) -I$(ADJUNCT_PROTO)/usr/include/libxml2 \ + -I../../ber_der/inc -I$(SRCDIR) CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-switch diff --git a/usr/src/lib/libkmf/plugins/kmf_nss/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_nss/Makefile.com index a3ab702811..3b5f23aa92 100644 --- a/usr/src/lib/libkmf/plugins/kmf_nss/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_nss/Makefile.com @@ -34,19 +34,21 @@ include $(SRC)/lib/Makefile.lib MPSDIR= /usr/lib/mps KMFINC= -I../../../include -I../../../ber_der/inc -NSSINC= -I/usr/include/mps +NSSINC= -I$(ADJUNCT_PROTO)/usr/include/mps BERLIB= -lkmf -lkmfberder BERLIB64= $(BERLIB) -NSSLIBS= $(BERLIB) -L$(MPSDIR) -R$(MPSDIR) -lnss3 -lnspr4 -lsmime3 -lc -NSSLIBS64= $(BERLIB64) -L$(MPSDIR)/$(MACH64) -R$(MPSDIR)/$(MACH64) -lnss3 -lnspr4 -lsmime3 -lc +NSSLIBS= $(BERLIB) -L$(ADJUNCT_PROTO)$(MPSDIR) -R$(MPSDIR) \ + -lnss3 -lnspr4 -lsmime3 -lc +NSSLIBS64= $(BERLIB64) -L$(ADJUNCT_PROTO)$(MPSDIR)/$(MACH64) \ + -R$(MPSDIR)/$(MACH64) -lnss3 -lnspr4 -lsmime3 -lc SRCDIR= ../common INCDIR= ../../include CFLAGS += $(CCVERBOSE) CPPFLAGS += -D_REENTRANT $(KMFINC) $(NSSINC) \ - -I$(SFWDIR)/include -I$(INCDIR) -I/usr/include/libxml2 + -I$(INCDIR) -I$(ADJUNCT_PROTO)/usr/include/libxml2 PICS= $(OBJECTS:%=pics/%) diff --git a/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com index e44eb0a87c..76ecd38479 100644 --- a/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_openssl/Makefile.com @@ -48,7 +48,7 @@ INCDIR= ../../include CFLAGS += $(CCVERBOSE) CPPFLAGS += -D_REENTRANT $(KMFINC) \ - -I$(INCDIR) -I/usr/include/libxml2 + -I$(INCDIR) -I$(ADJUNCT_PROTO)/usr/include/libxml2 CERRWARN += -_gcc=-Wno-unused-label CERRWARN += -_gcc=-Wno-unused-value diff --git a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com index ae97ef8e8f..0b69e23fd6 100644 --- a/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com +++ b/usr/src/lib/libkmf/plugins/kmf_pkcs11/Makefile.com @@ -49,7 +49,8 @@ SRCS = \ CFLAGS += $(CCVERBOSE) -CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) -I/usr/include/libxml2 -I$(BIGNUMDIR) +CPPFLAGS += -D_REENTRANT $(KMFINC) -I$(INCDIR) \ + -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I$(BIGNUMDIR) LINTFLAGS64 += -errchk=longptr64 CERRWARN += -_gcc=-Wno-unused-label diff --git a/usr/src/lib/libldap5/Makefile.com b/usr/src/lib/libldap5/Makefile.com index 9c28fae337..ee48739eea 100644 --- a/usr/src/lib/libldap5/Makefile.com +++ b/usr/src/lib/libldap5/Makefile.com @@ -57,7 +57,7 @@ OBJECTS= $(BEROBJS) $(LDAPOBJS) $(SSLDAPOBJS) $(PRLDAPOBJS) \ include ../../Makefile.lib NSS_LIBS= -lnspr4 -lplc4 -lnss3 -lssl3 -NSS_HDRS= /usr/include/mps +NSS_HDRS= $(ADJUNCT_PROTO)/usr/include/mps NSS_LDPATH= /usr/lib/mps NSS_LDPATH64= $(NSS_LDPATH)/64 diff --git a/usr/src/lib/libldap5/amd64/Makefile b/usr/src/lib/libldap5/amd64/Makefile index 680f2fb7c6..abf5a7d5f8 100644 --- a/usr/src/lib/libldap5/amd64/Makefile +++ b/usr/src/lib/libldap5/amd64/Makefile @@ -10,7 +10,7 @@ PR_MDUSOBJS = os_SunOS_x86.o include ../Makefile.com include ../../Makefile.lib.64 -LDLIBS += -L$(NSS_LDPATH64) $(NSS_LIBS) +LDLIBS += -L$(ADJUNCT_PROTO)$(NSS_LDPATH64) $(NSS_LIBS) DYNFLAGS += -R$(NSS_LDPATH64) all: $(LIBS) diff --git a/usr/src/lib/libldap5/i386/Makefile b/usr/src/lib/libldap5/i386/Makefile index d0eba36ca2..b9e154c6fc 100644 --- a/usr/src/lib/libldap5/i386/Makefile +++ b/usr/src/lib/libldap5/i386/Makefile @@ -11,7 +11,7 @@ PR_MDUSOBJS = os_SunOS_x86.o include ../Makefile.com -LDLIBS += -L$(NSS_LDPATH) $(NSS_LIBS) +LDLIBS += -L$(ADJUNCT_PROTO)$(NSS_LDPATH) $(NSS_LIBS) DYNFLAGS += -R$(NSS_LDPATH) all: $(LIBS) diff --git a/usr/src/lib/libldap5/sparc/Makefile b/usr/src/lib/libldap5/sparc/Makefile index e5e0562484..dcfe21adce 100644 --- a/usr/src/lib/libldap5/sparc/Makefile +++ b/usr/src/lib/libldap5/sparc/Makefile @@ -11,7 +11,7 @@ PR_MDUSOBJS = os_SunOS.o include ../Makefile.com -LDLIBS += -L$(NSS_LDPATH) $(NSS_LIBS) +LDLIBS += -L$(ADJUNCT_PROTO)$(NSS_LDPATH) $(NSS_LIBS) DYNFLAGS += -R$(NSS_LDPATH) diff --git a/usr/src/lib/libldap5/sparcv9/Makefile b/usr/src/lib/libldap5/sparcv9/Makefile index e1ac900b72..b3b78410e5 100644 --- a/usr/src/lib/libldap5/sparcv9/Makefile +++ b/usr/src/lib/libldap5/sparcv9/Makefile @@ -12,7 +12,7 @@ PR_MDUSOBJS = os_SunOS.o include ../Makefile.com include ../../Makefile.lib.64 -LDLIBS += -L$(NSS_LDPATH64) $(NSS_LIBS) +LDLIBS += -L$(ADJUNCT_PROTO)$(NSS_LDPATH64) $(NSS_LIBS) DYNFLAGS += -R$(NSS_LDPATH64) all: $(LIBS) diff --git a/usr/src/lib/libnisdb/db_mindex3.cc b/usr/src/lib/libnisdb/db_mindex3.cc index 886487f8c5..28182544a4 100644 --- a/usr/src/lib/libnisdb/db_mindex3.cc +++ b/usr/src/lib/libnisdb/db_mindex3.cc @@ -282,7 +282,7 @@ entriesFromLDAPthread(void *voidarg) { /* Lock to prevent removal */ (void) __nis_lock_db_table(arg->tableName, 1, 0, - "entriesFromLDAPthread"); + (char *)"entriesFromLDAPthread"); /* * It's possible that the db_mindex for the table has changed, @@ -314,7 +314,7 @@ entriesFromLDAPthread(void *voidarg) { stat = entriesFromLDAPreal(arg); (void) __nis_ulock_db_table(arg->tableName, 1, 0, - "entriesFromLDAPthread"); + (char *)"entriesFromLDAPthread"); freeQuery(arg->q); if (arg->dirObj != 0) diff --git a/usr/src/lib/libnisdb/db_table.cc b/usr/src/lib/libnisdb/db_table.cc index 2995f1a9c9..8044148355 100644 --- a/usr/src/lib/libnisdb/db_table.cc +++ b/usr/src/lib/libnisdb/db_table.cc @@ -599,7 +599,7 @@ db_table::setEntryExp(entryp where, entry_obj *obj, int initialLoad) { if (o != 0) { __nis_buffer_t b = {0, 0}; - bp2buf(myself, &b, "%s.%s", + bp2buf(myself, &b, (char *)"%s.%s", o->zo_name, o->zo_domain); t = getObjMapping(b.buf, 0, 1, 0, 0); sfree(b.buf); @@ -967,7 +967,7 @@ db_table::setEnumMode(long enumNum) { if (stat != DB_SUCCESS) { enumMode.flag = 0; enumCount.flag = 0; - logmsg(MSG_NOTIMECHECK, LOG_ERR, + logmsg(MSG_NOTIMECHECK, LOG_ERR, (char *) "%s: No memory for enum check array; entry removal disabled", myself); } diff --git a/usr/src/lib/libnisdb/nis_db.cc b/usr/src/lib/libnisdb/nis_db.cc index 2908cc99b0..b27889b147 100644 --- a/usr/src/lib/libnisdb/nis_db.cc +++ b/usr/src/lib/libnisdb/nis_db.cc @@ -527,7 +527,7 @@ dbFindObject(char *objName, db_status *statP) { /* If not the root dir, find the directory where the entry lives */ sfree(table); - name = entryName(myself, objName, &table); + name = entryName((char *)myself, objName, &table); if (name == 0 || table == 0) { sfree(name); RETSTAT(0, DB_MEMORY_LIMIT); @@ -737,7 +737,7 @@ dbDeleteObj(char *objName) { nod->objType = o->zo_data.zo_type; nis_destroy_object(o); - nod->objName = sdup(myself, T, objName); + nod->objName = sdup((char *)myself, T, objName); if (nod->objName == 0) { sfree(nod); return (DB_MEMORY_LIMIT); @@ -789,7 +789,7 @@ dbTouchObj(char *objName) { sfree(table); table = 0; - ent = entryName(myself, objName, &table); + ent = entryName((char *)myself, objName, &table); if (ent == 0 || table == 0) { sfree(ent); return (DB_MEMORY_LIMIT); @@ -989,7 +989,7 @@ dbRefreshObj(char *name, nis_object *o) { int lstat; /* Find parent */ - ent = entryName(myself, objName, &table); + ent = entryName((char *)myself, objName, &table); if (ent == 0 || table == 0) { sfree(b.buf); sfree(objTable); diff --git a/usr/src/lib/libnvpair/Makefile.com b/usr/src/lib/libnvpair/Makefile.com index 6a21376eb3..056d967554 100644 --- a/usr/src/lib/libnvpair/Makefile.com +++ b/usr/src/lib/libnvpair/Makefile.com @@ -23,6 +23,7 @@ # Use is subject to license terms. # # Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. # LIBRARY= libnvpair.a @@ -32,13 +33,15 @@ OBJECTS= libnvpair.o \ nvpair_alloc_system.o \ nvpair_alloc_fixed.o \ nvpair.o \ - fnvpair.o + fnvpair.o \ + nvpair_json.o include ../../Makefile.lib include ../../Makefile.rootfs SRCS= ../libnvpair.c \ ../nvpair_alloc_system.c \ + ../nvpair_json.c \ $(SRC)/common/nvpair/nvpair_alloc_fixed.c \ $(SRC)/common/nvpair/nvpair.c \ $(SRC)/common/nvpair/fnvpair.c @@ -54,7 +57,13 @@ LINTFLAGS64 += -erroff=E_BAD_PTR_CAST_ALIGN # turn off warning caused by lint bug: not understanding SCNi8 "hhi" LINTFLAGS += -erroff=E_BAD_FORMAT_STR2 +LINTFLAGS += -erroff=E_INVALID_TOKEN_IN_DEFINE_MACRO +LINTFLAGS += -erroff=E_RET_INT_IMPLICITLY +LINTFLAGS += -erroff=E_FUNC_USED_VAR_ARG2 LINTFLAGS64 += -erroff=E_BAD_FORMAT_STR2 +LINTFLAGS64 += -erroff=E_INVALID_TOKEN_IN_DEFINE_MACRO +LINTFLAGS64 += -erroff=E_RET_INT_IMPLICITLY +LINTFLAGS64 += -erroff=E_FUNC_USED_VAR_ARG2 CERRWARN += -_gcc=-Wno-type-limits CERRWARN += -_gcc=-Wno-parentheses diff --git a/usr/src/lib/libnvpair/libnvpair.h b/usr/src/lib/libnvpair/libnvpair.h index 4c2615d924..b05669e506 100644 --- a/usr/src/lib/libnvpair/libnvpair.h +++ b/usr/src/lib/libnvpair/libnvpair.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #ifndef _LIBNVPAIR_H @@ -46,6 +47,7 @@ extern int nvpair_value_match_regex(nvpair_t *, int, char *, regex_t *, char **); extern void nvlist_print(FILE *, nvlist_t *); +extern int nvlist_print_json(FILE *, nvlist_t *); extern void dump_nvlist(nvlist_t *, int); /* diff --git a/usr/src/lib/libnvpair/mapfile-vers b/usr/src/lib/libnvpair/mapfile-vers index a014835447..0403964e05 100644 --- a/usr/src/lib/libnvpair/mapfile-vers +++ b/usr/src/lib/libnvpair/mapfile-vers @@ -21,6 +21,7 @@ # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright (c) 2013, Joyent, Inc. All rights reserved. # # @@ -244,6 +245,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { nvlist_add_hrtime; nvlist_lookup_hrtime; nvlist_print; + nvlist_print_json; nvlist_prt; nvlist_prtctl_alloc; nvlist_prtctl_free; diff --git a/usr/src/lib/libnvpair/nvpair_json.c b/usr/src/lib/libnvpair/nvpair_json.c new file mode 100644 index 0000000000..77348041ab --- /dev/null +++ b/usr/src/lib/libnvpair/nvpair_json.c @@ -0,0 +1,400 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <strings.h> +#include <wchar.h> +#include <sys/debug.h> + +#include "libnvpair.h" + +#define FPRINTF(fp, ...) \ + do { \ + if (fprintf(fp, __VA_ARGS__) < 0) \ + return (-1); \ + } while (0) + +/* + * When formatting a string for JSON output we must escape certain characters, + * as described in RFC4627. This applies to both member names and + * DATA_TYPE_STRING values. + * + * This function will only operate correctly if the following conditions are + * met: + * + * 1. The input String is encoded in the current locale. + * + * 2. The current locale includes the Basic Multilingual Plane (plane 0) + * as defined in the Unicode standard. + * + * The output will be entirely 7-bit ASCII (as a subset of UTF-8) with all + * representable Unicode characters included in their escaped numeric form. + */ +static int +nvlist_print_json_string(FILE *fp, const char *input) +{ + mbstate_t mbr; + wchar_t c; + size_t sz; + + bzero(&mbr, sizeof (mbr)); + + FPRINTF(fp, "\""); + while ((sz = mbrtowc(&c, input, MB_CUR_MAX, &mbr)) > 0) { + switch (c) { + case '"': + FPRINTF(fp, "\\\""); + break; + case '\n': + FPRINTF(fp, "\\n"); + break; + case '\r': + FPRINTF(fp, "\\r"); + break; + case '\\': + FPRINTF(fp, "\\\\"); + break; + case '\f': + FPRINTF(fp, "\\f"); + break; + case '\t': + FPRINTF(fp, "\\t"); + break; + case '\b': + FPRINTF(fp, "\\b"); + break; + default: + if ((c >= 0x00 && c <= 0x1f) || + (c > 0x7f && c <= 0xffff)) { + /* + * Render both Control Characters and Unicode + * characters in the Basic Multilingual Plane + * as JSON-escaped multibyte characters. + */ + FPRINTF(fp, "\\u%04x", 0xffff & c); + } else if (c >= 0x20 && c <= 0x7f) { + /* + * Render other 7-bit ASCII characters directly + * and drop other, unrepresentable characters. + */ + FPRINTF(fp, "%c", 0xff & c); + } + break; + } + input += sz; + } + + if (sz == (size_t)-1 || sz == (size_t)-2) { + /* + * We last read an invalid multibyte character sequence, + * so return an error. + */ + return (-1); + } + + FPRINTF(fp, "\""); + return (0); +} + +/* + * Dump a JSON-formatted representation of an nvlist to the provided FILE *. + * This routine does not output any new-lines or additional whitespace other + * than that contained in strings, nor does it call fflush(3C). + */ +int +nvlist_print_json(FILE *fp, nvlist_t *nvl) +{ + nvpair_t *curr; + boolean_t first = B_TRUE; + + FPRINTF(fp, "{"); + + for (curr = nvlist_next_nvpair(nvl, NULL); curr; + curr = nvlist_next_nvpair(nvl, curr)) { + data_type_t type = nvpair_type(curr); + + if (!first) + FPRINTF(fp, ","); + else + first = B_FALSE; + + if (nvlist_print_json_string(fp, nvpair_name(curr)) == -1) + return (-1); + FPRINTF(fp, ":"); + + switch (type) { + case DATA_TYPE_STRING: { + char *string = fnvpair_value_string(curr); + if (nvlist_print_json_string(fp, string) == -1) + return (-1); + break; + } + + case DATA_TYPE_BOOLEAN: { + FPRINTF(fp, "true"); + break; + } + + case DATA_TYPE_BOOLEAN_VALUE: { + FPRINTF(fp, "%s", fnvpair_value_boolean_value(curr) == + B_TRUE ? "true" : "false"); + break; + } + + case DATA_TYPE_BYTE: { + FPRINTF(fp, "%hhu", fnvpair_value_byte(curr)); + break; + } + + case DATA_TYPE_INT8: { + FPRINTF(fp, "%hhd", fnvpair_value_int8(curr)); + break; + } + + case DATA_TYPE_UINT8: { + FPRINTF(fp, "%hhu", fnvpair_value_uint8_t(curr)); + break; + } + + case DATA_TYPE_INT16: { + FPRINTF(fp, "%hd", fnvpair_value_int16(curr)); + break; + } + + case DATA_TYPE_UINT16: { + FPRINTF(fp, "%hu", fnvpair_value_uint16(curr)); + break; + } + + case DATA_TYPE_INT32: { + FPRINTF(fp, "%d", fnvpair_value_int32(curr)); + break; + } + + case DATA_TYPE_UINT32: { + FPRINTF(fp, "%u", fnvpair_value_uint32(curr)); + break; + } + + case DATA_TYPE_INT64: { + FPRINTF(fp, "%lld", fnvpair_value_int64(curr)); + break; + } + + case DATA_TYPE_UINT64: { + FPRINTF(fp, "%llu", fnvpair_value_uint64(curr)); + break; + } + + case DATA_TYPE_HRTIME: { + hrtime_t val; + VERIFY0(nvpair_value_hrtime(curr, &val)); + FPRINTF(fp, "%llu", val); + break; + } + + case DATA_TYPE_DOUBLE: { + double val; + VERIFY0(nvpair_value_double(curr, &val)); + FPRINTF(fp, "%f", val); + break; + } + + case DATA_TYPE_NVLIST: { + if (nvlist_print_json(fp, + fnvpair_value_nvlist(curr)) == -1) + return (-1); + break; + } + + case DATA_TYPE_STRING_ARRAY: { + char **val; + uint_t valsz, i; + VERIFY0(nvpair_value_string_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + if (nvlist_print_json_string(fp, val[i]) == -1) + return (-1); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_NVLIST_ARRAY: { + nvlist_t **val; + uint_t valsz, i; + VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + if (nvlist_print_json(fp, val[i]) == -1) + return (-1); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_BOOLEAN_ARRAY: { + boolean_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, val[i] == B_TRUE ? + "true" : "false"); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_BYTE_ARRAY: { + uchar_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_byte_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%hhu", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_UINT8_ARRAY: { + uint8_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%hhu", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_INT8_ARRAY: { + int8_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_int8_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%hd", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_UINT16_ARRAY: { + uint16_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%hu", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_INT16_ARRAY: { + int16_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_int16_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%hhd", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_UINT32_ARRAY: { + uint32_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%u", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_INT32_ARRAY: { + int32_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_int32_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%d", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_UINT64_ARRAY: { + uint64_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%llu", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_INT64_ARRAY: { + int64_t *val; + uint_t valsz, i; + VERIFY0(nvpair_value_int64_array(curr, &val, &valsz)); + FPRINTF(fp, "["); + for (i = 0; i < valsz; i++) { + if (i > 0) + FPRINTF(fp, ","); + FPRINTF(fp, "%lld", val[i]); + } + FPRINTF(fp, "]"); + break; + } + + case DATA_TYPE_UNKNOWN: + return (-1); + } + } + + FPRINTF(fp, "}"); + return (0); +} diff --git a/usr/src/lib/libpool/Makefile.com b/usr/src/lib/libpool/Makefile.com index 493e442d0d..13b8a05cc1 100644 --- a/usr/src/lib/libpool/Makefile.com +++ b/usr/src/lib/libpool/Makefile.com @@ -48,7 +48,8 @@ SRCDIR = ../common $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) CFLAGS += $(CCVERBOSE) -CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 -I/usr/include/libxml2 +CPPFLAGS += -D_REENTRANT -D_FILE_OFFSET_BITS=64 \ + -I$(ADJUNCT_PROTO)/usr/include/libxml2 CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-switch diff --git a/usr/src/lib/libproc/common/Pzone.c b/usr/src/lib/libproc/common/Pzone.c index c478b41624..31319674b2 100644 --- a/usr/src/lib/libproc/common/Pzone.c +++ b/usr/src/lib/libproc/common/Pzone.c @@ -24,6 +24,9 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + */ #include <assert.h> #include <dlfcn.h> #include <errno.h> @@ -792,9 +795,10 @@ Pfindmap(struct ps_prochandle *P, map_info_t *mptr, char *s, size_t n) (strcmp(mptr->map_pmap.pr_mapname, "a.out") == 0) || ((fptr != NULL) && (fptr->file_lname != NULL) && (strcmp(fptr->file_lname, "a.out") == 0))) { - (void) Pexecname(P, buf, sizeof (buf)); - (void) strlcpy(s, buf, n); - return (s); + if (Pexecname(P, buf, sizeof (buf)) != NULL) { + (void) strlcpy(s, buf, n); + return (s); + } } /* Try /proc first to get the real object name */ diff --git a/usr/src/lib/libproject/common/setproject.c b/usr/src/lib/libproject/common/setproject.c index e24a8b78c6..ef208845a1 100644 --- a/usr/src/lib/libproject/common/setproject.c +++ b/usr/src/lib/libproject/common/setproject.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ @@ -199,9 +200,7 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr, int flags) int count = 0; char *tmp; int local_act; - rctlblk_t *rlast; rctlblk_t *rnext; - rctlblk_t *rtmp; int teardown_basic = 0; int teardown_priv = 0; @@ -358,44 +357,35 @@ rctl_set(char *ctl_name, char *val, struct ps_prochandle *Pr, int flags) /* teardown rctls if required */ if (!project_entity) { - if ((rlast = (rctlblk_t *)malloc(rctlblk_size())) == NULL) { - free(ablk); - return (SETFAILED); - } if ((rnext = (rctlblk_t *)malloc(rctlblk_size())) == NULL) { free(ablk); - free(rlast); return (SETFAILED); } +restart: if (pr_getrctl(Pr, ctl_name, NULL, rnext, RCTL_FIRST) == 0) { - while (1) { if ((rctlblk_get_privilege(rnext) == RCPRIV_PRIVILEGED) && (teardown_priv == 1)) { (void) pr_setrctl(Pr, ctl_name, NULL, rnext, RCTL_DELETE); + goto restart; } if ((rctlblk_get_privilege(rnext) == RCPRIV_BASIC) && (teardown_basic == 1)) { (void) pr_setrctl(Pr, ctl_name, NULL, rnext, RCTL_DELETE); + goto restart; } - rtmp = rnext; - rnext = rlast; - rlast = rtmp; - if (pr_getrctl(Pr, ctl_name, rlast, rnext, + if (pr_getrctl(Pr, ctl_name, rnext, rnext, RCTL_NEXT) == -1) break; } - } free(rnext); - free(rlast); - } /* set rctls */ diff --git a/usr/src/lib/libscf/inc/libscf.h b/usr/src/lib/libscf/inc/libscf.h index 8e68b4dfcc..232fc205e0 100644 --- a/usr/src/lib/libscf/inc/libscf.h +++ b/usr/src/lib/libscf/inc/libscf.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #ifndef _LIBSCF_H @@ -831,8 +832,13 @@ int smf_notify_del_params(const char *, const char *, int32_t); /* * SMF exit status definitions + * + * The SMF_EXIT_NODAEMON exit status should be used when a method does not + * need to run any persistent process. This indicates success, abandons the + * contract, and allows dependencies to be met. */ #define SMF_EXIT_OK 0 +#define SMF_EXIT_NODAEMON 94 #define SMF_EXIT_ERR_FATAL 95 #define SMF_EXIT_ERR_CONFIG 96 #define SMF_EXIT_MON_DEGRADE 97 diff --git a/usr/src/lib/libshare/Makefile.com b/usr/src/lib/libshare/Makefile.com index 7e3c902a5e..b5f057d694 100644 --- a/usr/src/lib/libshare/Makefile.com +++ b/usr/src/lib/libshare/Makefile.com @@ -42,6 +42,8 @@ $(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) #add nfs/lib directory as part of the include path CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(NFSLIB_DIR) \ + -I$(ADJUNCT_PROTO)/usr/include/libxml2 CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-uninitialized CERRWARN += -_gcc=-Wno-switch diff --git a/usr/src/lib/libshare/autofs/Makefile.com b/usr/src/lib/libshare/autofs/Makefile.com index 41c7dfd334..0538ec55fa 100644 --- a/usr/src/lib/libshare/autofs/Makefile.com +++ b/usr/src/lib/libshare/autofs/Makefile.com @@ -46,6 +46,8 @@ LDLIBS += -lshare -lscf -lumem -lc -lxml2 #add nfs/lib directory as part of the include path CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(AUTOFSSMFLIB_DIR) \ + -I$(ADJUNCT_PROTO)/usr/include/libxml2 CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-unused-variable CERRWARN += -_gcc=-Wno-uninitialized diff --git a/usr/src/lib/libshare/nfs/Makefile.com b/usr/src/lib/libshare/nfs/Makefile.com index d393c5f8ba..44e661bbe2 100644 --- a/usr/src/lib/libshare/nfs/Makefile.com +++ b/usr/src/lib/libshare/nfs/Makefile.com @@ -46,6 +46,8 @@ LDLIBS += -lshare -lnsl -lscf -lumem -lc -lxml2 #add nfs/lib directory as part of the include path CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(NFSLIB_DIR) \ + -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I$(SRCDIR)/../common CERRWARN += -_gcc=-Wno-parentheses CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-unused-variable diff --git a/usr/src/lib/libshare/nfs/libshare_nfs.c b/usr/src/lib/libshare/nfs/libshare_nfs.c index 37ea8cdf3d..0cf69a241a 100644 --- a/usr/src/lib/libshare/nfs/libshare_nfs.c +++ b/usr/src/lib/libshare/nfs/libshare_nfs.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. @@ -2663,9 +2664,16 @@ nfs_init() ret = initprotofromsmf(); if (ret != SA_OK) { - (void) printf(dgettext(TEXT_DOMAIN, - "NFS plugin problem with SMF repository: %s\n"), - sa_errorstr(ret)); + /* + * This is a workaround. See the comment in + * cmd/fs.d/nfs/lib/smfcfg.c for an explanation. + */ + if (getzoneid() == GLOBAL_ZONEID || + ret != SCF_ERROR_NOT_FOUND) { + (void) printf(dgettext(TEXT_DOMAIN, + "NFS plugin problem with SMF repository: %s\n"), + sa_errorstr(ret)); + } ret = SA_OK; } add_defaults(); diff --git a/usr/src/lib/libshare/smb/Makefile.com b/usr/src/lib/libshare/smb/Makefile.com index 6b3d821684..3fe65dff3c 100644 --- a/usr/src/lib/libshare/smb/Makefile.com +++ b/usr/src/lib/libshare/smb/Makefile.com @@ -49,6 +49,7 @@ LDLIBS += -lshare -ldlpi -lnsl -lnvpair -lscf -lumem -lc all install := LDLIBS += -lxml2 CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(ADJUNCT_PROTO)/usr/include/libxml2 CERRWARN += -_gcc=-Wno-char-subscripts CERRWARN += -_gcc=-Wno-switch CPPFLAGS += -D_REENTRANT -I/usr/include/libxml2 \ diff --git a/usr/src/lib/libshare/smbfs/Makefile.com b/usr/src/lib/libshare/smbfs/Makefile.com index c4b7b48117..fbd4b80000 100644 --- a/usr/src/lib/libshare/smbfs/Makefile.com +++ b/usr/src/lib/libshare/smbfs/Makefile.com @@ -41,6 +41,8 @@ LIBS = $(DYNLIB) LDLIBS += -lshare -lscf -lumem -luuid -lc -lxml2 -lsmbfs CFLAGS += $(CCVERBOSE) +CPPFLAGS += -D_REENTRANT -I$(ADJUNCT_PROTO)/usr/include/libxml2 \ + -I$(SRCDIR)/../common -I$(SRC)/lib/libsmbfs -I$(SRC)/uts/common CERRWARN += -_gcc=-Wno-switch CERRWARN += -_gcc=-Wno-uninitialized CPPFLAGS += -D_REENTRANT -I/usr/include/libxml2 -I$(SRCDIR)/../common \ diff --git a/usr/src/lib/libshell/Makefile b/usr/src/lib/libshell/Makefile index b584728d5f..1cce2316f0 100644 --- a/usr/src/lib/libshell/Makefile +++ b/usr/src/lib/libshell/Makefile @@ -64,6 +64,5 @@ $(SUBDIRS): FRC FRC: include Makefile.demo -include Makefile.doc include ../Makefile.targ diff --git a/usr/src/lib/libshell/Makefile.doc b/usr/src/lib/libshell/Makefile.doc deleted file mode 100644 index 07118f7459..0000000000 --- a/usr/src/lib/libshell/Makefile.doc +++ /dev/null @@ -1,91 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -ROOTDOCDIRBASE= $(ROOT)/usr/share/doc/ksh - -DOCFILES= \ - RELEASE \ - README \ - TYPES \ - DESIGN \ - COMPATIBILITY \ - OBSOLETE \ - shell_styleguide.docbook \ - shell_styleguide.html \ - images/tag_bourne.png \ - images/tag_i18n.png \ - images/tag_ksh88.png \ - images/tag_ksh93.png \ - images/tag_ksh.png \ - images/tag_l10n.png \ - images/tag_perf.png \ - images/callouts/1.png \ - images/callouts/2.png \ - images/callouts/3.png \ - images/callouts/4.png \ - images/callouts/5.png \ - images/callouts/6.png \ - images/callouts/7.png \ - images/callouts/8.png \ - images/callouts/9.png \ - images/callouts/10.png - -# Documentation rules -$(ROOTDOCDIRBASE)/%: common/% - $(INS.file) - -$(ROOTDOCDIRBASE)/%: misc/% - $(INS.file) - -ROOTDOCDIRS= \ - $(ROOTDOCDIRBASE) .WAIT \ - $(ROOTDOCDIRBASE)/images .WAIT \ - $(ROOTDOCDIRBASE)/images/callouts - -$(ROOTDOCDIRBASE)/%.html: misc/%.docbook - /usr/bin/xsltproc \ - --nonet \ - --stringparam generate.section.toc.level 0 \ - --stringparam toc.max.depth 3 \ - --stringparam toc.section.depth 12 \ - --xinclude \ - -o "$(@F)" \ - $(DOCBOOK_XSL_ROOT)/html/docbook.xsl \ - "$<" >xsltproc.log 2>&1 - $(INS) -s -m $(FILEMODE) -f "$(@D)" "$(@F)" - $(RM) "$(@F)" - -# Generic documentation rules -DOCFILESRCDIR= common -ROOTDOCFILES= $(DOCFILES:%=$(ROOTDOCDIRBASE)/%) -$(ROOTDOCDIRS) := OWNER = root -$(ROOTDOCDIRS) := GROUP = bin -$(ROOTDOCDIRS) := DIRMODE = 755 - -$(ROOTDOCDIRS): - $(INS.dir) - -install: $(ROOTDOCDIRS) .WAIT $(ROOTDOCFILES) diff --git a/usr/src/lib/libshell/common/COMPATIBILITY b/usr/src/lib/libshell/common/COMPATIBILITY deleted file mode 100644 index d4d645a99a..0000000000 --- a/usr/src/lib/libshell/common/COMPATIBILITY +++ /dev/null @@ -1,134 +0,0 @@ - - KSH-93 VS. KSH-88 - - -The following is a list of known incompatibilities between ksh-93 and ksh-88. -I have not include cases that are clearly bugs in ksh-88. I also have -omitted features that are completely upward compatible. - -1. Functions, defined with name() with ksh-93 are compatible with - the POSIX standard, not with ksh-88. No local variables are - permitted, and there is no separate scope. Functions defined - with the function name syntax, maintain compatibility. - This also affects function traces. - -2. ! is now a reserved word. As a result, any command by that - name will no longer work with ksh-93. - -3. The -x attribute of alias and typeset -f is no longer - effective and the ENV file is only read for interactive - shells. You need to use FPATH to make function definitions - visible to scripts. - -4. A built-in command named command has been added which is - always found before the PATH search. Any script which uses - this name as the name of a command (or function) will not - be compatible. - -5. The output format for some built-ins has changed. In particular - the output format for set, typeset and alias now have single - quotes around values that have special characters. The output - for trap without arguments has a format that can be used as input. - -6. With ksh-88, a dollar sign ($') followed by a single quote was - interpreted literally. Now it is an ANSI-C string. You - must quote the dollar sign to get the previous behavior. - Also, a $ in front of a " indicates that the string needs - to be translated for locales other than C or POSIX. The $ - is ignored in the C and POSIX locale. - -7. With ksh-88, tilde expansion did not take place inside ${...}. - with ksh-93, ${foo-~} will cause tilde expansion if foo is - not set. You need to escape the ~ for the previous behavior. - -8. Some changes in the tokenizing rules where made that might - cause some scripts with previously ambiguous use of quoting - to produce syntax errors. - -9. Programs that rely on specific exit values for the shell, - (rather than 0 or non-zero) may not be compatible. The - exit status for many shell failures has been changed. - -10. Built-ins in ksh-88 were always executed before looking for - the command in the PATH variable. This is no longer true. - Thus, with ksh-93, if you have the current directory first - in your PATH, and you have a program named test in your - directory, it will be executed when you type test; the - built-in version will be run at the point /bin is found - in your PATH. - -11. Some undocumented combinations of argument passing to ksh - builtins no longer works since ksh-93 is getopts conforming - with respect to its built-ins. For example, typeset -8i - previously would work as a synonym for typeset -i8. - -12. Command substitution and arithmetic expansion are now performed - on PS1, PS3, and ENV when they are expanded. Thus, ` and $( - as part of the value of these variables must be preceded by a \ - to preserve their previous behavior. - -13. The ERRNO variable has been dropped. - -14. If the file name following a redirection symbol contain pattern - characters they will only be expanded for interactive shells. - -15. The arguments to a dot script will be restored when it completes. - -16. The list of tracked aliases is not displayed with alias unless - the -t option is specified. - -17. The POSIX standard requires that test "$arg" have exit status - of 0, if and only if $arg is null. However, since this breaks - programs that use test -t, ksh93 treats an explicit test -t - as if the user had entered test -t 1. - -18. The ^T directive of emacs mode has been changed to work the - way it does in gnu-emacs. - -19. ksh-88 allowed unbalanced parenthes within ${name op val} whereas - ksh-93 does not. Thus, ${foo-(} needs to be written as ${foo-\(} - which works with both versions. - -20. kill -l in ksh-93 lists only the signal names, not their numerical - values. - -21. Local variables defined by typeset are statically scoped in - ksh93. In ksh88 they were dynamically scoped although this - behavior was never documented. - -22. The value of the variable given to getopts is set to ? when - the end-of-options is reached to conform to the POSIX standard. - -23. Since the POSIX standard requires that octal constants be - recongnized, doing arithmetic on typeset -Z variables can - yield different results that with ksh88. Most of these - differences were eliminated in ksh93o. - -24. Starting after ksh93l, If you run ksh name, where name does - not contain a /, the current directory will be searched - before doing a path search on name as required by the POSIX - shell standard. - -25. In ksh93, cd - will output the directory that it changes - to on standard output as required by X/Open. With ksh88, - this only happened for interactive shells. - -26. As an undocumented feature of ksh-88, a leading 0 to an - assignment of an integer variable caused that variable - to be treated as unsigned. This behavior was removed - starting in ksh93p. - -27. The getopts builtin in ksh93 requires that optstring contain - a leading + to allow options to begin with a +. - -28. In emacs/gmacs mode, control-v will not display the version when - the stty lnext character is set to control-v or is unset. - The sequence escape control-v will display the shell version. - -29. In ksh88, DEBUG traps were executed. after each command. In ksh93 - DEBUG traps are exeucted before each command. - -30. In ksh88, a redirection to a file name given by an empty string was - ignored. In ksh93, this is an error. -I am interested in expanding this list so please let me know if you -uncover any others. diff --git a/usr/src/lib/libshell/common/DESIGN b/usr/src/lib/libshell/common/DESIGN deleted file mode 100644 index c11c0aff1e..0000000000 --- a/usr/src/lib/libshell/common/DESIGN +++ /dev/null @@ -1,170 +0,0 @@ -Here is an overview of the source code organization for ksh93. - -Directory layout: - - The directory include contains header files for ksh93. - The files nval.h and shell.h are intended to be public - headers and can be used to add runtime builtin command. - The remainder are private. - - The directory data contains readonly data files for ksh93. - The man pages for built-ins are in builtins.c rather - than included as statics with the implementations in the - bltins directory because some systems don't make static const - data readonly and we want these to be shared by all running - shells. - - The directory edit contains the code for command line - editing and history. - - The fun directory contains some shell function such as - pushd, popd, and dirs. - - The directory features contains files that are used to generate - header files in the FEATURE directory. Most of these files - are in a format that is processed by iffe. - - The directory bltins contains code for most of the built-in - commands. Additional built-in commands are part of libcmd. - - The directory sh contains most of the code for ksh93. - - The directory tests contains a number of regression tests. - In most cases, when a bug gets fixed, a test is added to - one of these files. The regression tests can be run by - going to this directory and running - SHELL=shell_path shell_path shtests - where shell_path is an absolute pathname for the shell to - be tested. - - The top level directory contains the nmake Makefile, a README, - and several documentation files. The RELEASE file contains - the list of bug fixes and new features since the original - ksh93 release. The file COMPATIBILITY is a list of all - known incompatibilities with ksh88. - - The bash_pre_rc.sh is a startup script used when emulating - bash if the shell is compiled with SHOPT_BASH and the shell - is invoked as bash. The bash emulation is not complete. - -Include directory: - 1. argnod.h contains the type definitions for command - nodes, io nodes, argument nodes, and for positional - parameters.a It defines the prototypes for - all the positional parameters functions. - 2. builtins.h contains prototypes for builtins as well - as symbolic constants that refer to the name-pairs - that are associated with some of the built-ins. - It also contains prototypes for many of the strings. - 3. defs.h is the catch all for all definitions that - don't fit elsewhere and it includes several other - headers. It defines a strucuture that contains ksh - global data, sh, and a structure that contains per - function data, sh.st. - 4. edit.h contains definitions that are common to both - vi and emacs edit modes. - 5. env.h contains interfaces for creating and modifying - environment variables. - 6. fault.h contains prototypes for signal related - functions and trap and fault handling. - 7. fcin.h contains macro and function definitions for - reading from a file or string. - 8. history.h contains macros and functions definitions - related to history file processing. - 9. jobs.h contains the definitions relating to job - processing and control. - 10. lexstates.h contains the states associated with - lexical processing. - 11. name.h contains the internal definitions related - to name-value pair processing. - 12. national.h contains a few I18N definitions, mostly - obsolete. - 13. nval.h is the public interface to the name-value - pair library that is documented with nval.3. - 14. path.h contains the interface for pathname processing - and pathname searching. - 15. shell.h is the public interface for shell functions - that are documented int shell.3. - 16. shlex.h contains the lexical token definitions and - interfaces for lexical analysis. - 17. shnodes.h contains the definition of the structures - for each of the parse nodes and flags for the attributes. - 18. shtable.h contains some interfaces and functions for - table lookup. - 19. streval.h contains the interface to the arithmetic - functions. - 20. terminal.h is a header file that includes the appropriate - terminal include. - 21. test.h contains the definitions for the test and [[...]] - commands. - 22. timeout.h contains the define constant for the maximum - shell timeout. - 23. ulimit.h includes the appropriate resource header. - 24. variables.h contains symbolic constants for the built-in - shell variables. - -sh directory: - 1. args.c contains functions for parsing shell options - and for processing positional parameters. - 2. arith.c contains callback functions for the streval.c - library and the interface to shell arithmetic. - 3. array.c contains the code for indexed and associative - arrays. - 4. bash.h contains code used when compiling with SHOPT_BASH - to add bash specific features such as shopt. - 5. defs.c contains the data definitions for global symbols. - 6. deparse.c contains code to generate shell script from - a parse tree. - 7. env.c contains code to add and delete environment variables - to an environment list. - 8. expand.c contains code for file name expansion and - file name generation. - 9. fault.c contains code for signal processing, trap - handling and termination. - 10. fcin.c contains code for reading and writing a character - at a time from a file or string. - 11. init.c contains initialization code and callbacks - for get and set functions for built-in variables. - 12. io.o contains code for redirections and managing file - descriptors and file streams. - 13. jobs.c contains the code for job management. - 14. lex.c contains the code for the lexical analyzer. - 15. macro.c contains code for the $ macro expansions, including - here-documents. - 16. main.c contains the calls to initialization, profile - processing and the main evaluation loop as well as - mail processing. - 17. name.c contains the name-value pair routines that are - built on the hash library in libast. - 18. nvdisc.c contains code related to name-value pair disciplines. - 19. nvtree.c contains code for compound variables and for - walking the namespace. - 20. nvtype.c contains most of the code related to types that - are created with typeset -T. - 21. parse.c contains the code for the shell parser. - 22. path.c contains the code for pathname lookup and - some path functions. It also contains the code - that executes commands and scripts. - 23. pmain.c is just a calls sh_main() so that all of the - rest of the shell can be in a shared library. - 24. shcomp.c contains the main program to the shell - compiler. This program parses a script and creates - a file that the shell can read containing the parse tree. - 25. streval.c is an C arithmetic evaluator. - 26. string.c contains some string related functions. - 27. subshell.c contains the code to save and restore - environments so that subshells can run without creating - a new process. - 28. suid_exec.c contains the program from running execute - only and/or setuid/setgid scripts. - 29. tdump.c contains the code to dump a parse tree into - a file. - 30. timers.c contains code for multiple event timeouts. - 31. trestore contians the code for restoring the parse - tree from the file created by tdump. - 32. userinit.c contains a dummy userinit() function. - This is now obsolete with the new version of sh_main(). - 33. waitevent.c contains the sh_waitnotify function so - that builtins can handle processing events when the - shell is waiting for input or for process completion. - 34. xec.c is the main shell executuion loop. diff --git a/usr/src/lib/libshell/common/OBSOLETE b/usr/src/lib/libshell/common/OBSOLETE deleted file mode 100644 index c29cb8bb63..0000000000 --- a/usr/src/lib/libshell/common/OBSOLETE +++ /dev/null @@ -1,152 +0,0 @@ -.sp 3 -.tl ''Ksh Features That Are Obsolete in Ksh93'' -.sp 2 -.AL 1 -.LI -Using a pair of grave accents \^\fB\(ga\fR ... \fB\(ga\fR\^ -for command substition. Use \fB$(\fR ... \fB)\fR instead. -.LI -.B FCEDIT -is an obsolete name for -the default editor name for the -.B hist -command. -.B FCEDIT -is not used when -.B HISTEDIT -is set. Use -.B HISTEDIT -instead. -.LI -The newtest (\fB[[\fR ... \fB]]\fR) operator -\fB\-a\fP \fIfile\fP -is obsolete. Use -\fB\-e\fP instead. -.LI -The newtest (\fB[[\fR ... \fB]]\fR) operator -.BR = , -as used in -\fIstring\fP \fB=\fP \fIpattern\fP -is obsolete. Use -\fB==\fP instead. -.LI -The following obsolete arithmetic comparisons are also permitted: -.in +5 -.VL 20 -.LI "\fIexp1\fP \fB\-eq\fP \fIexp2\fP" -True, if -.I exp1 -is equal to -.IR exp2 . -.LI "\fIexp1\fP \fB\-ne\fP \fIexp2\fP" -True, if -.I exp1 -is not equal to -.IR exp2 . -.LI "\fIexp1\fP \fB\-lt\fP \fIexp2\fP" -True, if -.I exp1 -is less than -.IR exp2 . -.LI "\fIexp1\fP \fB\-gt\fP \fIexp2\fP" -True, if -.I exp1 -is greater than -.IR exp2 . -.LI "\fIexp1\fP \fB\-le\fP \fIexp2\fP" -True, if -.I exp1 -is less than or equal to -.IR exp2 . -.LI "\fIexp1\fP \fB\-ge\fP \fIexp2\fP" -True, if -.I exp1 -is greater than or equal to -.IR exp2 . -.LE \" End .VL -.in -5 -.LI -Using test -t or [ -t ] without specifying the file unit number. -.LI -The -.B \-k -option to the \fBset\fR builtin is obsolete. It causes -.I all\^ -variable assignment arguments are placed in the environment, -even if they occur after the command name. -The following -first prints -.B "a=b c" -and then -.BR c : -There is no alternative. -.LI -The obsolete -.B \-xf -option of the -.B typeset -command allows a function to be exported -to scripts that are executed without a separate -invocation of the shell. -Functions that need to be defined across separate -invocations of the shell should -be placed in a directory and the -.B FPATH -variable should contains the name of this directory. -They may also -be specified in the -.B ENV -file with the -.B \-xf -option of -.BR typeset . -.LI -The shell environment variable -.B FCEDIT -is obsolete. Use -.B HISTEDIT -instead. -.LI -In the -.B \-s -option -(to \fBfc\fR or \fBhist\fR command???) -( -and in obsolete versions, the editor name -.B \- -) -is used to skip the editing phase and -to re-execute the command. -.LI -The -.B \-t -option to \fBalias\fR builtin is is obsolete. It -is used to set and list tracked aliases. -There is no replacement. -.LI -The shell command line option -.B \-t -is obsolete. This option cause the shell to exit after reading -and executing one command. The is no replacement (although ending -\&"command" with the exit builtin should have the same effect). -.LI -As an obsolete feature of the "set" builtin, -if the first -.I arg\^ -is -.B \- -then the -.B \-x -and -.B \-v -options are turned off and the next -.I arg -is treated as the first argument. -Using -.B \+ -rather than -.B \- -causes these options to be turned off. -These options can also be used upon invocation of the shell. -.LE - diff --git a/usr/src/lib/libshell/common/README b/usr/src/lib/libshell/common/README deleted file mode 100644 index 1feeec8a90..0000000000 --- a/usr/src/lib/libshell/common/README +++ /dev/null @@ -1,232 +0,0 @@ -This directory, and its subdirectories contain the source code -for ksh-93; the language described in the second addition of -the book, "The KornShell Command and Programming Language," by -Morris Bolsky and David Korn which is published by Prentice Hall. -ksh-93 has been compiled and run on several machines with several -operating systems. The end of this file contains a partial list of -operating systems and machines that ksh-93 has been known to run on. - -The layout of files for ksh-93 has changed somewhat since ksh-88, -the last major release. Most of the source code for ksh remains in -the sh directory. However, the shell editing and history routines -are in the edit sub-directory. The code for shell built-ins is -in the bltins directory. The data directory contains read-only -data tables and messages that are used by the shell. The include -files remain in the include directory and the shlib directory -is gone. The features directory replaces the older install -directory. The method for generating systems specific feature -information has changed substantially. - -The Makefile file contains several compilation options that can be set -before compiling ksh. Options are of the form SHOPT_option and become -#define inside the code. These options are set to their recommended -value and some of these may disappear as options in future releases. -A value of 0, or no value represents off, 1 represents on. -Note that == is needed, not =, because these are nmake state variables -and changing their value will cause all modules that could be affected -by this change to be recompiled. -The options have the following defaults and meanings: - ACCT off Shell accounting. - ACCTFILE off Enable per user accounting info. - AUDIT off For auditing specific users - AUDITFILE "/etc/ksh_audit" - APPEND on Allows var+=val string and array append. - BASH off Bash compatibility mode. It is not fully implemented - and is experimental. - BRACEPAT on C-shell type abc{d,e}f style file generation - CMDLIB_BLTIN off Makes all commands in libcmd.a builtins. The - SH_CMDLIB_DIR nmake state variable can be used to - specify a directory. - CMDLIB_DIR off Sets CMDLIB_BLTIN=1 and provides a default value - of "/opt/ast/bin" for SH_CMDLIB_DIR. - COMPOUND_ARRAY - on Allows all components of compound variables except the - first to be any string by enclosing in [...]. It also - allows components other than the last to be arrays. - This is experimental and only partially complete. - CRNL off <cr><nl> treated as <nl> in shell grammar. - DYNAMIC on Dynamic loading of builtins. (Requires dlopen() interface.) - ECHOPRINT off Make echo equivalent to print. - ESH on Compile with emacs command line editing. The original - emacs line editor code was provided by Mike Veach at IH. - FILESCAN on Experimental option that allows fast reading of files - using while < file;do ...; done and allowing fields in - each line to be accessed as positional parameters. - FS_3D off For use with 3-D file system. Enabled automatically for - sytems with dynamic linking. - KIA off Allow generation of shell cross reference database with -I. - MULTIBYTE on Multibyte character handling. Requires mblen() and - mbctowc(). - NAMESPACE on Allows namespaces. This is experimental, incomplete - and undocumented. - OLDTERMIO off Use either termios or termio at runtime. - OO on Experimental object oriented extension. This option - should disappear soon. - OPTIMIZE on Optimize loop invariants for with for and while loops. - P_SUID off If set, all real uids, greater than or equal to this - value will require the -p flag to run suid/sgid scripts. - PFSH off Compile with support for profile shell. - RAWONLY off Turn on if the vi line mode doesn't work right unless - you do a set -o viraw. - SEVENBIT off Strip the eigth bit from characters. - SPAWN off Use spawn as combined fork/exec. May improve speed on - some systems. - STATS on Add .sh.stats compound variable. - SUID_EXEC on Execute /etc/suid_exec for setuid, setgid script. - TIMEOUT off Set this to the number of seconds for timing out and - exiting the shell when you don't enter a command. If - non-zero, TMOUT can not be set larger than this value. - TYPEDEF on Enable typeset type definitions. - VSH on Compile with vi command line editing. The original vi - line editor code was provided by Pat Sullivan at CB. - -The following compile options are set automatically by the feature testing: - DEVFD Set when /dev/fd is a directory that names open files. - SHELLMAGIC - Set on systems that recognize script beginning with #! specially. - VPIX Set on systems the have /usr/bin/vpix program for running MS-DOS. - - -In most instances, you will generate ksh from a higher level directory -which also generates libcmd and libast libraries on which ksh depends. -However, it is possible to generate ksh, with by running make -f ksh.mk -in this directory. The ksh.mk file was generated from the nmake Makefile. -If you do not have make or nmake, but do have a Version 7 UNIX compatible -shell, then you can run the script mamexec < Mamfile to build ksh. -If you have nmake, version 2.3 or later, you can use it without the -f ksh.mk. -In either case, ksh relies on libraries libast and libcmd which must be -built first. The binary for ksh becomes the file named ./ksh which can -be copied to where ever you install it. - -If you use old make or the Mamfile, and you system has dynamic shared -libraries, then you should define the variables mam_cc_static and -mam_cc_dynanamic as the compiler options that request static linking -and dynamic linking respectively. This will decrease the number of -shared libraries that ksh need and cut startup time substantially. - -The makefile should also generate shcomp, a program that will precompile -a script. ksh93 is able to recognize files in this format and process -them as scripts. You can use shcomp to send out scripts when you -don't want to give away the original script source. - -It is advisable that you put the line PWD=$HOME;export PWD into the -/etc/profile file to reduce initialization time for ksh. - -To be able to run setuid/setgid shell scripts, or scripts without read -permission, the SUID_EXEC compile option must be on, and ksh must be installed -in the /bin directory, the /usr/bin directory, the /usr/lbin directory, -or the /usr/local/bin directory and the name must end in sh. The program -suid_exec must be installed in the /etc directory, must be owned by root, -and must be a suid program. If you must install ksh in some other directory -and want to be able to run setuid/setgid and execute only scripts, then -you will have to change the source code file sh/suid_exec.c explicitly. -If you do not have ksh in one of these secure locations, /bin/sh will -be invoked with the -p options and will fail when you execute a setuid/setgid -and/or execute only script. Note, that ksh does not read the .profile -or $ENV file when it the real and effective user/group id's are not -equal. - -The tests sub-directory contains a number of regression tests for ksh. -To run all these tests with the shell you just built, go to the tests -directory and run the command - SHELL=$dir/ksh $dir/ksh shtests -where dir is the directory of the ksh you want to test. - -The file PROMO.mm is an advertisement that extolls the virtues of ksh. -The file sh.1 contains the troff (man) description of this Shell. -The file nval.3 contains the troff (man) description of the name-value -pair library that is needed for writing built-ins that need to -access shell variables. - -The file sh.memo contains a draft troff (mm) memo describing ksh. The -file RELEASE88 contains the changes made for ksh88. The file RELEASE93 -contains the changes made in this release since ksh-88. The file -RELEASE contains bug fixes made in this release since ksh-88. The file -COMPATIBILITY contains a list of incompatibilities with ksh-88. The -file bltins.mm is a draft troff (mm) memo describing how to write -built-in commands that can be loaded at run time. - -Most of the work for internationalization has been done with ksh93. -The file ksh.msg is a generated file that contains error messages -that need to be translated. In addition, the function translate() -in sh/init.c has to be completed to interface with the dictionary -lookup. The translate function takes two argument, the string -that is to be translated and a type which is - 0 when a library string needs translation. - 1 when one of the error messages in ksh.msg needs translation. - 2 when a string in a script needs translation. You use a $ in front - of a double quoted string in a script to indicate that it - needs translation. The -D option for ksh builds the dictionary. -The translate routine needs to return the translated message. -For dictionaries that need to use a numeric key, it should be -possible to use the strhash() function to generate numbers to -go along with each of the messages and to use this number both -when generating the dictionary and when converting strings. -If you encounter error messages of type 1 that are not be translated via -this translate() function send mail to the address below. - -Please report any problems or suggestions to: - -dgk@research.att.com - - -ksh93 has been compiled and alpha tested on the following. An asterisk -signifies that ksh has been installed as /bin/sh on this machine. - -* Sun OS 4.1.[123] on sparc. - Sun OS 4.1.1 on sun. - Solaris 2.[1-9] on sparc. - Solaris 2.[4-8] on X86. - HP/UX 8 on HP-9000/730. - HP/UX 9 on HP-9000/730. - HP/UX 10 on HP-9000/857. - HP/UX 11 on pa-risc. - System V Release 3 on Counterpoint C19 - System V Release 4 on AT&T Intel 486. - System V Release 4 on NCR 4850 Intel 486. - IRIX Release 4.0.? System V on SGI-MIPS. - IRIX Release 5.1 System V on SGI-MIPS. - IRIX Release 6.[1-5] System V on SGI-MIPS. - System V Release 3.2 on 3B2. - UTS 5.2.6 on Amdahl 3090,5990,580. - System V Release 3.2 on i386. - SMP_DC.OSx olivetti dcosx MIServer-S 2/128. - SMP_DC.OSx Pyramid dcosx MIServer-S 2/160 r3000. - 4.3BSD on Vax 8650. - AIX release 2 on RS6000. - AIX 3.2 on RS6000. - Linux 1.X on Intel - Linux 2.X on Intel - Linux 2.X on Alpha - Linux 2.X on Alpha - Linux 2.X on OS/390 - Linux 2.X on sparc - Linux 2.4 on intel itanium 64 - Linux Slackware on sparc64 -* Linux ARM on i-PAQ - OSF1 on DEC alpha. - OSF4 on DEC alpha. - UMIPS 4.52 on mips. - BSD-i [2-4] on X86. - OpenBSD on X86 - NetBSD on X86 - FreeBSD on X86 - NeXT on Intel X86. - NeXT on HP. -* Windows NT using UWIN on X86 -* Windows NT using UWIN on alpha - Windows NT using Cygwin on X86 - Windows NT with NutCracker libraries. - Windows NT with Portage libraries. - Windows 3.1 using custom C library. - OpenEdition on MVS - Darwin OS X on PPC - MVS on OS 390 - SCO Openserver 3.2 on X86 - Unixware 7 on X86 - -Good luck!! - -David Korn -dgk@research.att.com - diff --git a/usr/src/lib/libshell/common/RELEASE b/usr/src/lib/libshell/common/RELEASE deleted file mode 100644 index b8fc92511a..0000000000 --- a/usr/src/lib/libshell/common/RELEASE +++ /dev/null @@ -1,2204 +0,0 @@ -10-03-05 --- Release ksh93t+ --- -10-03-05 A varibale unset memory leak has been fixed and tests/leaks.sh - has been added to verify the fix. -10-03-04 Documentation, comment, and disgnostic spelling typos corrected. -10-02-14 Fix sh_getenv() initialization to cooperate with the 3d fs. -10-02-12 A bug in which the get discipline function was not invoked for - associative array subscripts for unset array elements has been fixed. -10-02-12 A bug which could occur if the last line of a script was an eval - that executed multiple commands has been fixed. -10-02-02 A buffer overflow in read and another in binary type base64 - encoding were fixed. -10-01-20 A bug in the evaluation of arithmetic expression in which the - subscript was evaluated twice for $((foo[x++]++)) has been fixed. -10-01-19 A workaround for a double-free of a trap in both a subshell and its - parent has been added. -10-01-18 A bug in type handling of typeset -H has been fixed. -10-01-15 The "adding empty subscript" warning now only emitted with -x set. -10-01-01 A bug in the parser in which '$((case i in i):;esac);:))' was not - parsed correctly was fixed. -10-01-01 A bug in the parser in which '$(( 2 , 3.6 ))' dumped core for locales - with radix char , and thousands separator . has been fixed. -09-12-28 A bug in the handling of SIGCLD on systems that generated SIGCLD - while blocked waiting for process to complete has been fixed. -09-12-24 ast setlocale() reworked to differentiate env var changes from user - override. -09-12-18 A bug with the SHOPT_BGX option set which disabled traps for signals - < SIGCHLD when a trap for a signal > SIGCHLD was set has been fixed. -09-12-18 A bug where [[ -v var ]] was incorrect for some variables (including - LC_* vars) has been fixed. -09-12-15 A bug that produced a syntax error when a multibyte character - straddled a buffer boundary has been fixed. -09-12-11 A bug where the subscript of an unset variable was not evaluated has - been fixed. -09-12-09 A bug where shcomp dumped core on certain syntax errors has been fixed. -09-12-07 A bug where a parent shell environment var reset in a subshell removed - the value in subsequent children of the parent shell has been fixed. -09-12-04 A bug in which in some cases a trap in a function executed in - a subshell could trigger twice has been fixed. -09-12-03 A bug in which SHLVL exported with some attributes could cause - the shell to abort at startup has been fixed. -09-12-02 A bug with pipefail in which the shell could hang waiting for the - writer to complete before the last reader command has been fixed. -09-11-30 A bug in which a trap could be inherited by the first element of - a pipeline when the command had more than 63 arguments that did - not contain any macro expansions has been fixed. -09-11-19 When read from a terminal was called from with a while or foo loop, - and an edit mode was on, a backspace or erase no longer will - overwrite the prompt. -09-11-17 Change .paths parse to handle BUILTIN_LIB=foo BUILTIN_LIB=foo-1.2. -09-11-17 Inside a function, typeset foo.bar will bind foo to global variable - foo if local variable foo does not exist, instead of creating a - local variable. -09-11-17 "read -n1" from the terminal has been fixed to read exactly one character. -09-11-11 Job control now works for subshell commands, (...). -09-11-11 If set -e is on for an interactive shell errors in special builtins - now cause the shell to exit. -09-11-11 A bug in which an interrupt handler processed during the read builtin - when IFS did not contain a new line has been fixed. -09-11-09 A bug in which a variable that has been unset in a subshell and then - exported from that subshell does not show up in the environment - has been fixed. -09-11-02 ``,2'' is now a valid numeric constant for locales with - decimal_point=','. -09-11-02 A bug where "return" in .profile did not restore the shell state - has been fixed. -09-10-31 A bug that corrupted saved exit status when pids wrapped around has - been fixed. -09-10-26 A bug in { LANG LC_ALL LC_category } ordering has been fixed in -last. -09-10-16 A bug where notification to libast that the environment has changed - has been fixed. -09-10-12 A bug in which a function loaded in a subshell could leave side - effects in the parent shell has been fixed. -09-10-12 A bug in converting a printf %d operand to a number when the operand - contains multiple subscripts for the same variable has been fixed. -09-10-09 A bug in the handling of the escape character \ in directory prefixes - in command completion has been fixed. -09-10-09 $PATH processing has been changed to delay dir stat() and .paths - lookup until the directory is needed in the path search. -09-09-28 Call the ast setlocale() intercept on unset too. -09-09-24 A bug in which LANG=foo; LC_ALL=foo; unset LC_ALL; did not revert - LC_CTYPE etc. to the LANG value has been fixed. -09-09-17 A bug in which unsetting SVLVL could cause a script invoked by - name without #! to core dump has been fixed. -09-09-16 A bug in which a pipeline in a here-document could hang when the - pipefail option was on has been fixed. -09-09-09 A bug in the processing of line joining in here documents which - occurred when a buffer began with <escape><new-line> has been fixed. -09-09-09 A leading ; with commands in a brace group or parenthesis group - no longer causes an error. It now is used for the "showme" option. -09-09-09 A bug in which a subshell containing a background process could - block until the background process completed has been fixed. -09-09-04 A bug in handing ${var[sub]}, where var is a nameref has been fixed. -09-09-03 A bug which caused an index array to have the wrong number of elements - when it was converted from a compound variable by adding an another - element has been fixed. -09-09-03 Specifying export for a compound variable now generates an error. -09-09-02 $"..." localizations strings are no longer recognized inside `...`. -09-09-01 A bug in the for loop optimizer in the handling of type static - variables has been fixed. -09-09-01 An error message is not displayed when * and @ are used as subscripts. -09-09-01 Several bugs in the processing for types that included an associative - array of another type has been fixed. -09-09-01 A bug in the tracing of [[ a < b ]] and [[ a > b ]] has been fixed. -09-08-26 The .sh.file variable was not being set for a script that was run - by name and didn't start with #! and this has been fixed. -09-08-25 A bug in which a function called to deeply from command substitution - did not display an error message has been fixed. -09-08-24 When processing profiles, ksh93 now violates the POSIX standard and - treats &> as a redirection operator similar to bash. -09-08-23 A bug in the handling of the trap on SIGPIPE that could lead to a - memory fault has been fixed. -09-08-21 A bug in the handling of the comma operator in arithmetic expressions - that could cause a core dump on some systems has been fixed. -09-08-20 A bug in which a compound variable containing an array of a type - that doesn't have any elements now expands correctly. -09-08-19 A bug which disabled function tracing inside a function after - a call to another function has been fixed. -09-08-19 A bug in which initializing a compound variable instance to another - compound variable by name has been fixed. -09-08-18 A bug in which compound variable instances could be lost after - an instance that invoked a type method discipline has been fixed. -09-08-18 A bug in which a discipline function for a type applied to an - array instance when invoked in a function ignored the subscript - has been fixed. -09-08-18 A scoping error with variables in arithmetic expression with - type variables when reference with a name reference has been fixed. -09-08-10 Several memory leaks were fixed primarily related to subshells. -09-08-06 A bug in which setting the trap on CHLD to ignore could cause - a script to hang has been fixed. -09-07-08 A bug in the processing of name reference assignments when it - contained pattern expansions with quoting has been fixed. -09-06-22 The default width for typeset -X has been changed so that there - should be no loss of precision when converting to a string. -09-06-19 A bug in the printing of array elements for binary variables with - printf %B has been fixed. -09-06-19 A bug which caused a core dump with trap DEBUG set with an array - assignment with no elements has been fixed. -09-06-19 A bug with read with typeset -b -Z<num> has been fixed. -09-06-19 Two bugs related to read -b for array variables has been fixed. -09-06-19 A bug with typeset for compound variables containing arrays of - compound variables has been fixed. -09-06-18 A bug in appending a compound variable to a an indexed array of - compound variables has been fixed. -09-06-18 A bug which occurs when appending a compound variable to an indexed - array element has been fixed. -09-06-18 Setting VISUAL to a value other than one ending in vi or emacs will - no longer unset the edit mode. -09-06-17 A bug in typeset -m when moving a local compound variable to a - global compound variable via a name reference has been fixed. -09-06-17 A bug in appending to nodes of an array of compound variables when - addressing them via nameref has been fixed. -09-06-17 A bug in typeset -p var, when var is an array of compound variables - in which the output only contained on array element has been fixed. -09-06-17 The prefix expansion ${!y.@} now works when y is a name - reference to an element of an array. -09-06-16 Traps on signals that are ignored when the shell is invoked - no longer display. Previously they were ignored as required but - would be listed with trap -p. -09-06-12 A bug in vi edit mode in which hitting the up arrow key at the - end of a line longer than 40 characters which caused a core dump - has been fixed. -09-06-11 A bug in which "eval non-builtin &" would create two processes, - one for the & and another for non-builtin has been fixed. -09-06-08 When var is an identifier and is unset, ${var} no longer tries to - run command substitution on the command var. -09-06-08 Process substitution arguments of the form <(command) can now be - used following the < redirection operator to redirect from command. -09-05-13 A bug in which redirections of the form 2>&1 1>&5 inside command - substitution could cause the command substitution to hang has been - fixed. -09-05-12 To conform with POSIX, the -u option only checks for unset variables - and subscript elements rather than checking for all parameters. -09-05-12 A bug which could cause a core dump when a variable whose name - begins with a . was referenced as part of a name reference inside - a function has been fixed. -09-05-01 A bug that caused a core dump when SIGWINCH was received and - both vi and emacs mode were off has been fixed. -09-04-22 Default alias compound='typeset -C' added. -09-04-15 A bug that caused ${...;} to hang for large files has been fixed. -09-04-08 A change was made in the -n option which printed out an incorrect - warning with <>. -09-04-07 The emacs edit command M-_ and M_. and the vi command _ was fixed - to handle the case there there is no history file. -09-04-05 A bug in handling new-lines with read -n has been fixed. -09-04-05 The ENV variable defaults the the file named by $HOME/.kshrc rather - then to the string $HOME/.kshrc. -09-03-31 A bug in which a nested command substitution with redirections could - leave a file descriptor open has been fixed. -09-03-24 ksh now only uses the value of the _ variable on startup if it can - verify that it was set by the invoking process rather than being - inherited by some other ancestor. -09-03-24 When ksh is invoked without -p and ruid!=euid, and the shell is - compiled without SHOPT_P_UID or ruid<SHOPT_P_UID, the shell now - enables the -p option. The previous version instead set the - euid to the ruid as it does for set +p. -09-03-24 When SHOPT_P_UID is defined at compile time and the shell is started - without -p and ruid!=euid and ruid>=SHOPT_P_UID then euid is set - to ruid. A bug that did the wrong test (ruid<SHOPT_P_UID) was fixed. -09-03-17 The sleep(1) builtin now accept and ISO 8601 PnYnMnDTnHnMnS - duration or date(1) compatible date/time operand. -09-03-10 If a variable that was left or right justified or zero-filled was - changed with a typeset statement that was left or right justified - or zero-filled, then the original justification no longer affects - the result. -09-03-10 A bug in the handling of traps when the last command in a script - is a subshell grouping command has been fixed. -09-03-03 A bug in which an expansion of the form ${!prefix@} could generate - an exception after the return from a function has been fixed. -09-02-02 A bug in restricted mode in which the value of ENV could be - changed from within a function has been fixed. -09-02-02 A bug in which an erroneous message indicating that a process - terminated with a coredump has been fixed. -09-02-02 The exit status when exit was called without an argument from - a signal handler was incorrect and has been fixed. -09-02-02 A bug in which a function autoloaded in a subshell could cause - a core dump when the subshell completed has been fixed. -09-02-02 A bug in which 2>&1 inside a command substitution wasn't working - correctly has been fixed. -09-02-02 A bug in the call stack of arithmetic function with 2 args - returning int has been fixed. -09-01-30 A bug in which 'eval print \$0' inside a function was giving the - wrong value for $0 has been fixed. -09-01-28 A bug in which a command substitution could return an exit status - of 127 when the pipefail option is enabled has been fixed. -09-01-26 ksh93 now generates an error message if you attempt to create - a global name reference to a local variable. -09-01-26 The [[ -v var ]] operator was modified to test for array elements. -09-01-23 The redirection operator <>; was added. It is similar to <> - except that if the command it is applied to succeeds, the file - is truncated to the offset at the command completion. -09-01-23 The default file descriptor for <> was changed to 1. -09-01-20 A bug in which the exit status specified in an exit trap was - not used when a process terminated with a signal has been fixed. -09-01-19 A bug in which a signal whose default action is to terminate - a process could be ignored when the process is running a sub-shell - has been fixed. -09-01-19 A bug in which sending SIGWINCH to a process that reads from a pipe - could cause a memory fault has been fixed. -09-01-16 The -R unary operator was added to [[...]] and test to check whether - a variable is a name reference. -09-01-16 The -v unary operator was added to [[...]] and test to check whether - a variable is set. -09-01-14 The unset built-in was modified to return 0 exit status when - unsetting a variable that was unset to conform with the POSIX - standard. -09-01-14 The unset built-in was modified to continue to unset variables - after encountering a variable that it could not unset to - conform to the POSIX standard. -09-01-14 The parameter expansion ${x+value} no longer expands the value of - the variable x when determining whether x is set or not. -09-01-13 A bug in which background jobs and pipelines that were not waited - for could, in rare instances, cause the shell to go into an infinite - loop or fail has been fixed. -09-01-06 A bug in indexed arrays of compound variables in which referencing - non-existent sub-variable in an arithmetic expression could cause - the sub-variable to be created has been fixed. -09-01-05 A bug in which the \ character did not escape extended regular - expression pattern characters has been fixed. -08-12-24 A bug in which killing the last element of a pipe did not cause - a write to the pipe to generate a SIGPIPE has been fixed. -08-12-19 A bug which could cause command substitution to hang when the - last element of a pipeline in a command substitution was a built-in - and the output was more that PIPE_BUFF. -08-12-18 A bug which occurs when a here documented marker embedded in a - command substitution occurs on a buffer boundary has been fixed. -08-12-17 A bug in the output of typeset -p for variables that had attributes - but did not have a value has been fixed. -08-12-16 A bug in which a name reference to a name reference variable that - references an array element has been fixed. -08-12-16 A bug in which a variable given both the -A and -C attribute along - with an initial assignment didn't work correctly has been fixed. -08-12-10 The [[ -t fd ]] test was fixed to handle fd>9. -08-12-10 A bug where function stack misalignment could cause a bus error - has been fixed. -08-12-09 Command completion was changed to use \ to quote special characters - instead of quoting the argument in single quotes. -08-12-07 A bug in typeset -m which occurred when the target node was an - associative array element has been fixed. -08-12-07 A timing bug on some systems (for example darwin), that could - cause the last process of a pipeline entered interactively to fail - with an "Exec format error" has been fixed. -08-12-04 SHOPT_BGX enables background job extensions. Noted by "J" in - the version string when enabled. (1) JOBMAX=n limits the number - of concurrent & jobs to n; the n+1 & job will block until a - running background job completes. (2) SIGCHLD traps are queued - so that each completing background job gets its own trap; $! is - set to the job pid and $? is set to the job exit status at the - beginning of the trap. (3) sleep -s added to sleep until the time - expires or until a signal is delivered. -08-12-04 The sign of floating point zero is preserved across arithmetic - function calls. -08-12-04 A bug that caused print(1) to produce garbled stdout/stderr - output has been fixed. -08-12-04 A bug in which printf "%d\n" "'<euro>'" did not output the - numerical value of the EURO symbol, 8354, has been fixed. -08-11-24 /dev/fd* and /dev/std* redirections are first attempted with - open() to preserve seek semantics; failing that the corresponding - file descriptors are dup()'d. -08-11-20 A bug which could cause a core dump if a function compiled with - shcomp was found has been fixed. -08-11-20 A bug in which jobs were not cleared from the jobs table for - interactive shells when the pipefail option is on has been fixed. -08-11-11 A bug in which a field that was unset in a type definition and later - set for an instance could appear twice when displaying the variable - has been fixed. -08-11-11 A bug in which running a simple command & inside a function would - not return the correct process id has been fixed. -08=11-10 A bug in which the exit status of a command could be lost if the pid - was that of the most recent command substitution that had completed - has been fixed. -08-11-10 The maximum depth for subshells has been increased from 256 to 65536. -08-11-06 A bug which could cause a core dump when the _ reference variable was - used as an embedded type with a compound assignment has been fixed. - -08-10-31 --- Release ksh93t --- -08-10-31 Variable scoping/initialization bugs that could dump core were fixed. -08-10-24 The lexer now accepts all RE characters for patterns prefixed - with a ksh ~(...) option expression. -08-10-24 For ${var/pat/sub} \0 in sub expands to the text matched by pat. -08-10-18 A bug in array scoping that could dump core has been fixed. -08-10-10 read -n and -N fixed to count characters in multibyte locales. -08-10-10 A bug that mishandled _.array[] type references has been fixed. -08-10-09 ${.sh.version} now contains a concatenation of the following (after - 'Version') denoting compile time features: - A SHOPT_AUDIT - B SHOPT_BASH - L SHOPT_ACCT - M SHOPT_MULTIBYTE -08-10-09 A bug that caused subshell command substitution with redirection - to hang has been fixed. -08-10-08 Output errors, other than to stderr, now result in a diagnostic. -08-10-08 ksh93 now supports types that contain arrays of other types as - members. Earlier versions core dumped in this case. -08-10-05 A bug which caused the shell to emit a syntax error for an arithmetic - statement of the form (( var.name[sub] = value)) has been fixed. -08-10-01 A bug that caused subshell command substitution to hang has - been fixed. -08-09-29 When the -p export option of typeset is used with other options, - only those variables matching the specified options are displayed. -08-09-29 When the shell reads the environment and finds variables that are - not valid shell assignments, it now passes these on to subsequent - commands rather than deleting them. -08-09-29 A bug in the display of compound variables containing an indexed - array of compound variables has been fixed. -08-09-29 A bug in the display of compound variables containing an associative - array with a subscript containing a . in the name has been fixed. -08-09-26 A core dump in the subshell environment restore has been fixed. -08-09-24 $(...) has been fixed to properly set the exit status in $?. -08-09-23 $(<...) with IFS=$'\n\n' has been fixed to retain all but the last - of multiple trailing newlines. -08-09-23 The -p option to typeset when used with other attributes, restricts - the output to variables with the specified attributes. -08-09-22 A bug that sometimes lost the exit status of a job has been fixed. -08-09-21 A bug that retained trailing command substitution newlines in - cases where the command caused the shell to fork has been fixed. -08-09-19 type, whence -v, and command -v were fixed to comply with POSIX - by writing 'not found' diagnostics to the standard error. -08-09-18 test and [...] were fixed to comply with POSIX in the case - of test '(' binop ')' where binop is a valid binary test operator. -08-09-16 If a method discipline named create is specified when defining a - type, this function will be called when an instance is created. -08-09-15 The variable _ is now set as a reference to the compound variable - when defining a compound variable or a type. -08-09-10 The shell now prints an error message when the type name specified - for an indexed array subscript is not an enumeration type. -08-09-10 A bug in which a subshell that spawned a background process could - loose output that was produced after the foreground completed - has been fixed. -08-09-10 A timing bug on some systems that could cause coprocesses started by a - subshell to not clean up and prevent other coprocesses has been fixed. -08-09-09 The typeset -m option is now able to rename array elements from - the same array. -08-09-09 The exit status of 2 from the DEBUG trap causes the next command - to be skipped. An exit value of 255 from a DEBUG trap called from - a function causes the function to return. -08-09-08 A bug in which a coprocess created in a subshell that did not - complete when the subshell terminated could prevent a coprocess - from being created in the parent shell has been fixed. -08-09-05 An assignment of the form name1=name2 where name1 and name2 - are both compound variables causes name1 to get a copy of name2. - name1+=name2 causes name2 sub-variables to be appended to name1. -08-09-05 A bug in which unsetting a compound variable did not unset all - the sub-variables has been fixed. -08-09-01 A bug in the subshell cleanup code that could cause SIGSEGV has - been fixed. -06-08-26 The SHLVL variable which is an environment variable used by bash - and zsh that gets incremented when the shell starts. -08-08-25 For an indexed array, a negative subscript now refers to offsets - from the end so that -1 refers to the last element. -08-08-24 An alignment error for shorts on 64 bit architectures has been fixed. -08-08-22 If oldvar is a compound variable, typeset -C newvar=oldvar creates - newvar as a copy of oldvar. -08-08-19 The ALRM signal no longer cause the sleep builtin to terminate. -08-08-13 When used in an arithmetic expression, the .sh.version variable - now produces a number that will be increasing for each release. -08-08-11 A bug in which type instantiation with a compound assignment in - a dot script in which the type is defined has been fixed. -08-08-07 The -m option has been added to typeset to move or rename a - variable. Not documented yet. -08-08-06 A bug in read when used in a loop when a prompt was specified - when reading from a terminal has been fixed. -08-08-01 A bug with the pipefail option in which a nested pipeline could - cause an asynchronous command to block has been fixed. -08-08-01 A for loop optimizer bug that treats .sh.lineno as an invariant - has been fixed. -08-07-30 A bug in which expanding compound variable that had a get discipline - from with a here document could cause a syntax error has been fixed. -08-07-18 A bug in which a nameref caused a local variable to be created - rather than binding to an existing variable in the global scope - has been fixed. -08-07-17 A bug which occurred when a nameref was created from within a - function that was part of a pipeline has been fixed. -08-07-14 The compile option SHOPT_STATS was added. With this option the - compound variable .sh.stats keeps usage statistics that could help - with performance tuning. -08-07-10 The output of set now always uses a single line for each variable. - For array variables, the complete set of values is now displayed. -08-07-09 The typeset -C option can be used with arrays to indicate that - each element should default to a compound variable. -08-07-08 The %B format now outputs compound variables and arrays. The - alternate flag # can be used to cause output into a single line. -08-07-03 When the window change signal, WINCH, is received, the current - edit line is redrawn in place. -08-07-01 A bug in the handling of shared variables when inside an embedded - type has been fixed. -08-06-29 A bug in multiline edit mode which occurred when the prompt length - was three characters or less has been fixed. -08-06-23 A bug in which the SIGCLD was not be triggered when background - jobs completed has been fixed. -08-06-23 KSH_VERSION added as a name reference to .sh.version. -08-06-20 type now outputs 'special builtin' for special builtins. -08-06-19 A couple of bugs in multi-dimensional arrays have been fixed. -08-06-19 A bug in which a syntax error in a dot script could generated - a syntax error in the next subsequent command has been fixed. -08-06-17 Reduced the maximum function call depth to 2048 to avoid exceptions - on some architectures. -08-06-16 A bug in which printf "%B" could generate an exception when the - specified variable was not set has been fixed. -08-06-16 When typeset -p is followed by variable names, it now displays - the attributes names and values for the specific names. -08-06-14 A bug that could effect the drawing of the screen from multiline - emacs or gmacs mode when walking up the history file has been fixed. -08-06-13 A bug in which a compound variable defined in a subshell could - have side effects into the parent shell has been fixed. -08-06-13 A number of bugs related to using .sh.level to set the stack from - for DEBUG traps have been fixed. -08-06-13 The .sh.lineno variable has been added. When .sh.level is changed - inside a DEBUG trap, the .sh.lineno contains the calling line number - for the specified stack frame. -08-06-13 The .sh.level variable has been documented and now works. -08-06-11 The -C option has been added to read for reading compound command - definitions from a file. -08-06-11 The . command is now permitted inside a compound command definition. - The dot script can contain declaration commands and dot commands. -08-06-09 Add -C option to typeset so that typeset -C foo, is equivalent - to foo=(). -08-06-09 Added -n warning message for typeset option orderings that are valid - with ksh88 but not valid with ksh93, for example Lx5. -08-06-09 A bug in which the return value for an assignment command containing - a command substitution with that failed was zero when the assignment - contained redirections has been fixed. -08-06-09 A bug in the quoting of $ inside a ERE pattern ~(E)(pattern) - has been fixed. -08-06-06 A bug when processing `` command substitution with the character - sequence \$' has been fixed. -08-06-02 When defining a type, the typeset -r attribute causes this field - to be required to be specified for each instance of the type and - does not allow a default value. -08-06-02 Several bugs in which compound variables were modified by - subshells have been fixed. -08-05-22 The ceil function has been added to the math functions. -08-05-21 A bug in which a name reference defined in a function and passed - as an argument to another function could cause an incorrect binding. -08-05-21 A bug in freeing compound variables that are local to functions - has been fixed. -08-05-19 The array expansions ${array[sub1..sub2]} and ${!array[sub1..sub2]} - to expand to the value (or subscripts) for array between sub1 and - sub2 inclusive. For associative arrays, the range is based on - location in the POSIX locale. The .. must be explicit and cannot - result from an expansion. -08-05-15 The trap on SIGCLD is no longer triggered by the completion of - the foreground job as with ksh88. -08-05-14 A bug in the implementation of the editing feature added on - 07-09-19 in emacs mode has been fixed. -08-05-12 A bug in processing the test built-in with parenthesis has been - fixed. -08-05-12 The unset built-in now returns non-zero when deleting an array - subscript that is not set. -08-05-08 Changing the value of HISTFILE or HISTSIZE will cause the old - history file to be close and reopened with the new name or size. -08-05-08 When FPATH is changed functions that were found via a path search - will be searched for again. -08-05-08 A parser bug in which reserved words and labels were recognized - inside compound indexed array assignment after a new-line has - been fixed. -08-05-07 A bug in getopts when handling numerical option arguments has - been fixed. -08-05-07 The typeset -S option was added for variables outside type - definitions to provide a storage class similar to C static - inside a function defined with function name. When outside - type definitions and outside a function, the -S option cause - the specified variable so be unset before the assignment and - before the remaining attributes are supplied. -08-05-07 A bug that affected the cursor movement in multiline mode when - a character was deleted from near the beginning of the any - line other than the first. -08-05-01 In multiline edit mode, the refresh operation will now clear - the remaining portion of the last line. -08-05-01 A bug in computing prompt widths for the edit modes for prompts - with multibyte characters has been fixed. -08-05-01 A bug in the multiline edit mode which could cause the current - line to be displayed incorrectly when moving backwards from third - or higher line to the previous line has been fixed. -08-05-01 A bug in which options set in functions declared with the function - name syntax were carried across into functions invoked by these - functions has been fixed. -08-04-30 A bug which could cause a coprocess to hang when the read end - is a builtin command has been fixed. -08-04-30 The emacs and vi editors have been modified to handle window - change commands as soon as they happen rather than waiting for - the next command. -08-04-28 A bug in which ${!x} did not expand to x when x was unset has been - fixed. -08-04-27 A bug in which the assignment x=(typeset -a foo=([0]=abc)) created - x.foo as an associative array has been fixed. -08-04-25 A bug in which $# did not report correctly when there were more - than 32K positional parameters has been fixed. -08-04-04 Choose the name _ as the sub-variable that holds type or instance - specific data used by discipline functions. -08-03-27 A bug in which the terminal group was not given back to the parent - shell when the last part of a pipeline was handled by the parent shell - and the other parts of the pipeline complete has been fixed. - The symptom was that the pipeline became uninterruptable. -08-03-25 A bug in restricted mode introduced in ksh93s that caused scripts - that did not use #! to executed in restricted mode has been fixed. -08-03-25 A bug in which the pipefail option did not work for a pipeline - within a pipeline has been fixed. -08-03-24 A bug in which OPTIND was not set correctly in subshells has - been fixed. -08-03-24 A bug which could cause a memory exception when a compound variable - containing an indexed array with only element 0 defined was expanded. -08-03-20 A bug in which ${!var[sub].*} was treated as an error has been fixed. -08-03-20 Associative array assignments of the form ([name]=value ...) - now allow ; as well as space tab and new line to separate elements. -08-03-18 A buffering problem in which standard error was sometimes - not flushed before sleep has been fixed. -08-03-17 A bug in which a signal sent to $$ while in a subshell would be - sent to the subshell rather than the parent has been fixed. -08-03-17 --default option added to set(1) to handle set +o POSIX semantics. - set --state added as a long name alias for set +o. -08-03-14 A bug in which using monitor mode from within a script could - cause the terminal group to change has been fixed. -08-03-10 The new ${...} command substitution will treat the trailing } - as a reserved word even if it is not at the beginning of a command, - for example, ${ date }. -08-03-10 If the name of the ENV begins with /./ or ././ then the - /etc/ksh.kshrc file will not be executed on systems that support - this interactive initialization file. -08-03-07 A bug in which ksh -i did not run the ENV file has been fixed. -08-03-07 A bug in which ulimit did not always produce the same output as - ulimit -fS has been fixed. -08-03-04 A bug in multiline mode in emacs and vi mode which could cause the - cursor to be on the wrong line when interrupt was hit has been fixed. -08-03-03 The change made in ksh93s+ on 07-06-18 in which braces became - optional for ${a[i]} inside [[...]] was restored in the case - where the argument can be a pattern. -08-03-03 A bug in which creating a name reference to an associative array - instance would fail when the subscript contained characters [ or - ] has been fixed. -08-02-29 The redirection operator >; has been added which for non-special - files, generates the output in a temporary file and writes the - specified file only of the command has completed successfully. -08-02-15 A bug in ${var/pattern/string} for patterns of the form ?(*) and +(*) - has bee fixed. -08-02-07 A bug in which test \( ! -e \) produced an error has been fixed. -08-02-14 The typeset -a option can now optionally be followed by the name - of an enumeration type which allows subscripts to be enumerations. -08-02-14 The enum builtin which creates enumeration types has been added. -08-02-12 The backoff logic when there are no more processes has been fixed. -08-02-07 The -X option has been added to typeset. The -X option creates - a double precision number that gets displayed using the C99 %a - format. It can be used along with -l for long double. -08-01-31 The -T option to typeset has been added for creating typed - variables. Also the -h and -S options have been added to - typeset that are only applicable when defining a type. -08-01-31 The prefix expansion operator @ has been added. ${@name} - expands to the type of name or yields the attributes. -07-11-15 A bug in the macro expander for multibyte characters in which - part of the character contains a file pattern byte has been fixed. -07-10-03 A bug in which : was not allowed as part of an alias name has been - fixed. -07-09-26 A bug in which appending a compound variable to a compound variable - or to an index array didn't work has been fixed. -07-09-19 In both emacs and vi edit mode, the escape sequence \E[A (usually - cursor up, when the cursor is at the end of the line will fetch - the most recent line starting with the current line. -07-09-18 The value of ${!var} was correct when var was a reference to an - array instance. -07-09-18 The value of ${!var[sub]} was not expanding to var[sub] and this - was fixed. It also fixed ${name} where name is a name reference - to var[sub]. -07-09-18 It is now legal to create a name reference without an initialization. - It will be bound to a variable on the first assignment. -07-08-30 A discipline function can be invoked as ${x.foo} and is equivalent - to ${ x.foo;} and can be invoked as x.foo inside ((...)). -07-07-09 A bug in which typeset -a did not list indexed arrays has been - fixed. -07-07-03 The command substitution ${ command;} has been added. It behaves - like $(command) except that command is executed in the current - shell environment. The ${ must be followed by a blank or an - operator. - -08-04-17 --- Release ksh93s+ --- -08-04-17 A bug in which umask was not being restored correctly after a - subshell has been fixed. -08-04-15 A bug in which sending a STOP signal to a job control shell started - from within a shell function caused cause the invoking shell to - terminate has been fixed. -08-04-11 A bug which caused $(exec > /dev/null) to go into an infinite loop - has been fixed. -08-03-27 A bug in which typeset -LZ was being treated as -RZ has been fixed. -08-03-06 A bug with ksh -P on systems that support the the profile shell, - in which it would exit after running a non-builtin has been fixed. -08-01-31 A bug in which command substitution inside ((...)) could cause - syntax errors or lead to core dumps has been fixed. -08-01-17 A bug in which discipline functions could be deleted when invoked - from a subshell has been fixed. -08-01-17 A bug in which a command substitution consisting only of - assignments was treated as a noop has been fixed. -08-01-17 A bug in which discipline functions invoked from withing a - compound assignment could fail has been fixed. -08-01-16 Incomplete arithmetic assignments, for example ((x += )), now - generate an error message. -08-01-16 A bug in which a set discipline defined for a variable before - an array assignment could cause a core dump has been fixed. -08-01-03 A bug in on some systems in which exit status 0 is incorrectly - returned by a process that catches the SIGCONT signal is stopped - and then continued. -07-12-13 A race condition in which a program that has been stopped and then - continued could loose the exit status has been fixed. -07-12-12 Code to check for file system out of space write errors for all - writes has been added. -07-12-11 A bug in the macro expander for multibyte characters in which - part of the character contains a file pattern byte has been fixed. -07-12-06 A bug in the emacs edit mode when multiline was set that output - a backspace before the newline to the screen has been fixed. -07-12-04 A bug in which using <n>TAB after a variable name listing expansion - in the edit modes would cause the $ to disappear has been fixed. -07-11-28 A bug in which setting IFS to readonly could cause a subsequent - command substitution to fail has been fixed. -07-11-27 A work around for a gcc 4.* C99 "feature" that could cause a job - control shell to go into an infinite loop by adding the volatile - attribute to some auto vars in functions that call setjmp(). -07-11-27 A bug in which the shell could read ahead on a pipe causing the - standard input to be incorrectly positioned has been fixed. -07-11-27 A bug in which compound variable UTF-8 multibyte values were not - expanded or traced properly has been fixed. -07-11-21 A bug where an unbalanced '[' in a command argument was not treated - properly has been fixed. -07-11-15 A bug in which compatibility mode (no long option names) getopts(1) - incorrectly set the value of OPTARG for flag options has been fixed. -07-11-15 A bug in which "hash -- name" treated "--" as an invalid name operand - has been fixed. -07-11-15 typeset now handles "-t -- [-r] [--]" for s5r4 hash(1) compatibility. -07-11-15 A bug in which the umask builtin mis-handled symbolic mode operands - has been fixed. -07-11-15 Bugs in which shell arithmetic and the printf builtin mis-handled the - signs of { -NaN -Inf -0.0 } have been fixed. -07-11-15 The full { SIGRTMIN SIGRTMIN+1 ... SIGRTMAX-1 SIGRTMAX } range - of signals, determined at runtime, are now supported. -07-11-15 A bug in which creating an index array with only subscript 0 created - only a simple variable has been fixed. -07-11-14 A bug in which appending to an indexed array using the form - name+=([sub]=value) could cause the array to become an associative - array has been fixed. -07-11-14 A bug in which typeset without arguments could coredump if a - variable is declared as in indexed array and has no elements has - been fixed. -07-11-14 A bug in which creating a local SECONDS variable with typeset in - a function could corrupt memory has been fixed. -07-11-14 A bug which could cause a core dump when a script invoked by name - from a function used compound variables has been fixed. -07-11-05 A bug in which printf %d "'AB" did not diagnose unconverted characters - has been fixed. -07-11-05 printf %g "'A" support added for all floating point formats. -07-11-01 A bug in which typeset -f fun did not display the function definition - when invoked in a subshell has been fixed. -07-10-29 The sleep builtin was fixed so that all floating point constants - are valid operands. -07-10-10 A bug in which the locale was not being restored after - LANG=value command has been fixed. -07-09-20 A bug in which a nameref to a compound variable that was local - to the calling function would not expand correctly when displaying - is value has been fixed. -07-09-19 A bug which cause cause a core dump if .sh.edchar returned - 80 characters or more from a keyboard trap has been fixed. -07-09-14 A bug in which could cause a core dump when more than 8 file - descriptors were in use has been fixed. -07-09-10 A bug in which creating a name reference to an instance of - an array when the array name is itself a reference has been fixed. -07-09-10 The file completion code has been modified so that after an = in - any word, each : will be considered a path delimiter. -07-09-06 A bug in which subprocess cleanup could corrupt the malloc() heap - has been fixed. -07-08-26 A bug in which a name reference to an associative array instance - could cause the subscript to be evaluated as an arithmetic expression - has been fixed. -07-08-22 A bug in which the value of an array instance was of a compound - variable was not expanded correctly has been fixed. -07-08-14 A bug which could cause a core dump when a compound assignment was - made to a compound variable element with a typeset -a attribute - has been fixed. -07-08-08 A bug in which a trap ignored in a subshell caused it to be - ignored by the parent has been fixed. -07-08-07 A bug in which the set command would generated erroneous output - for a variable with the -RZ attribute if the variable name had been - passed to a function has been fixed. -07-08-02 A bug in which read x[1] could core dump has been fixed. -07-08-02 A second bug in which after read x[sub] into an associative array - of an element that hasn't been assigned could lead to a core dump - has been fixed. -07-07-31 A bug in which a pipeline that completed correctly could have - an exit status of 127 when pipefail was enabled has been fixed. -07-07-09 The SHOPT_AUDIT compile option has been added for keyboard logging. -07-06-25 In vi insert mode, ksh no longer emits a backspace character - before the carriage return when the newline is entered. -07-06-25 A bug in which pipefail would cause a command to return 0 - when the pipeline was the last command and the failure happened - on a component other than the last has been fixed. -07-06-25 A bug in the expansion of ${var/pattern/rep} when pattern or rep - contained a left parenthesis in single quotes has been fixed. -07-06-18 The braces for a subscripted variable with ${var[sub]} are now - optional when inside [[...]], ((...)) or as a subscript. -07-05-28 A bug in brace expansion in which single and double quotes did - not treat the comma as a literal character has been fixed. -07-05-24 The -p option of whence now disables -v. -07-05-23 Several bug fixes in compound variables and arrays of arrays - have been made. -07-05-15 A bug in which the %B format of printf was affected by the - locale has been fixed. -07-05-14 A bug in which \ was not removed in the replacement pattern with - ${var/pattern/rep} when it was not followed by \ or a digit has - been fixed. -07-05-10 A bug in which ksh -R file core dumped if no script was specified - has been fixed. it not displays an error message. -07-05-07 Added additional Solaris signals to signal table. -07-04-30 A bug in which a pipeline with command substitution inside a - function could cause a pipeline that invokes this function to - hang when the pipefail option is on has been fixed. -07-04-30 Added -q to whence. -07-04-18 A small memory leak with each redirection of a non-builtin has - been fixed. -07-03-08 A bug in which set +o output command line options has been fixed. -07-03-08 A bug in which an error in read (for example, an invalid variable - name), could leave the terminal in raw mode has been fixed. -07-03-06 A bug in which read could core dump when specified with an array - variable with a subscript that is an arithmetic expression has - been fixed. -07-03-06 Several serious bugs with the restricted shell were reported and - fixed. -07-03-02 If a job is stopped, and subsequently restarted with a CONT - signal and exits normally, ksh93 was incorrectly exiting with - the exit status of the stop signal number. -07-02-26 M-^L added to emacs mode to clear the screen. -07-02-26 A bug in which setting a variable readonly in a subshell would - cause an unset error when the subshell completed has been fixed. -07-02-19 The format with printf uses the new = flag to center the output. -07-02-19 A bug in which ksh93 did not allow multibyte characters in - identifier names has been fixed. -07-02-19 A bug introduced in ksh93 that causes global compound variable - definitions inside functions to exit with "no parent" has been fixed. -07-02-19 A bug in which using compound commands in process redirection - arguments would give syntax errors <(...) and >(...) has been fixed. -07-01-29 A bug which caused the shell to core dump which can occur when a - built-in exits without closing files that it opens has been fixed. -07-01-26 A bug in which ~(E) in patterns containing \ that are not inside () - has been fixed. - -06-12-29 --- Release ksh93s --- -06-12-29 A bug in which the value of IFS could be changed after a command - substitution has been fixed. -06-12-22 /dev/(tcp|udp|sctp)/HOST/SEVRICE now handles IPv6 addresses on - systems that provide getaddrinfo(3). -06-12-19 A -v option was added to read. With this option the value of - the first variable name argument will become the default value - when read from a terminal device. -06-11-20 A bug in which "${foo[@]:1}}" expands a null argument (instead of - no argument), when foo[0] is not empty has been fixed. -06-11-16 The discipline functions have been modified to allow each subscript - to act independently. Currently the discipline function will not - be called when called from a discipline function of the same variable. -06-11-14 A bug which could cause a core dump if a file descriptor for - an internal file was closed from with a subshell has been fixed. -06-10-30 The redirections <# pattern, and <## pattern have been added. - Both seek forward to the beginning of the next line that contains - the pattern. The <## form copies the skipped portion to standard - output. -06-10-26 On systems that support stream control transport, the virtual file - name /dev/sctp/host/port can now be used to establish connections. -06-10-26 The printf modifier # when used with d produces units in thousands - with a single letter suffix added. The modifier # when used with - the i specification provides units of 1024 with a two letter suffix. -06-10-24 The value of $! is now set to the process id of a job put - into the background with the bg command as required by POSIX. -06-10-23 A bug in which the value of $! was affected by a background - job started from a subshell has been fixed. -06-10-23 A bug in ${var:offset:len} in multibyte locales has been fixed. -06-10-15 The remaining math functions from C99 were added for any system - that supports them. -06-10-13 The klockwork.com software detected a few coding errors that - have been fixed. -06-10-12 A bug when skipping over `...` with ${x:=`...`} when x is set - has been fixed. -06-10-11 A bug in process floating constants produced by the %a format - of printf has been fixed. -06-10-06 A bug in which IFS was not being restored correctly in some - cases after a subshell has been fixed. -06-10-06 A bug in which pipefail was not detecting some failures in - pipelines with 3 or more states has been fixed. -06-10-03 A bug in the processing of >(...) with builtins which could - cause the builtin to hang has been fixed. -06-10-03 A bug in the for loop optimizer which causes >(...) process - substitution to be ignored has been fixed. -06-09-17 The -a option was added to typeset for indexed arrays. This - is only needed when using the ([subscript]=value ...) form. -06-09-06 The showme option was added. Each simple command not beginning - with a redirection and not occurring with in the while, until, if, - select condition can be preceded by a semi-colon which will - be ignored when showme is off. When showme is on, any command - preceded by a colon will be traced but not executed. -06-08-16 As a new feature, a leading ~(N) on a pattern has no effect - except when used for file expansion. In this case if not - matches are found, the pattern is replaced by nothing rather - than itself. -06-08-11 A bug in the expansion of ${.sh.match[i]:${#.shmatch[i]}} has - been fixed. -06-08-10 The read builtin options -n and -N have been modified to treat - the size as characters rather than bytes unless storing into a - binary (typeset -B) variable. -06-07-27 When the here document operator << is followed directly by a # - rather than a -, the first line of the here-document determines - how much whitespace is removed for each line. -06-07-26 A bug in the C-shell history (enabled with set -H) in which the - history event !$ was not processed has been fixed. -06-07-21 A bug on some systems in which assigning PATH on a command line - would not take effect has been fixed. -06-07-20 Add ksh93 and rksh93 as allowable names for ksh binaries. -06-07-20 Removed the SHOPT_OO compilation option which was only partially - implemented. -06-07-20 The ability to use egrep, grep, and fgrep expressions within - shell patterns has been documented. -06-07-17 A bug with arithmetic command expressions for locales in which - the comma is a thousands separator has been fixed. -06-07-13 The default HISTSIZE was increased from 128 to 512. -06-07-13 A multibyte problem with locales that use shift codes has been fixed. -06-06-23 A number of bug fixes for command, file, and variable completion - have been mode. -06-06-20 Floating point division by zero now yields the constant Inf or -Inf - and floating functions with invalid arguments yield NaN. -06-06-20 The floating point constants Inf and NaN can be used in arithmetic - expressions. -06-06-20 The functions isinf(), isnan(), tanhl() have been added for - arithmetic expressions. -06-06-13 Internal change to use ordering for variables instead of hashing - to speed up prefix matching. -06-06-13 A window between fork/exec in which a signal could get lost - and cause a program to hang has been eliminated -06-06-13 A bug in edit completion with quoted strings has been fixed. -06-06-07 The restricted options can now be enabled by set as well as on - the command line. Once set, it can not be disabled. -06-06-04 Modified built-in binding so that for systems for which /bin - and /usr/bin are the same, a builtin bound to /bin will get - selected when either /bin or /usr/bin is scanned. -06-06-04 Added literal-next character processing for emacs/gmacs mode. - This change is not compatible with earlier versions of ksh93 - and ksh88 when the stty lnext is control-v. The sequence - escape-control-v will display the shell version. -06-05-31 Modified emacs and vi mode so that entering a TAB after a partial - TAB completion, generates a listing of possible completions. - After the second TAB, a number followed by a TAB will perform - the completion with the corresponding item. -06-05-19 Modified arithmetic so that conversions to strings default to - the maximum number of precision digits. -06-05-16 Bug fixes for multibyte locales. -06-05-10 The =~ operator was added to [[...]] and [[ string ~= ERE ]] - is equivalent to [[ string == ~(E)ERE ]]. -06-04-25 A bug in the vi edit mode which could cause the shell to core dump - when switching from emacs mode. -06-04-17 A bug in which using LANG or LC_ in assignment lists with builtins - did not restore the localed correctly has been fixed. -06-04-04 A bug in which discipline functions could not be added to variables - whose names started with .sh has been fixed. -06-03-28 The -s option to typeset was added to modify -i to indicate short - integers. -06-03-28 A bug in which variables assignment lists before functions - defined with function name were not passed on the functions - invoked by this function has been fixed. -06-03-28 A bug in which name references defined within a function defined - with function name could not be used with compound variables has - been fixed. -06-03-27 A bug in which read <&p (print >&p) would cause the coprocess input - (output) pipe to close before reading from (after writing to) - it has been fixed. -06-02-28 A bug in which stopping a job created with the hist builtin command - would create a job that could not be restarted has been fixed. - -06-01-24 --- Release ksh93r --- -06-01-24 A bug in which running commands with standard output closed would - not work as expected has been fixed. -06-01-23 A bug in which print -u<n> could fail when file descriptor <n> was - open for writing has been fixed. -06-01-19 The ?: arithmetic operator fixed to work when the operation after - the colon was an assignment. -05-12-24 A bug which could lead to a core dump when elements of a compound - variable were array elements, i.e. foo=(bar=(1 2)), has been fixed. -05-12-13 An arithmetic bug in which x+=y+=z was not working has been fixed. -05-12-13 An arithmetic bug in which x||y was returning x when x was non-zero - rather than 1 has been fixed. -05-12-07 The aliases for integer and float have been changed to use attributes - -li and -lE to handle long long and long double types. -05-12-07 The histexpand (-H) option has been added which allows C-shell - style history expansions using the history character !. -05-12-07 The multiline option was added which changes that way the edit - modes handle lines longer than the window width. Instead of - horizontal scrolling, multiple lines on the screen are used. -05-12-05 The whence builtin now returns an absolute pathname when the - command is found in the current directory. -05-11-29 A bug which caused ksh -c '[[ ! ((' to core dump rather than - report a syntax error has been fixed. -05-11-29 A bug when reading fixed length records into typeset -b variables - which caused a zero byte to terminate the value has been fixed. -05-11-22 The ability to seek to an offset within a file has been added - with the new I/O redirection operators, <# and >#. Currently, - these redirection operators must be followed by ((expr)) - but in a future release, it should be able to used to seek forward - to the specified shell pattern. In addition $(n<#) expands to the - current byte offset for file descriptor n. -05-11-22 The .sh.match array variable is now set after each [[ ... ]] - pattern match. Previously it was only set for substring matches. -05-10-17 A bug in which the library path variable could be prefixed - with a directory when a .path file was not encountered in - the directory of the executable has been fixed. -05-09-15 A for/while loop optimizer bug in which $OPTIND was not - correctly expanded has been fixed. -05-09-05 A bug in which a history command that invoked a history - command could go into an infinite loop has been fixed. -05-08-31 In the case that IFS contains to adjacent new-lines so that - new-line is not treated as a space delimiter, only a single - new-line is deleted at the end of a command substitution. -05-08-19 When a tilde substitution expands to the / directory and is - followed by a /, it is replaced by the empty string. -05-08-16 A bug in which n<&m did not synchronize m has been fixed. -05-08-16 A bug in which process substitution ( <() and >() ) was not - working within for and while loops has been fixed. -05-07-24 A bug in which the pattern ~(E)(foo|bar) was treated as a syntax - error has been fixed. -05-07-24 A bug in completion with <n>=, where n was the one of the - previous selection choices has been fixed. -05-07-21 A bug with multibyte input when no edit mode was specified which - caused the input line to shift left/right has been fixed. -05-06-24 A race condition which could cause the exit status to get lost - on some fast systems has been fixed. -05-06-21 A bug in which nested patterns of the form {m,n}(pat) would cause - syntax errors has been fixed. -05-06-21 A bug in the macro expander has been fixed which could cause a - syntax error for an expansion of the form ${x-$(...)} when - x is set and the command substitution contained certain strings. -05-06-08 On systems for which echo does not do System V style \ expansions, - the -e option was added to enable these expansion. -05-06-08 A bug in which ${var op pattern} to not work when inside an - arithmetic expression has been fixed. -05-05-23 An extension to shell patterns that allows matching of nested - groups while skipping over quoted strings has been added. -05-05-18 A bug in which the line number for errors was not correct for - functions loaded from FPATH has been fixed. -05-04-18 A bug in which the exit status $? is not set when a trap triggered - by the [[...]] command is executed has been fixed. -05-04-08 Redirection operators can be directly preceded with {varname} - with no intervening space, where varname is a variable name which - allows the shell to select a file descriptor > 10 and store it - into varname. -05-04-08 SHOPT_CMDLIB_BLTIN=1 now includes <cmdlist.h> generated table. -05-04-07 [[ -o ?option ]] is true if "option" is a supported option. -05-04-05 A bug in handling file completion with spaces in the names - has been fixed. -05-03-25 The SIGWINCH signal is caught by default to keeps the LINES and - COLUMNS variables in sync with the actual window size. -05-03-25 Building ksh with SHOPT_REMOTE=1 causes ksh to set --rc if stdin is - a socket (presumably part of a remote shell invocation.) -05-03-25 Building ksh with SHOPT_SYSRC=1 causes interactive ksh to source - /etc/ksh.kshrc (if it exists) before sourcing the $ENV file. -05-03-25 {first..last[..incr][%fmt]} sequences added to brace expansions - when braceexpand is enabled. -05-03-03 A bug where a SIGCHLD interrupt could cause a fifo open to fail has - been fixed. -05-02-25 A bug in which a builtin command run in the background could - keep a file descriptor open which could cause a foreground - process to hang has been fixed. -05-02-24 A bug where builtin library commands (e.g., date and TZ) failed to - detect environment variable changes has been fixed. -05-02-22 The read builtin and word splitting are now consistent with respect - to IFS -- both treat IFS as field delimiters. -05-02-22 The read builtin no longer strips off trailing delimiters that - are not space characters when there are fewer variables than fields. -05-02-17 A builtin bug on systems where dlsym(libcmd) returns link-time - bindings has been fixed. -05-02-12 A bug in which the lib_init() function for .paths BUILTIN_LIB - libraries was not called has been fixed. -05-02-06 A bug on some systems in which moving the write end of a co-process - to a numbered file descriptor could cause it to close has been fixed. -05-02-06 A bug in the vi-edit mode in which the character under the cursor - was not deleted in some cases with the d% directive has been fixed. -05-02-06 A bug where external builtin stdout/stderr redirection corrupted - stdout has been fixed. -05-02-04 A bug where times formatting assumed CLK_TCK==60 has been fixed. - -05-01-11 --- Release ksh93q --- -05-01-11 A bug in the integral divide by zero check has been fixed. -05-01-11 The -l option has been added to read /etc/profile and - $HOME/.profile, if they exist, before the first command. -05-01-11 An argument parsing bug that caused `kill -s x -- n' to fail has - been fixed. -05-01-11 The .paths file, introduced in ksh93m, which can appear in - any directory in PATH, now allows a line of the form 'BUILTIN_LIB=.' - When a command is searched for this directory, and the full path - matches the path of the built-in version of the command (listed - by the 'builtin' command) then the built-in version of the command - is used. When ksh is built with SHOPT_CMDLIB_DIR=1 then all libcmd - functions become builtins with the '/opt/ast/bin/' directory prefix. -05-01-10 A bug in which a nameref to a compound name caused a core dump has - been fixed. -05-01-09 A bug in which some SIGCHLD interrupts (from child processes exiting) - caused a fatal print/echo error diagnostic has been fixed. -04-12-24 A bug in which some SIGCHLD interrupts (from child processes exiting) - corrupted the internal process/job list, sometimes causing the shell - to hang, has been fixed. -04-12-01 A bug in which typeset -Fn truncated less than n digits for large - numbers has been fixed. -04-11-25 A bug in which standard error could be closed after a redirection - to /dev/stderr has been fixed. -04-11-17 A bug in which an expansion of the form ${array[@]:3} could expand - to ${array[0]} when ${array[3]} was not set has been fixed. -04-10-22 The -E or -orc command line option reads ${ENV-$HOME/.kshrc} file. -04-10-22 `-o foo' equivalent to `+o nofoo', `-o nobar' equivalent to `+o bar'. - `--foo' equivalent to `-o foo', `--nofoo' equivalent to `+o foo' -04-10-05 The .paths file, introduced in ksh93m, which can appear in - any directory in PATH, now allows a line of the form - 'BUILTIN_LIB=libname'. When a command is searched for this directory, - the shared library named by libname will first be searched for a - built-in version of the command. -04-09-03 <<< here documents now handle quotes in the word token correctly. -04-08-08 The maximum size for read -n and and read -N was increased from - 4095 to 32M. -04-08-04 printf %q was modified so that if an no operand was supplied, no - no output would be generated rather than a quoted empty string. -04-08-01 The -n and -N options of the read builtin has been modified - when reading variables with the binary attribute so that the - data is stored directly rather than through assignment. -04-08-01 The shcomp command has been modified to process alias commands - under some conditions. -04-07-31 The .sh.match variable added in ksh93l, now works like other - indexed arrays. -04-07-08 A loop optimizer bug which occurs when typeset is used in - a for or while loop inside a function has been fixed. -04-06-24 The number of subexpressions in a pattern was increased to 64 - from the current number of 20. -04-06-17 The -t option to read was modified to allow seconds to be - specified as any arithmetic expression rather than just - an integral number of seconds, for example even -t 'sin(.5)' - is now valid. -04-06-16 Two small memory leak problems were fixed. -04-06-15 A bug in ${var/pattern/"string"} which occurred when string - contained pattern matching characters has been fixed. -04-05-08 printf $'%d\n' produced an erroneous error message and has - been fixed. -04-05-24 A bug in which an associative array without any elements could - cause a core dump when a script with an associative array with - the same name was declared in a script invoked by name has - been fixed. -04-05-11 A bug in which an exec statement could close the script that - is being processed in a script that is run by name causing - a failure has been fixed. -04-04-28 If the first character of assignment to an integer variable was 0, - the variable had been treated as unsigned. This behavior was - undocumented and has been removed. -04-04-05 A bug in which the positioning of standard input could be incorrect - after reading from standard input from a subshell has been fixed. -04-03-30 A bug in the for loop optimizer which in rare cases could cause - memory corruption has been fixed. -04-03-29 The preset alias source='command .' has been added. -04-03-29 A bug introduced in ksh93p on some systems in which invoked by - name with #! on the first line would not get the signals handling - initialized correctly has been fixed. -04-03-29 A bug introduced in ksh93p in which a HUP signal received by - a shell that is a session group leader was not passed down to - its children has been fixed. - -04-02-28 --- Release ksh93p --- -04-02-28 The ability to apply an append discipline to any variable has - been added. -04-02-14 A bug in which the exportall option (set -a) would cause incorrect - results for arrays has been fixed. -04-02-02 A bug in which an exported array would pass more than - the first element to a script invoked by name has been fixed. -04-02-02 A bug on some systems in which name=value pairs preceding a script - invoked by name was not getting passed to the script has been fixed. -04-01-20 A bug in which an unset discipline function could cause a core - dump on some systems has been fixed. -04-01-12 A bug in which a continue or break called outside a loop from - inside a function defined with name() syntax could affect - the invoking function has been fixed. -04-01-08 If a command name begins with ~, only filename completion will be - attempted rather than pathname completion using the builtin editors. -04-01-08 A bug in the vi edit mode in which the wrong repeat count on - multiple word replacements with the . directive has been fixed. -04-01-06 Backspace characters are now handled correctly in prompt strings. -04-01-06 The getopts builtin has been modified to accept numerical - arguments of size long long on systems that support this. -04-01-06 A bug in which unsetting all elements of an associative array - would cause it to be treated as an indexed array has been fixed. -03-12-15 A bug in which a quoted string ending with an unescaped $ would - delete the ending $ in certain cases has been fixed. -03-12-05 A bug in which the shell could hang when set -x tracing a command - when an invalid multibyte character is encountered has been fixed. -03-12-05 On some systems, if the KEYBD trap is set, then commands that use - the meta key were not processed until return was hit. This - has been fixed. -03-12-05 A problem which occurred when the login shell was not a group - leader that could cause it to fail has been fixed. -03-12-05 A problem in which a shell could core dump after receiving a signal - that should cause it to terminate while it was in the process - of acquiring more space has been fixed. -03-12-05 If ENV is not specified, the shell will default to $HOME/.kshrc - for interactive shells. -03-11-21 A bug introduced in ksh93o in which the DEBUG trap could get - disabled after it triggered has been fixed. -03-11-04 A bug in which using arithmetic prefix operators ++ or -- on a - non-lvalue could cause a core dump has been fixed. -03-11-04 A bug in which leading zeros were stripped from variable - expansions within arithmetic computation to avoid being treated - as octal constants when they should not have, has been fixed. -03-10-08 A bug introduced in ksh93o in which a large here document inside - a function definition could get corrupted has been fixed. -03-09-22 A bug in which the .get discipline function was not being - called when a string variable was implicitly referenced from - within a numerical expression has been fixed. -03-09-22 A bug in which a script without a leading #! could get executed - by /bin/sh rather than the current shell on some systems has - been fixed. -03-09-12 To improve conformance with ksh88, leading zeros will be ignored - when getting the numerical value of a string variable so that - they will not be treated as octal constants. -03-09-03 The builtin kill command now processes obsolete invocations - such as kill -1 -pid. -03-09-02 The restriction on modifying FPATH in a restricted shell (sh -r) - has been documented. -03-09-02 The restricted shell (sh -r) has been modified to disallow - executing command -p. -03-08-07 A bug in which the KEYBD trap was not being invoked when - characters with the 8th bit set has been fixed. -03-08-02 A parser bug introduced in ksh93o which caused the character - after () in a Posix function definition to be skipped - when reading from standard input has been fixed. -03-08-01 A bug in which "${foo#pattern}(x)" treated (x) as if it were - part of the pattern has been fixed. -03-08-01 The command -x option has been modified so that any trailing - arguments that do expand to a single word will be included - on each invocation, so that commands like command -x mv * dir - work as expected. - -03-07-20 --- Release ksh93o+ --- -03-07-20 A bug in which could cause memory corruption when a posix - function invoked another one has been fixed. -03-07-15 A bug in which a file descriptor>2 could be closed before - executing a script has been fixed. -03-07-15 A parsing error for <() and >() process substitutions inside - command substitution has been fixed. -03-07-15 A parsing error for patterns of the form {...}(...) when - used inside ${...} has been fixed. -03-07-15 An error in which expanding an indexed array inside a compound - variable could cause a core dump has been fixed. -03-07-15 A bug in which on rare occasions a job completion interrupt - could cause to core dump has been fixed. -03-06-26 A bug in which process substitution embedded within command - substitution would generate a syntax error has been fixed. -03-96-23 A bug in which ${@:offset:len} could core dump when there - were no arguments has been fixed. -03-96-23 A bug in which ${X[@]:offset:len} could core dump when X - was unset has been fixed. -03-06-22 The -x option was added to the command builtin. If this - option is on, and the number of arguments would exceed ARG_MAX, - the command will be invoked multiple times with a subset of - the arguments. For example, with alias grep='command -x grep, - any number of arguments can be specified. -03-06-14 A bug in which could cause a core dump on some systems with - vi and emacs editors with the MULTIBYTE option has been fixed. -03-06-06 A bug in which the shell could core dump when a script was - run from its directory, and the script name a symlink to a file - beginning with .., has been fixed. -03-06-05 A bug in which the shell could core dump when a child process - that it is unaware of terminates while it is calling malloc() - has been fixed. -03-06-02 An option named globstar (set -G) has been added. When enabled, - during pathname expansion, any component that consists only of ** is - matches all files and any number of directory levels. -03-05-30 A bug in which the PATH search could give incorrect results when - run from directory foo and PATH contained .:foo:xxx has been fixed. -03-05-29 Some changes were made to the code that displays the prompt in edit - mode to better handle escape sequences in the prompt. -03-05-27 I added = to the list of characters that mark the beginning of - a word for edit completion so that filenames in assignments - can be completed. -03-05-20 A bug in which read -N could hang on some systems when reading - from a terminal or a pipe has been fixed. -03-05-19 A bug in which the output of uname from a command substitution - would go to the standard output of the invoking command when - uname was invoked with a non-standard option has been fixed. -03-05-19 A job control bug which would cause the shell to exit because - it hadn't take back the terminal has been fixed. The bug - could occur when running a function that contained a pipeline - whose last element was a function. -03-05-19 A job control timing bug introduced in ksh93o on some systems - which could cause a pipeline to hang if the first component - completed quickly has been fixed. -03-05-13 The read builtin has been modified so that the builtin editors - will not overwrite output from a previous incomplete line. -03-05-13 A bug in which the name of an identifier could have the string - .sh. prefixed to it after expanding a variable whose name begins - with .sh. has been fixed. -03-05-13 A bug in the expansion of $var for compound variables in which - some elements would not be output when the name was a prefix - of another name in the compound variable has been fixed. -03-05-08 The last item in the ksh93o release on 03-01-02 has been - altered slightly to preserve the leading 0's when the - preceding character is a digit. Thus, with typeset -LZ3 x=10, - $(( 1$x)) will be 1010 whereas $(( $x) will be 10. -03-04-25 A bug in which if x is a name reference, then nameref y=x.foo - did not follow x has been fixed. - -03-03-18 --- Release ksh93o --- -03-03-18 A -N unary operator was added to test and [[...]] which returns - true if the file exists and the file has been modified since it - was last read. -03-03-18 The TIMEFORMAT variable was added to control the format for - the time compound command. The formatting description is - described in the man page. -03-03-06 A -N n option was added to read which causes exactly n bytes - to be read unlike -n n which causes at most n bytes to be read. -03-03-03 Three new shell variables were added. The variable .sh.file - stores the full pathname of the file that the current command - was found in. The variable .sh.fun names the current function - that is running. The variable .sh.subshell contains the depth - of the current subshell or command substitution. -03-03-03 When the DEBUG trap is executed, the current command line after - expansions is placed in the variable .sh.command. The trap - is also now triggered before each iteration of a for, select, - and case command and before each assignment and redirection. -03-02-28 Function definitions are no longer stored in the history file so - that set -o nolog no longer has any meaning. -03-02-28 All function definitions can be displayed with typeset -f not - just those stored in the history file. In addition, typeset +f - displays the function name followed by a comment containing the - line number and the path name for the file that defined this function. -03-02-28 A bug in which the value of $LINENO was not correct when executing - command contained inside mult-line command substitutions has been - fixed. -03-02-19 Since some existing ksh88 scripts use the undocumented and - unintended ability to insert a : in front of the % and # parameter - expansion operators, ksh93 was modified to accept :% as equivalent - to % and :# as equivalent to # with ${name op word}. -03-02-14 A bug which could cause a core dump when reading from standard - error when standard error was a pty has been fixed. -03-02-14 The shell arithmetic was modified to use long double on systems - that provide this data type. -03-02-09 A bug in which a function located in the first directory in FPATH - would not be found when the last component of PATH was . and the - current directory was one of the directories in PATH has been fixed. -03-02-07 The trap and kill builtin commands now accept a leading SIG prefix - on the signal names as documented. -03-02-05 A bug in the expansion of ${var/$pattern}, when pattern contained - \[ has been fixed. -03-02-05 A bug in which .sh.match[n], n>0, was not being set for substring - matches with % and %% has been fixed. -03-01-15 A bug in which getopts did not work for numerical arguments specified - as n#var in the getopts string has been fixed. -03-01-09 A bug in which using ${.sh.match} multiple times could lead to - a memory exception has been fixed. -03-01-06 A bug in the expansion of ${var/pattern/$string} in the case that - $string contains \digit has been fixed. -03-01-02 A -P option was added for systems such as Solaris 8 that support - profile shell. -03-01-02 For backward compatibility with ksh88, arithmetic expansion - with ((...)) and let has been modified so that if x is a zero-filled - variable, $x will not be treated as an octal constant. - -02-12-05 --- Release ksh93n+ --- -02-11-30 A bug that can show up in evaluating arithmetic statements that - are in an autoloaded function when the function is autoload from - another function has been fixed. -02-11-30 An optimization bug in which an expansion of the form ${!name.@}, - which occurred inside a for or a while loop, when name is a name - reference, has been fixed. -02-11-18 A bug in which modifying array variables in a subshell could leave - side effects in the parent shell environment has been fixed. -02-11-18 A memory leak when unsetting an associative array has been fixed. -02-11-14 The code to display compound objects was rewritten to make - it easier for runtime extensions to reuse this code. -02-11-14 A change was made to allow runtime builtins to be notified when - a signal is received so that cleanup can be performed. -02-10-31 User applications can now trap the ALRM signal. Previously, - the ALRM signal was used internally and could not be used - by applications. -02-10-31 A bug in which signals received while reading from a coprocess - for which traps were set was not handled correctly has been fixed. -02-10-31 A bug in which a file opened with exec inside a subshell could - be closed before the subshell completed has been fixed. -02-10-21 A bug in which setting PATH or FPATH inside a function might not - take effect has been fixed. -02-10-21 A bug which could cause a core dump when a local SECONDS variable - is defined in a function has been fixed. -02-10-15 A bug in which the associate array name operator ${!array[@]} - could return the same name multiple times has been fixed. -02-10-15 A bug in which the zero'th element of an associative array was - not getting set when an assignment was made without a subscript - specified has been fixed. - -02-09-30 --- Release ksh93n --- -02-09-30 The maximum indexed array size was increased to 16Megs. -02-09-30 A bug which could cause a core dump when changing attributes - of associative array has been fixed. -02-09-30 A bug in which exporting an array variable would not export the - 0-th element has been fixed. -02-09-30 A bug in which an array assignment of the form a=($a ...) would unset - 'a' before the right hand side was evaluated has been fixed. -02-09-27 A bug in which the error message for ${var?message} when var was - null or unset did not contain the variable name var has been fixed. -02-09-27 A bug in which closing file descriptors 0 through 2 could - cause a subsequent here document to fail has been fixed. -02-09-14 A bug in whence which occurs when the specified name contained - a / has been fixed. -02-09-14 A bug in the parser for strings of the form name$((expr))=value - has been fixed. -02-09-14 A for loop optimization bug in which the number of elements in - an array was treated as an invariant has been fixed. -02-09-09 A bug in which redirection or closing of a file descriptor between - 3 and 9 could cause a subsequent here document to fail has been - fixed. -02-09-09 A bug in which a background job was not removed from the job list - when a subshell completed has been fixed, for example (prog&). -02-09-03 A bug in which an assignment of the form name=(integer x=3) - could be interpretted as an array assignment rather than a - compound variable assignment has been fixed. -02-08-19 A command completion bug which occurred on file systems that - are case insensitive has been fixed. -02-08-19 A bug which could lead to an exception on some systems (for - example FREEBSD) which occurred when setting PATH has been fixed. -02-08-11 A bug in arithmetic rounding in which a value input as a decimal - string would output as a rounded version of the string has - been fixed. -02-08-11 A bug in which the last character could be deleted from shell - traces and from whence when called from a multibyte locale - has been fixed. -02-08-01 A bug which could cause a core dump to occur when a shell script - is executed while a coprocess is running that has closed the - output pipe has been fixed. -02-08-01 A bug in which command completion in multibyte mode could - corrupt memory for long command lines has been fixed. - -02-06-17 --- Release ksh93n- --- -02-06-17 A bug in which user defined macros could cause a core dump in - with MULTIBYTE mode has been fixed. -02-06-17 A bug in which printf format specifiers of the form %2$s were causing - a core dump has been fixed. -02-06-17 A bug in which setting stty to noecho mode did not prevent the - echoing of characters by ksh when emacs or viraw mode - was enabled has been fixed. -02-06-17 A bug in which background job completion could cause the sleep - builtin to terminate prematurely has been fixed. -02-06-17 A bug in which the shell could core dump if getopts was called - when the OPTIND variable contained a negative value has been fixed. -02-06-10 The edit mode prompt has been modified to handle escape sequences. -02-06-10 A bug which occurred for interactive shells in which the builtin - cat command was used in command substitution on a file whose - size was larger than PIPE_BUF has been fixed. -02-06-10 A bug in which the trap on ERR was not being processed when - set inside a function has been fixed. -02-06-07 A bug in which function definitions could cause the history count - to be decremented by one (and even become negative) has been fixed. -02-06-05 A bug in read in which share mode could be enabled has been fixed. -02-05-28 A bug which could occur when the last command of a script was - a case statement and the action selected ended in ;& instead of ;; - has been fixed. -02-05-23 A bug with unary + introduced in ksh93k has been fixed. -02-05-07 A bug in substitutions of the form ${var/pattern/string} in which - a backslash was inserted in the replacement string when it contained - a special pattern character has been fixed. -02-05-01 A bug in the emacs edit mode which occurred in versions compiled - for multibyte character sets which occurred when a repeated search - was requested after a long line had been returned for the previous - search has been fixed. -02-04-02 vi and emacs edit modes were modified so that tab completion is - disabled when invoked from the read built-in. - -02-03-26 --- Release ksh93m+ --- -02-03-26 A bug in which \ was not handled correctly when used in file - expansion has been fixed. -02-02-18 A bug in which lines beginning with a # were deleted from here - documents when the here-document delimiter was followed by - a comment has been fixed. -02-12-06 An optimization bug in which ${!x[@]) was treated as invariant in - a for loop has been fixed. -02-02-06 A bug in which the ERR trap is not cleared for a script invoked - by name from within a function has been fixed. -02-01-08 A bug in which a shell script executed from within a subshell - could cause this script to have an invalid pointer leading - to a memory fault has been fixed. -02-01-07 Added here documents of the form <<< word (as per zsh) which - is equivalent to << delim\nword\ndelim. -02-01-07 A bug in which the first word of a compound assignment, - x=(word ...), was treated as a reserved word has been fixed. -02-01-07 A bug in the handling of \ when noglob was enabled and a - substitution of the form ${word op pattern} occurred in the - same word has been fixed. -02-01-07 A compilation option, CMDLIB_BLTIN in the file OPTION, has - been added. When this options is set, all commands implemented - in libcmd become shell builtin commands by default. -02-01-07 A bug in which builtin foo, where foo is already a builtin - would result in the builtin foo getting removed has been fixed. -02-01-07 A bug which the shell executed a command found in the current - directory when PATH have no valid directories has been fixed. -01-11-28 The value of $? was not being set when called with exit. -01-11-28 If the last command was of the form (...) and a trap on EXIT or - ERR was set, and the command inside () modified the trap, then - the original trap wasn't executed. -01-11-26 The value for 0 is now preceded by the base number when - the base was not 10. -01-11-26 The default has compilation mode has been changes so that - viraw mode will always be on. - -01-10-31 --- Release ksh93m --- -01-10-31 A for loop optimizer bug for subshells contained withing for - loops has been fixed. -01-10-16 typeset without arguments no longer outputs variable names - that do not have any attributes that are set. -01-10-16 A bug introduced in ksh93l in which assignments specified with - the exec built-in were not being expanded properly has been - fixed. -01-10-11 An optimization bug in which ${!x) was treated as invariant in - a for loop has been fixed. -01-10-11 Unsigned integer variables in bases other than 10 are printed now - expand in that base with the base prefix. -01-10-10 A number of typos in the self generating man pages for shell - built-ins have been fixed. -01-10-04 The self generated man pages for hist and fc were not working - correctly and have been fixed. -01-10-03 Yet another optimizer bug in which shell patterns were - treated as invariants has been fixed. -01-09-27 Two bugs relating to multibyte history searches and to find - have been fixed. -01-09-27 A bug introduced in ksh93k in which the PATH searching was - not restored after running a command with an assignment list - has been fixed. -01-09-26 A bug in which a zero filled field was treated as octal when - converted to integer has been fixed. -01-09-26 Yet another bug in the optimization of for loops related to - recursive functions with break or continue statements has been fixed. -01-09-25 The exponentiation operator ** was added to the shell arithmetic - evaluation. It has higher precedence than * and is left - associative. -01-09-25 The code was modified to use the ast multibyte macros - and functions for handing multibyte locales. -01-09-25 The expansion ${parameter:offset:length} now handles negative - offsets which cause offsets to be measured from the end. -01-09-25 Some spelling errors in the documentation were corrected. -01-09-24 The /dev/tcp/host/port and /dev/udp/host/port now allow - the ports to be specified by service name. -01-09-24 The change staring with ksh93g in which the the appropriate - library path variable is prepended with a corresponding library - directory has been modified. With the new method, only the - library path defined in the file named .paths in the directory - where the executable is found will be modified. See the - man page for more details. -01-09-23 The .fpath file (see ksh93h) is no longer looked for in each - directory on the path to locate function directories. The - file named .paths is used instead. -01-09-23 A bug in which IFS was not being restored after being changed in - a subshell has been fixed. -01-09-16 With the vi and emacs edit modes, after a list of command - or functions is generated with = or M-= respectively, - any element from the list can be pasted on the command line - by preceding the = or M-= with a numeric parameter specifying - the position on the list. -01-09-16 A bug in ksh93l caused command completion not to find aliases - and functions. Command listing from the edit mode was presented - in reverse order. This has been fixed. -01-09-13 Another bug in the optimization of for loops related to subshells - when traps were set has been fixed. -01-09-07 A change in ksh93l caused brace expansion to stop working - and this has been fixed. -01-09-04 A bug introduced in ksh93k in which an arithmetic statement - within a function that used name references did not follow the - reference has been fixed. -01-09-04 A bug introduced in ksh93l in which export -p did not prefix - each export with the word export has been fixed. -01-08-29 A bug in multibyte input which occurred when a partial multibyte - character was received has been fixed. -01-08-29 A bug introduced in ksh93l which could cause a core dump - when an assignment list containing PATH is specified inside - command substitution has been fixed. -01-08-09 Another bug in the optimization of for loops in ksh93l caused - errors in recursive functions using local variables that - contained for loops has been fixed. -01-07-27 A bug in which IFS would be unset after a command substitution - inside a here document has been fixed. -01-07-26 To conform to the POSIX standard, if you invoked ksh name, - and name does not contain a /, it will first try to run - one in the current directory whether it is executable or not - before doing a path search for an executable script. Earlier - versions first checked for an executable script using the - PATH variable. -01-07-23 A bug in which unset -f invoked in a subshell could unset a - function defined in the parent has been fixed. -01-07-16 A bug in the optimization of for loops in ksh93l caused - name references to be treated as invariants has been fixed. -01-07-09 A bug in which a discipline function applied to a local variable - could cause a shell exception has been fixed. Discipline - functions can only be specified for global variables. - -01-06-18 --- Release ksh93l --- -01-06-18 A bug in assigning integers larger than can be represented as - long integers to floating point variables has been fixed. -01-06-18 A bug in the handling of unsigned integers (typeset -ui) has - been fixed. -01-06-04 The evaluation of the PS1 prompt no longer effects the value - of the $? variable. -01-06-01 A small memory leak from subshells has been fixed. -01-05-22 A bug in which attributes for variables that did not have - values would be lost after a subshell has been fixed. -01-05-22 The %R format has been added to convert a shell pattern into - an extended regular expression. -01-05-22 The escape sequences \e, \cX, \C[.collating-element.], and - \x{hex} have been added to ASCII-C strings and to printf format - strings. -01-05-20 Patterns of the form {n}(pattern) and {m,n}(pattern) are now - recognized. The first form matches exactly n of pattern whereas, - the second form matches from m to n instances of pattern. -01-05-20 The shell allows *-(pattern), +-(pattern), ?-(pattern), - {m,n}-(pattern}, and @-(pattern) to cause the minimal - match of pattern to be selected whenever possible rather - than the maximal (greedy) match. -01-05-20 The character class [:word:] has been added to patterns. - The word class is the union of [:alnum:] and the character _. -01-05-20 Inside (...) pattern groups, the \ character is now treated - specially even when in an enclosing character class. The - sequences, \w, \d, \s are equivalent to the character classes - word, digit, and space respectively. The sequences \W, \D, - and \S are their complement sets. -01-05-20 The shell now recognizes pattern groups of the form - ~(options:pattern) where options or :pattern can be omitted. - Options use the letters + and - to enable and disable options - respectively. The option letters g (greedy), i (ignore case) - are used to cause maximal matching and to cause case - insensitive matching respectively. If :pattern is also - specified, these options are only in effect while this - pattern is being processed. Otherwise, these options remain - in effect until the end of the pattern group that they are contained - in or until another ~(...) is encountered. These pattern groups - are not counted with respect to group numbering. -01-05-14 When edit completion, expansion, or listing occurs in the - middle of a quoted string, the leading quote is ignored when - performing the completion, expansion, or listing. -01-05-14 A small memory leak from subshells has been fixed. -01-05-10 A bug in which open files were not restored after a subshell - that had used exec to replace a file has been fixed. -01-05-10 Redirection to a null file name now generates an error message. -01-05-09 The shell now rejects some invalid parameter substitutions that - were previously processed in undefined ways. -01-05-09 A bug in which the output of select was not flushed before the - read when input did not come from the terminal has been fixed. -01-05-08 A bug in which job ids would not be freed for interactive shells - when subshells ran built-ins in the background has been fixed. -01-05-08 The FPATH variable now requires an explicit . to cause the - current directory to be treated as a function directory. -01-05-08 A bug in read -n when echo mode was disabled has been fixed. -01-05-07 A bug in which function definitions could be listed as part - of the history has been fixed. -01-04-30 This release uses a new and often much faster pattern matcher than - earlier releases. -01-04-30 An optimizer now eliminates invariant parameter expansions from - for while and until loops. -01-04-30 The variable .sh.match is set after each pattern match (# % or /) - in a variable substitution. The variable .sh.match is an - indexed array with element 0 being the complete match. - The array is only valid until the next subsequent pattern - match or until the value of the variable changes which ever - comes first. -01-04-30 A self generating man page has been added to shcomp. Also, - shcomp now stops compiling when it finds an exit or exec - command and copies the remainder so that it can be used - for standard input. -01-04-30 The shcomp command was modified so that it can work in an - EBCIDIC environment and that binary scripts are portable - across environments. -01-04-30 A bug in the handling of a trailing : in PATH has been fixed. -01-04-30 A bug in which the builtin version of a command would get invoked - even though the full pathname for the command was specified - has been fixed. -01-04-30 A bug in which read would loose the last character when - reading the last line of a file that did not contain a new-line - character has been fixed. -01-04-23 A bug on some systems in which in vi mode the end of file - character and end of line character could be swapped has - been fixed. -01-04-23 A bug on some systems in which invoking a shell script that - did not have execute permission could set the exit value to - 127 rather than 126 has been fixed. -01-04-20 A bug in which read -n from a pipe would block if fewer than - n characters was received has been fixed. -01-04-09 A bug in which invalid patterns, for example, ) by itself, - was not treated as a string has been fixed so that if i=')', - then [[ $i == $i ]] is true. -01-04-09 The shell arithmetic now interprets C character constants. -01-04-09 A bug in which a non-zero return from a function defined - with the function reserved word did not trigger the ERR - trap or exit with set -e has been fixed. -01-04-02 A bug on some systems, in which characters above 127 were - not displayed correctly in vi or emacs edit mode has been fixed. -01-04-02 A bug on some systems, introduced in the 'k' point release, in - which the erase character in viraw mode was moving the cursor - to the left without erasing the character has been fixed. -01-04-02 On some systems the wcwith() function was returning a wrong - value for characters and caused characters to be displayed - incorrectly from the shell edit modes. A work around for - this problem has been added. -01-03-26 A bug in which valid scripts could produce syntax errors - when run with locales that considered characters such as "'" - to be space characters has been fixed. -01-03-20 A bug in which an syntax error in an arithmetic expression - entered interactively could cause the shell to go into - an infinite loop outputting the error message has been fixed. -01-03-10 ksh93 accepts -l as a synonym for -L in test on systems for - which /bin/test -l tests for symbolic links. -01-03-10 A bug in parsing scripts in which { and } are used in place of - in and esac in case statements embedded in compound commands - has been fixed. Use of { and } for in and esac is obsolete. -01-03-06 A bug in which an argument of the form foo=bar was not - being passed correctly to a traced function whose name - was foo has been fixed. -01-03-02 Using $(trap -p name) did not print the name of the current - trap setting for trap name. -01-02-26 Exported floating point variables gave incorrect results - when passing them to ksh88. This has been fixed. -01-02-25 A race condition in which a coprocess which completed too quickly - would not allow subsequent coprocesses to start has been fixed. -01-02-25 The 'g' format specifier is now handled by printf. It had - inadvertently been omitted. -01-02-20 The + was not being displayed during an execution trace - with the += assignment operator. -01-02-19 The error message which occurs when the interpreter name - defined on the #! line does not exist is more informative. -01-02-19 A bug in which $0 would not be set correctly when a - script with #! was invoked by full pathname from the - directory of the script has been fixed. -01-02-19 A shell script did not always pick up tty mode changes - made by external commands such as stty which could - effect the behavior of read. -01-02-19 The -u, -g, and -k unary tests did not give the correct - results when used with negation and this has been fixed. - -01-02-05 --- Release ksh93k+ --- -01-02-05 The sequence \<newline> inside $'...' was not incrementing - the line count and this has been fixed. -01-02-05 Modified expansion of "${@-}" so that if no arguments are set - it results in null string rather than nothing. -01-02-02 memory leak problem with local variables in functions fixed. -01-01-25 allow arithmetic expressions with float%int and treat them - as ((int)float)%int rather than as an error. -01-01-19 read -n1 was not working and has been fixed. -01-01-17 ksh now handles the case in which a here document in command - substitution $() is terminated by the trailing ). Previously, - a new-line was needed at the end of the delimiter word. -01-01-02 A bug in which a KEYBD trap would cause a multi-line token - to be processed incorrectly has been fixed. -00-12-10 Arithmetic integer constants can now have L and U suffices. -00-12-10 A bug in the processing of arithmetic expressions with compound - variables when the -n option is on has been fixed. -00-12-08 A bug in M-f and M-b from emacs mode has been fixed. This - bug only occurs when ksh93 is compiled without MULTIBYTE enabled. -00-11-29 A bug in which jobs -p would yield 0 for background - jobs run in a script has been fixed. -00-11-21 A bug in integer arrays in which the number of elements is - incorrect when the ++ operator is applied to a non-existing - element has been fixed. For example, integer x; ((x[3]++)). -00-11-20 A timing bug in which the shell could reset the terminal - group to the wrong value in the case that the a new process - changes the terminal group during startup has been fixed. - -00-10-27 --- Release ksh93k --- -00-10-27 Using tab for completion now works only when applied - after a non-blank character at the end of the current line. - In other case a tab is inserted. -00-10-27 A bug in the emacs edit mode for ^X^E has been fixed. - The ^X^E sequence is supposed to invoke the full editor - on the current command. -00-10-18 A bug in which expansions of the form ${var//pattern/string} - did not work correctly when pattern was '/' or "/" has - been fixed. -00-10-18 The output format for indexed arrays in compound variables - has been modified so that it can be used as input. -00-10-18 Assignments with name references (typeset -n) will now - implicitly unreference an existing name reference. -00-10-17 A bug the += append operator when a single array element - is appended to a variable that is not an array has been fixed. -00-10-16 A bug in which the SIGCONT signal was being sent to - each process will kill -0 or kill -n 0 has been fixed. -00-10-12 The arithmetic evaluation portion has been rewritten to - perform a number of optimizations. -00-10-10 A bug in which name prefix matching ${!name.*} was not - checking name to see if it was a name reference has been fixed. -00-09-26 A bug in the multibyte version in which the width of for - non-printing characters was not correct has been fixed. -00-09-12 Made changes to get multibyte editing work on UWIN for windows -00-09-12 A bug in which multibyte characters would be displayed incorrectly - has been fixed. -00-08-08 Removed build dependency on iswprint() and iswalph(). -00-07-20 In some cases the read builtin would read more than a single - line from a pipe on standard input and therefore leave the seek - position in the wrong location. -00-07-05 If the directory / is on the path, a / will not be inserted - between the directory and the file name during path searching - to avoid searching // for systems that treat this specially. -00-06-26 A bug in which on rare occasions wait could return before all - jobs have completed has been fixed. -00-06-21 A bug in which backspace did not work correctly during the - R replace directive in vi-mode has been fixed. -00-06-12 Added variable name completion/expansion/listing to the set of - completions. Variable name completions begin with $ or "$ followed - by a letter. -00-05-09 --- Release ksh93j --- -00-05-09 Modified command substitution to avoid using /tmp files when - run on read-only file systems. -00-04-17 Modified printf to handle '%..Xc' and '%..Xs' options where X - is not an alpha character. Previous versions core dumped with this. -00-04-10 Changes to multibyte editing code were made to use standard - ISO C functions rather than methods devised before the standard. -00-04-09 Add %H options to printf to output strings with <"'&\t> properly - converted for use in HTML and XML documents. -00-04-07 Modified getopts builtin to handle \f...\f in usage string - by invoking specified function. -00-04-04 Added self generating man pages for bg, fc, fg, disown, jobs, - hist, let, ., and ulimit. -00-03-30 The append operator += has been added and can be used - for all assignments, strings, arrays, and compound variables. -00-03-30 Code was modified in several places to support automatic - generation of C locale dictionaries. -00-03-28 A bug in which the set and trap commands invoked with --name - type arguments would terminate the invoking script has - been fixed. -00-03-27 A bug in which the library path variable was not updated - correctly on some systems as described in the 'g' point - release has been fixed. -00-03-07 printf now returns a non-zero exit status when one of - its arguments cannot be converted to the given type. -00-03-05 The return value and error message for a command that - was found on the path but was not executable was set - incorrectly. -00-03-05 A prototype for ioctl() was removed from the vi edit mode. - -00-01-28 --- Release ksh93i --- -00-01-28 Most of the built-in commands and ksh itself are now - self documenting. Running command --man will produce - screen output. Running command --html produces the - man page in html format. -00-01-28 The getopts builtin can process command description - strings to produce man pages. -00-01-28 A bug in which a script could terminate when getopts - encountered an error when invoked inside a function - has been fixed. -00-01-28 When a symbolic link was specified as the name of - the script to invoke by name, the value of $0 was - set to the real file name rather than the link name - in some cases and this has been fixed. -00-01-28 A bug in which the precision given as an argument - to printf was not working has been fixed. - -99-03-31 --- Release ksh93h --- -99-03-31 The PATH search algorithm has been modified to look - for a file named .fpath in each bin directory and if - found, to search for functions in this directory if - it cannot find the command in that directory. -99-03-31 When performing pathname expansion, the shell checks - to see whether each directory it reads is case sensitive - or not, and performs the matching accordingly. -99-03-31 The %T format for printing formatted date/time. -99-03-31 The emacs and vi modes now handle arrow keys when - they use standard ANSI escape sequences. -99-03-31 The TAB key can be used for completion in emacs and viraw mode. -99-03-31 A bug in setting .sh.editchar during the KEYBD trap - for the MULTIBYTE option was fixed in release ksh93h. -99-03-31 A bug in shcomp for compilation of unary operators with [[...]] - has been fixed. -99-03-31 A bug in which the value of $? was changed when executing - a keyboard trap has been fixed. -99-03-31 The handling of SIGCHLD has been changed so that the - trap is not triggered while executing trap commands - to avoid recursive trap calls. -99-03-31 A bug in which a local variable in a function declared readonly - would generated an error when the function went out of - scope has been fixed. -99-03-31 A bug in which \<new_line> entered from the keyboard - with the KEYBD trap enabled has been fixed. -99-03-31 The error message for a misplaced ((, for example print ((3), - was often garbled and has been fixed. -99-03-31 A bug in the KEYBD trap in which escape sequences of the form - <ESC>[#~ were not being handled as a unit has been fixed. -99-03-31 A bug in which ksh would consider expressions like [[ (a) ]] - as syntax errors has been fixed. -99-03-31 A function defined as foo() without a function body - was not reported as a syntax error. -99-03-31 A bug in which ksh could run out of file descriptors when - a stream was repeatedly opened with exec and read from - has been fixed. - -98-04-30 --- Release ksh93g --- -98-04-30 The pipefail option has been added. With pipefail - enabled, a pipeline will not complete until all - commands are complete, and the return value will - be that of the last command to fail, or zero if - all complete successfully. -98-04-30 The name-value pair library uses the cdt library rather - than the hash library. This change should be transparent - to applications. -98-04-30 On the U/WIN version for Window 95 and Windows NT, - when a directory beginning with a letter followed by - a colon is given to cd, it is assumed to be an absolute - directory -98-04-30 When an executable is found on a given path, - the appropriate library path variable is prepended - with a corresponding library directory. -98-04-30 A bug in which a name reference could be created to - itself and later cause the shell to get into an infinite - loop has been fixed. -98-04-30 A bug in shcomp relating to compound variables was fixed. -98-04-30 A bug introduced in ksh93e in which leading 0's in -Z - fields caused the value to be treated as octal for arithmetic - evaluation has been fixed. -98-04-30 A bug when a name reference with a shorter name than - the variable it references was the subject of a compound - assignment has been fixed. -98-04-30 A bug which in which assignment to array variables in - a subshell could effect the parent shell has been - fixed. -98-04-30 read name?prompt was putting a 0 byte at the end of the - prompt on standard error. -98-04-30 A bug in [[ string1 > string2 ]] when ksh was run with -x - has been fixed. -98-04-30 A bug in which the escape character was not processed - correctly inside {...} when brace expansion is enabled - has been fixed, for example {\$foo}. -98-04-30 A bug in line continuation in here-documents has been - fixed. -98-04-30 The default base when not specified with typeset -i is - 10 in accordance with the documentation. Previously, - the value was determined by the first assignment. -98-04-30 A parsing bug in which a # preceded alphanumeric - characters inside a command substitution caused - a syntax error to be reported has been fixed. -98-04-30 A bug in which a decimal constant represented as 10#ddd - where ddd was more than five digits generated a syntax - error has been fixed. -98-04-30 A bug in here document expansion in which ${...} expansions - were split across buffer boundaries has been fixed. -98-04-30 The sh_fun() function now takes third argument which - is an argument list for the invoked discipline function - or built-in. -98-04-30 A callback function can be installed which will give - notification of file duplications and file closes. -98-04-30 When ksh is compiled on systems that do not use fork() - current option settings where not propagated to sub-shells. - -97-06-30 --- Release ksh93f --- -97-06-30 Hostnames in addition to host addresses can be given in - /dev/tcp/host/port virtual file names. -97-06-30 File name completion and expansion now quotes special - characters in file names from both emacs and vi edit modes. -97-06-30 An empty for list behave like a for list with null expansions. - It produces a warning message with sh -n. -97-06-30 The code has been modified to work with EBCDIC as well as ASCII. -97-06-30 A bug which would cause the secondary prompt to be - displayed when a user entered a literal carriage - return has been fixed. -97-06-30 A bug which caused ksh read -s name to core dump was - fixed. -97-06-30 A bug with the expansion of \} and \] inside double - quoted strings that also contained variable expansions - has been fixed -97-06-30 Changes in the ksh93e point release caused autoload - functions invoked from within command substitution - to fail. This has been fixed. -97-06-30 A bug in the processing of here-documents that could - prevent variable substitution to occur after $(...) command - substitution for long here documents has been fixed. -97-06-30 A bug caused by a race condition that could cause SIGTERM - to be ignored by a child process has been fixed. -97-06-30 A bug which prevented the startup of a coprocess immediately - after killing a running coprocess has been fixed. -97-06-30 ulimit foobar, where foobar is not an arithmetic - expression, now gives an error message as it did with ksh88 - instead of setting the file size limit to 0. -97-06-30 A bug which could cause an interactive shell to terminate when - the last process of a pipeline was a POSIX function was fixed. -97-06-30 A bug which could cause command substitution of a shell script - to core dump has been fixed. -97-06-30 A security hole was fixed in suid_exec. -97-06-30 Arithmetic functions such as pow() that take more than - one argument, did not work if arguments other than the - first contained parenthesized sub-expression. -97-06-30 The error message from a script containing an incomplete - arithmetic expression has been corrected. -97-06-30 A bug which caused a core dump on some machines when - the value of a name reference contained a positional - parameter and the name reference was not defined inside - a function has been fixed. -97-06-30 Arithmetic expressions now correctly handle hexadecimal - constants. -97-06-30 A bug in which integer variables could be expanded - with a leading 10# when declared with typeset -i - multiple times has been corrected. -97-06-30 A bug in which IFS wasn't correctly restored when - set within command substitution has been fixed. -97-06-30 The _ character is now considered as part of a word - with the M-f and M-b emacs directives as it was in ksh88. -97-06-30 A bug in brace pattern expansions that caused expressions - such as {foo\,bar,bam} to expand incorrectly have been fixed. - - -96-07-31 --- Release ksh93e --- -96-07-31 The math functions, atan2, hypot, fmod, and pow were added. -96-07-31 When a shared library is loaded, if the function lib_init() - is defined in the library, it is invoked the first time that - the library is loaded with builtin -f library. -96-07-31 The k-shell information abstraction database option, KIA, - has been revamped. -96-07-31 Empty command substitutions of the form $() now work. - whence -v foo now gives the correct result after calling - builtin -d foo. -96-07-31 A bug in right to left arithmetic assignment for which - the arithmetic expression (( y = x = 1.5 )) did not - yield 1 for y when x was declared typeset -i was fixed. -96-07-31 printf has been fixed to handle format containing \0 - and/or \0145 correctly. In addition, characters following - %b in the format string are no longer displayed when - the operand contains \c. -96-07-31 A bug in printf that could cause the %E format to - produce unnormalized results has been fixed. -96-07-31 A bug which causes some arithmetic expressions to be - incorrectly evaluated as integer expressions rather - that floating point has been fixed. -96-07-31 Functions defined inside a subshell no longer remain - defined when the subshell completes. -96-07-31 The error message from sh -c ';echo foo' has been - corrected. -96-07-31 The format for umask -S has been changed to agree - with the specification in the POSIX standard. -96-07-31 A bug that caused side effects in subscript evaluation - when tracing was enabled for subscripts using ++ or -- - has been fixed. -96-07-31 To conform to the Posix standard getopts has been changed - so that the option char is set to ? when it returns with - a non-zero exit status. -96-07-31 The handling of \} inside ${name...} has been fixed so - that the \ quotes the }. -96-07-31 A bug that caused the read builtin to resume execution - after processing a trap has been fixed. -96-07-31 [[ -s file ]] has been fixed so that if file is open - by ksh, it is flushed first. -96-07-31 In some cases attributes and sizes for non exported - variables weren't being reset before running a script. -96-07-31 The value of TMOUT was affected by changes make to - it in a subshell. -96-07-31 The jobs command did not reflect changes make by - sending the CONT signal to a command. -96-07-31 The error message for ksh -o unknown was incorrect. -96-07-31 Functions invoked as name=value name, did not use - values from the calling scope when evaluating value. -96-07-31 A bug in which the shell would reexecute previously - executed code when a shell script or coprocess was - run in the background has been fixed. -96-07-31 A bug in which an empty here-document would leave - a file descriptor open has been fixed. -96-07-31 A bug in which $(set -A array ...) would leave a - side effect has been fixed. -96-07-31 A discipline function for a global variable defined - within a function defined with the function keyword, - incorrectly created a local variable of the same name - and applied the discipline to it. - -95-08-28 --- Release ksh93d --- -95-08-28 The \ character was not handled correctly in replacement - patterns with ${x/pattern/replace}. -95-08-28 A bug with read in which the line did not end with - a new-line has been fixed. -95-08-28 A bug in file name generation which sometimes - appended a . for filenames that ended in / has - been fixed. -95-08-28 If a process is waited for after a status has - been returned by a previous wait, wait now - returns 127. -95-08-28 A bug with hist (fc) -e which prevented a command - to re-executed after it had been edited has been fixed. -95-08-28 A bug which prevented quoting from removing the meaning - of unary test operators has been fixed. -95-08-28 A bug with typeahead and KEYBOARD traps with the - MULTIBYTE option set has been fixed. -95-08-28 Builtin functions can take a third argument which is - a void*. -95-08-28 The nv_scan() function can restrict the scope of a walk - to the top scope. - -95-04-31 --- Release ksh93c --- -95-04-31 The expansion of "$@" was incorrect when $1 was the null - string. -95-04-31 A bug which could incorrectly report a syntax error in - a backquoted expression when a $ was preceded by \\ - has been fixed. -95-04-31 A bug which prevented the shell from exiting after - reporting an error when failing to open a script - has been fixed. -95-04-31 A bug that could lead to memory corruption when a - large here document that required parameter or command - substitution was expanded has been fixed. -95-04-31 A bug that could cause a core dump on some systems - after ksh detected an error when reading a function - has been fixed. -95-04-31 A bug which could cause a coprocess to hang when - reading from a process that has terminated has been fixed. -95-04-31 A bug which caused a script to terminate when set -e - was on and the first command of and && or || list - failed has been fixed. -95-04-31 A bug with here documents inside $(...) when the delimiter - word is an identifier has been fixed. -95-04-31 A bug which caused $0 to display the wrong value when - a script was invoked as an argument to the . command - and the eval command has been fixed. -95-04-31 A bug that could cause the built-in sleep to hang - has been fixed. -95-04-31 A bug introduces in 12/28/93b which caused the backslash - to be removed when it was followed by digit inside double - quotes in some instances has been fixed. -95-04-31 A bug which could cause a core dump if ksh was invoked with - standard input closed has been fixed. -95-04-31 A bug which could cause a core dump if typeset -A was - specified for an existing variable has been fixed. -95-04-31 Variables that were unset but had attributes such as readonly - and export were not listed with readonly, export and typeset. -95-04-31 Several problems with signals have been fixed. -95-04-31 A bug which prevented ulimit -t from working has been fixed. - Also, a bug in which failed ulimits could cause a core dump - has also been fixed. -95-04-31 A bug in expansion of the form ${name/#pattern/string} and - ${name/%pattern/string} has been fixed. -95-04-31 A bug which caused read -r on a line that contained only - blanks to get a non-null value has been fixed. -95-04-31 A bug introduced in the 'a' point release in which - ${x='\\'} expanded to \ when x was unset has been fixed. -95-04-31 A bug which prevented a trap on EXIT from being executed - when the last command in a script was a function invocation - has been fixed. -95-04-31 A bug which caused an interactive shell ignore input when - standard error was redirected to a file with exec, - and then restored with exec 2>&1 has been fixed. -95-04-31 An interactive shell turns on monitor mode even when - standard error has been redirected to a file. -95-04-31 A bug which could cause standard input to be incorrectly - positioned for the last command of a script has been fixed. -95-04-31 A bug in the edit modes which allowed walking back in - the history file for more than HISTSIZE commands has - been fixed. -95-04-31 A bug which could cause a core dump if variable TMPDIR was - changed between two command substitutions has been fixed. -95-04-31. A bug which prevented a trap on EXIT from being cleared - has been fixed. -95-04-31 A bug fixed for the v directive in vi MULTIBYTE has been - fixed. -95-04-31 Code to for IFS handling of multibyte characters has - been added. -95-04-31 The displaying of multibyte strings in export, readonly, - typeset, and execution traces has been fixed. -95-04-31 Variables inside functions are now statically scoped. - The previous behavior was never documented. -95-04-31 Variables inside functions are now statically scoped. - The previous behavior was never documented. -95-04-31 A few changes have been made to the name-value library - that affect built-ins that use disciplines. The - changes allow disciplines to be shared by variables - and should make it possible to add new disciplines - without recompilation. -95-04-31 The name-value library interface has undergone significant - change for this revision. See the new nval.3 man page. - -94-12-31 --- Release ksh93b --- -94-12-31 Variables inside functions are now statically scoped. - The previous behavior was never documented. -94-12-31 If IFS contains two consecutive identical characters belonging - to the [:space:] class, then this character is treated as - a non-space delimiter so that each instance will delimit - a field. For example, IFS=$'\t\t' will cause two consecutive - tabs to delimit a null field. -94-12-31 The getopts command has a -a name option that specifies a - name that will be used for usage messages. -94-12-31 A bug which caused unset RANDOM to dump core has been - fixed. -94-12-31 A bug which prevented return for terminating a profile - or ENV file has been fixed. -94-12-31 A bug which prevented standard input from being - directed to /dev/null for background jobs when - monitor mode was turned off has been fixed. -94-12-31 Statements of the form typeset -options var[expr]=value - did not perform substitutions on expr as expected. -94-12-31 A bug which prevented the shell from sending a HUP - signal to some background jobs that were not disowned - has been fixed. -94-12-31 A bug which allowed a script to trap signals that are - ignored at the time that the shell was invoked by exec - has been fixed. -94-12-31 A bug which could cause a core dump when a discipline - function was unset within a discipline was fixed. -94-12-31 The typeset builtin now accepts a first argument of - + or - for compatibility with ksh88. -94-12-31 For compatibility with ksh88, the results of expansions - of command arguments will treat the extended character - match characters ()|& as ordinary characters. -94-12-31 A bug which caused read to fail on a file that was - open for read/write with <> when the first operation - was print or printf has been fixed. -94-12-31 When a job is suspended, it is put on the top of - the job list as required by the POSIX standard. -94-12-31 The value of OPTARG when an option that required - an argument but didn't have one was incorrect in the - case the the option string began with a :. -94-12-31 A bug which caused the terminal to get into a bad - state with some KEYBD traps in vi-mode has been fixed. -94-12-31 A bug which caused an invalid trap to cause a script - to terminate, rather than just return an error, has - been fixed. -94-12-31 Backreferencing sub-expressions in patterns and replacement - strings now works. -94-12-31 A bug in chmod which caused the -R option to fail has - been fixed. -94-12-31 More signal names have been added for Solaris - -94-06-30 --- Release ksh93a --- -94-06-30 An expansion bug which causes portions of a word after - a $((...)) expansion that contains a nested $var expansion - to be lost has been fixed. -94-06-30 A bug that caused a core dump when a script that did not - have PWD set and did a cd inside command substitution - has been fixed. -94-06-30 A bug which caused a core dump on some machines when - the LANG variable was assigned to has been fixed. -94-06-30 A bug which incorrectly handled set disciplines that - performed arithmetic evaluation when the discipline - was called from the arithmetic evaluator has been fixed. -94-06-30 A bug caused by an EXIT trap inside a function that - was executed in a subshell was fixed. -94-06-30 If foo is a function, and not a program, then command foo - now reports that foo isn't found rather than invoking foo. -94-06-30 The previous version incorrectly listed -A as an - invocation option. The -A option is only for set. -94-06-30 A bug was fixed which caused ksh to loop when execution trace - was enabled and the PS4 prompt required command substitution. -94-06-30 A bug which could cause the job control switch character - to be disabled when a script that enabled monitor mode - terminated was fixed. -94-06-30 A bug in the macro expansion global replacement operator //, - when the pattern began with a [ or +( has been fixed. -94-06-30 A bug which prevented ~ expansion from occurring when - it was terminated with a colon inside an assignment - has been fixed. -94-06-30 A bug in the dot command which prevented autoload functions - from working has been fixed. -94-06-30 A bug which caused a variable to be unset if the - its value were expanded inside a set discipline has - been fixed. -94-06-30 Whence -a now longer reports that a defined function - is undefined. -94-06-30 A bug on some systems in which $0 would be incorrect - in scripts invoked by name has been fixed. -94-06-30 Here documents with an empty body now work. -94-06-30 A bug which disabled argument passing and resetting - of options for a script invoked by name inside a - function has been fixed. -94-06-30 A bug in which an EXIT trap set the caller of a function - would be executed if a command called inside a function - was not found has been fixed. -94-06-30 A bug which allowed a script to trap signals that are - ignored at the time that the shell was invoked has - been fixed. -94-06-30 A bug which caused 2<&1- when applied to a shell built-in - to leave standard input closed has been fixed. -94-06-30 A bug which caused the shell to incorrectly parse - $() command substitutions with nested case statements - has been fixed. - diff --git a/usr/src/lib/libshell/common/TYPES b/usr/src/lib/libshell/common/TYPES deleted file mode 100644 index 6eb6f41b5e..0000000000 --- a/usr/src/lib/libshell/common/TYPES +++ /dev/null @@ -1,182 +0,0 @@ - -The ability for users to define types has been added to ksh93t. -Here is a quick summary of how types are defined and used in ksh93t. -This is still a work in progress so some changes and additions -are likely. - -A type can be defined either by a shared library or by using the new -typeset -T option to the shell. The method for defining types via -a shared library is not described here. However, the source file -bltins/enum.c is an example of a builtin that creates enumeration types. - -By convention, typenames begin with a capitol letter and end in _t. -To define a type, use - typeset -T Type_t=( - definition - ) -where definition contains assignment commands, declaration commands, -and function definitions. A declaration command (for example typeset, -readonly, and export), is a built-in that differs from other builtins in -that tilde substitution is performed on arguments after an =, assignments -do not have to precede the command name, and field splitting and pathname -expansion is not performed on the arguments. -For example, - typeset -T Pt_t=( - float -h 'length in inches' x=1 - float -h 'width in inches' y=0 - integer -S count=0 - len() - { - print -r $((sqrt(_.x*_.x + _.y*_.y))) - } - set() - { - (( _.count++)) - } - ) - -defines a type Pt_t that has three variables x, y, and count defined as well -as the discipline functions len and set. The variable x has an initial value -of 1 and the variable y has an initial value of 0. The new -h option argument, -is used for documentations purposes as described later and is ignored outside -of a type definition. - - -The variable count has the new -S attribute which means that it is shared -between all instances of the type. The -S option to typeset is ignored -outside of a type definition. Note the variable named _ that is used inside -the function definition for len and set. It will be a reference to the -instance of Pt_t that invoked the function. The functions len and set -could also have been defined with function len and function set, but -since there are no local variables, the len() and set() form are more -efficient since they don't need to set up a context for local variables -and for saving and restoring traps. - -If the discipline function named create is defined it will be -invoked when creating each instance for that type. A function named -create cannot be defined by any instance. - -When a type is defined, a declaration built-in command by this name -is added to ksh. As with other shell builtins, you can get the man page -for this newly added command by invoking Pt_t --man. The information from -the -h options will be embedded in this man page. Any functions that -use getopts to process arguments will be cross referenced on the generated -man page. - -Since Pt_t is now a declaration command it can be used in the definition -of other types, for example - typeset -T Rect_t=( Pt_t ur ll) - -Because a type definition is a command, it can be loaded on first reference -by putting the definition into a file that is found on FPATH. -Thus, if this definition is in a file named Pt_t on FPATH, then -a program can create instances of Pt_t without first including -the definition. - -A type definition is readonly and cannot be unset. Unsetting non-shared -elements of a type restores them to their default value. Unsetting a -shared element has no effect. - -The Pt_t command is used to create an instance of Pt_t. - Pt_t p1 -creates an instance named p1 with the initial value for p1.x set to 1 -and the initial value of p1.y set to 0. - Pt_t p2=(x=3 y=4) -creates an instance with the specified initial values. The len function -gives the distance of the point to the origin. Thus, p1.len will output -1 and p2.len will output 5. - -ksh93t also introduces a more efficient command substitution mechanism. -Instead of $(command), the new command substitution ${ command;} -can be used. Unlike (and ) which are always special, the { and } are -reserved words and require the space after { and a newline or ; before }. -Unlike $(), the ${ ;} command substitution executes the command in -the current shell context saving the need to save and restore -changes, therefore also allowing side effects. - -When trying to expand an element of a type, if the element does not exist, -ksh will look for a discipline function with that name and treat this as if -it were the ${ ;} command substitution. Thus, ${p1.len} is equivalent to -${ p1.len;} and within an arithmetic expression, p1.len will be expanded -via the new command substitution method. - -The type of any variable can be obtained from the new prefix -operator @. Thus, ${@p1} will output Pt_t. - -By default, each instance inherits all the discipline functions defined -by the type definition other than create. However, each instance can define -a function by the same name that will override this definition. -However, only discipline functions with the same name as those defined -by the type or the standard get, set, append, and unset disciplines -can be defined by each instance. - -Each instance of the type Pt_t behaves like a compound variable except -that only the variables defined by the type can be referenced or set. -Thus, p2.x=9 is valid, but p2.z=9 is not. Unless a set discipline function -does otherwise, the value of $p1 will be expanded to the form of a compound -variable that can be used for reinput into ksh. - -If the variables var1 and var2 are of the same type, then the assignment - var2=var1 -will create a copy of the variable var1 into var2. This is equivalent to - eval var2="$var1" -but is faster since the variable does not need to get expanded or reparsed. - -The type Pt_t can be referenced as if it were a variable using the name -.sh.type.Pt_t. To change the default point location for subsequent -instances of Pt_t, you can do - .sh.type.Pt_t=(x=5 y=12) -so that - Pt_t p3 - p3.len -would be 13. - -Types can be defined for simple variables as well as for compound -objects such as Pt_t. In this case, the variable named . inside -the definition refers to the real value for the variable. For example, -the type definition - typeset -T Time_t=( - integer .=0 - _='%H:%M:%S' - get() - { - .sh.value=$(printf "%(${_._})T" "#$((_))" ) - } - set() - { - .sh.value=$(printf "%(%#)T" "${.sh.value}") - - } - ) - -The sub-variable name _ is reserved for data used by discipline functions -and will not be included with data written with the %B option to printf. -In this case it is used to specify a date format. - -In this case - Time_t t1 t2=now -will define t1 as the time at the beginning of the epoch and t2 -as the current time. Unlike the previous case, $t2 will output -the current time in the date format specified by the value t2._. -However, the value of ${t2.} will expand the instance to a form -that can be used as input to the shell. - -Finally, types can be derived from an existing type. If the first -element in a type definition is named _, then the new type -consists of all the elements and discipline functions from the -type of _ extended by elements and discipline functions defined -by new type definition. For example, - - typeset -T Pq_t=( - Pt_t _ - float z=0. - len() - { - print -r $((sqrt(_.x*_.x + _.y*_.y + _.z*_.z))) - } - ) - -defines a new type Pq_t which is based on Pq_t and contains an additional -field z and a different len discipline function. It is also possible -to create a new type Pt_t based on the original Pt_t. In this case -the original Pt_t is no longer accessible. diff --git a/usr/src/lib/libshell/misc/images/callouts/1.png b/usr/src/lib/libshell/misc/images/callouts/1.png Binary files differdeleted file mode 100644 index 608fad3596..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/1.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/10.png b/usr/src/lib/libshell/misc/images/callouts/10.png Binary files differdeleted file mode 100644 index 39e55197cf..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/10.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/2.png b/usr/src/lib/libshell/misc/images/callouts/2.png Binary files differdeleted file mode 100644 index 5444738841..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/2.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/3.png b/usr/src/lib/libshell/misc/images/callouts/3.png Binary files differdeleted file mode 100644 index 64b87c7151..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/3.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/4.png b/usr/src/lib/libshell/misc/images/callouts/4.png Binary files differdeleted file mode 100644 index c308193ac4..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/4.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/5.png b/usr/src/lib/libshell/misc/images/callouts/5.png Binary files differdeleted file mode 100644 index 24799f0a43..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/5.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/6.png b/usr/src/lib/libshell/misc/images/callouts/6.png Binary files differdeleted file mode 100644 index 8919a670cd..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/6.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/7.png b/usr/src/lib/libshell/misc/images/callouts/7.png Binary files differdeleted file mode 100644 index e30e8a70cb..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/7.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/8.png b/usr/src/lib/libshell/misc/images/callouts/8.png Binary files differdeleted file mode 100644 index 3e35c8827c..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/8.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/callouts/9.png b/usr/src/lib/libshell/misc/images/callouts/9.png Binary files differdeleted file mode 100644 index ed2f14b4eb..0000000000 --- a/usr/src/lib/libshell/misc/images/callouts/9.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_bourne.png b/usr/src/lib/libshell/misc/images/tag_bourne.png Binary files differdeleted file mode 100644 index f1f78e3a25..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_bourne.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_i18n.png b/usr/src/lib/libshell/misc/images/tag_i18n.png Binary files differdeleted file mode 100644 index 559929df2a..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_i18n.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_ksh.png b/usr/src/lib/libshell/misc/images/tag_ksh.png Binary files differdeleted file mode 100644 index b33d5a7aa1..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_ksh.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_ksh88.png b/usr/src/lib/libshell/misc/images/tag_ksh88.png Binary files differdeleted file mode 100644 index d36dc0f5f5..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_ksh88.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_ksh93.png b/usr/src/lib/libshell/misc/images/tag_ksh93.png Binary files differdeleted file mode 100644 index 357ee3c50a..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_ksh93.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_l10n.png b/usr/src/lib/libshell/misc/images/tag_l10n.png Binary files differdeleted file mode 100644 index be89f7a163..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_l10n.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/images/tag_perf.png b/usr/src/lib/libshell/misc/images/tag_perf.png Binary files differdeleted file mode 100644 index fcb2960852..0000000000 --- a/usr/src/lib/libshell/misc/images/tag_perf.png +++ /dev/null diff --git a/usr/src/lib/libshell/misc/shell_styleguide.docbook b/usr/src/lib/libshell/misc/shell_styleguide.docbook deleted file mode 100644 index 0376912d1f..0000000000 --- a/usr/src/lib/libshell/misc/shell_styleguide.docbook +++ /dev/null @@ -1,1464 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V5.0//EN" "http://www.oasis-open.org/docbook/xml/5.0b5/dtd/docbook.dtd" [ - <!ENTITY tag_bourneonly '<inlinemediaobject><imageobject><imagedata fileref="images/tag_bourne.png"></imagedata></imageobject><textobject><phrase>[Bourne]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_kshonly '<inlinemediaobject><imageobject><imagedata fileref="images/tag_ksh.png"></imagedata></imageobject><textobject><phrase>[ksh]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_ksh88only '<inlinemediaobject><imageobject><imagedata fileref="images/tag_ksh88.png"></imagedata></imageobject><textobject><phrase>[ksh88]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_ksh93only '<inlinemediaobject><imageobject><imagedata fileref="images/tag_ksh93.png"></imagedata></imageobject><textobject><phrase>[ksh93]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_performance '<inlinemediaobject><imageobject><imagedata fileref="images/tag_perf.png"></imagedata></imageobject><textobject><phrase>[perf]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_i18n '<inlinemediaobject><imageobject><imagedata fileref="images/tag_i18n.png"></imagedata></imageobject><textobject><phrase>[i18n]</phrase></textobject></inlinemediaobject> '> - <!ENTITY tag_l10n '<inlinemediaobject><imageobject><imagedata fileref="images/tag_l10n.png"></imagedata></imageobject><textobject><phrase>[l10n]</phrase></textobject></inlinemediaobject> '> -]> -<!-- - - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License (the "License"). - You may not use this file except in compliance with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - ---> - -<!-- - - Copyright 2009 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - ---> - -<!-- tag images were created like this: -$ (text="perf" ; - pbmtext -nomargins -lspace 0 -builtin fixed "${text}" | - pbmtopgm 1 1 | - pgmtoppm 1.0,1.0,1.0-0,0,0 /dev/stdin | - ppmtogif | - giftopnm | - pnmtopng >"tag_${text}.png") ---> - -<!-- compile with: -xsltproc −−stringparam generate.section.toc.level 0 \ - −−stringparam toc.max.depth 3 \ - −−stringparam toc.section.depth 12 \ - −−xinclude -o opensolaris_shell_styleguide.html /usr/share/sgml/docbook/docbook-xsl-stylesheets-1.69.1/html/docbook.xsl opensolaris_shell_styleguide.docbook ---> - -<article - xmlns:xlink="http://www.w3.org/1999/xlink" - xmlns="http://docbook.org/ns/docbook" - xml:lang="en"> - <!-- xmlns:xi="http://www.w3.org/2001/XInclude" --> - - <info> - <title><emphasis>[DRAFT]</emphasis> Bourne/Korn Shell Coding Conventions</title> - - <!-- subtitle abuse --> - <subtitle> - This page is currently work-in-progress until it is approved by the OS/Net community. Please send any comments to - <email>shell-discuss@opensolaris.org</email>. - </subtitle> - - - <authorgroup> -<!-- - <author><personname>David G. Korn</personname><email>dgk@research.att.com</email></author> - <author><personname>Roland Mainz</personname><email>roland.mainz@nrubsig.org</email></author> - <author><personname>Mike Shapiro</personname><email>mike.shapiro@sun.com</email></author> ---> - <author><orgname>OpenSolaris.org</orgname></author> - </authorgroup> - </info> - -<section xml:id="intro"> - <title>Intro</title> - <para>This document describes the shell coding style used for all the SMF script changes integrated into (Open)Solaris.</para> - <para>All new SMF shell code should conform to this coding standard, which is intended to match our existing C coding standard.</para> - <para>When in doubt, think "what would be the C-Style equivalent ?" and "What does the POSIX (shell) standard say ?"</para> -</section><!-- end of intro --> - - -<section xml:id="rules"> - <title>Rules</title> - - - - <section xml:id="general"> - <title>General</title> - - <section xml:id="basic_format"> - <title>Basic Format</title> - <para>Similar to <literal>cstyle</literal>, the basic format is that all - lines are indented by TABs or eight spaces, and continuation lines (which - in the shell end with "\") are indented by an equivalent number of TABs - and then an additional four spaces, e.g. -<programlisting> -cp foo bar -cp some_realllllllllllllllly_realllllllllllllly_long_path \ - to_another_really_long_path -</programlisting> - </para> - <para>The encoding used for the shell scripts is either <literal>ASCII</literal> - or <literal>UTF-8</literal>, alternative encodings are only allowed when the - application requires this.</para> - </section> - - - <section xml:id="commenting"> - <title>Commenting</title> - <para>Shell comments are preceded by the '<literal>#</literal>' character. Place - single-line comments in the right-hand margin. Use an extra '<literal>#</literal>' - above and below the comment in the case of multi-line comments: -<programlisting> -cp foo bar # Copy foo to bar - -# -# Modify the permissions on bar. We need to set them to root/sys -# in order to match the package prototype. -# -chown root bar -chgrp sys bar -</programlisting> - </para> - </section> - - - <section xml:id="interpreter_magic"> - <title>Interpreter magic</title> - <para>The proper interpreter magic for your shell script should be one of these: -<programlisting> -#!/bin/sh Standard Bourne shell script -#!/bin/ksh -p Standard Korn shell 88 script. You should always write ksh - scripts with -p so that ${ENV} (if set by the user) is not - sourced into your script by the shell. -#!/bin/ksh93 Standard Korn shell 93 script (-p is not needed since ${ENV} is - only used for interactive shell sessions). -</programlisting> - </para> - </section> - - - <section xml:id="harden_your_script_against_unexpected_input"> - <title>Harden the script against unexpected (user) input</title> - <para>Harden your script against unexpected (user) input, including - command line options, filenames with blanks (or other special - characters) in the name, or file input</para> - </section> - - - <section xml:id="use_builtin_commands"> - <title>&tag_kshonly;&tag_performance;Use builtin commands if the shell provides them</title> - <para> - Use builtin commands if the shell provides them. For example ksh93s+ - (ksh93, version 's+') delivered with Solaris (as defined by PSARC 2006/550) - supports the following builtins: - <simplelist type="inline"> - <member>basename</member> - <member>cat</member> - <member>chgrp</member> - <member>chmod</member> - <member>chown</member> - <member>cmp</member> - <member>comm</member> - <member>cp</member> - <member>cut</member> - <member>date</member> - <member>dirname</member> - <member>expr</member> - <member>fds</member> - <member>fmt</member> - <member>fold</member> - <member>getconf</member> - <member>head</member> - <member>id</member> - <member>join</member> - <member>ln</member> - <member>logname</member> - <member>mkdir</member> - <member>mkfifo</member> - <member>mv</member> - <member>paste</member> - <member>pathchk</member> - <member>rev</member> - <member>rm</member> - <member>rmdir</member> - <member>stty</member> - <member>tail</member> - <member>tee</member> - <member>tty</member> - <member>uname</member> - <member>uniq</member> - <member>wc</member> - <member>sync</member> - </simplelist> - Those builtins can be enabled via <literal>$ builtin name_of_builtin #</literal> in shell - scripts (note that ksh93 builtins implement exact POSIX behaviour - some - commands in Solaris <filename>/usr/bin/</filename> directory implement pre-POSIX behaviour. - Add <literal>/usr/xpg6/bin/:/usr/xpg4/bin</literal> before - <filename>/usr/bin/</filename> in <envar>${PATH}</envar> to test whether your script works with - the XPG6/POSIX versions) - </para> - </section> - - - <section xml:id="use_blocks_not_subshells"> - <title>&tag_performance;Use blocks and not subshells if possible</title> - <para>Use blocks and not subshells if possible, e.g. use - <literal>$ { print "foo" ; print "bar" ; }</literal> instead of - <literal>$ (print "foo" ; print "bar") #</literal> - blocks are - faster since they do not require to save the subshell context (ksh93) or - trigger a shell child process (Bourne shell, bash, ksh88 etc.) - </para> - </section> - - - <section xml:id="use_long_options_for_set_builtin"> - <title>&tag_kshonly; use long options for "<literal>set</literal>"</title> - <para>use long options for "<literal>set</literal>", for example instead of <literal>$ set -x #</literal> - use <literal>$ set -o xtrace #</literal> to make the code more readable.</para> - </section> - - - <section xml:id="use_posix_command_substitutions_syntax"> - <title>&tag_kshonly; Use <literal>$(...)</literal> instead of <literal>`...`</literal> command substitutions</title> - <para>Use <literal>$(...)</literal> instead of <literal>`...`</literal> - <literal>`...`</literal> - is an obsolete construct in ksh+POSIX sh scripts and <literal>$(...)</literal>.is a cleaner design, - requires no escaping rules, allows easy nesting etc.</para> - - <note><title>&tag_ksh93only; <literal>${ ...;}</literal>-style command substitutions</title> - <para>ksh93 has support for an alternative version of command substitutions with the - syntax <literal>${ ...;}</literal> which do not run in a subshell. - </para></note> - </section> - - - <section xml:id="put_command_substitution_result_in_quotes"> - <title>&tag_kshonly; Always put the result of a <literal>$(...)</literal> or - <literal>$( ...;)</literal> command substitution in quotes</title> - <para>Always put the result of <literal>$( ... )</literal> or <literal>$( ...;)</literal> in - quotes (e.g. <literal>foo="$( ... )"</literal> or <literal>foo="$( ...;)"</literal>) unless - there is a very good reason for not doing it</para> - </section> - - - <section xml:id="always_set_path"> - <title>Scripts should always set their <envar>PATH</envar></title> - <para>Scripts should always set their <envar>PATH</envar> to make sure they do not use - alternative commands by accident (unless the value of <envar>PATH</envar> is well-known - and guaranteed to be set by the caller)</para> - </section> - - - <section xml:id="make_sure_commands_are_available"> - <title>Make sure that commands from other packages/applications are really installed on the machine</title> - <para>Scripts should make sure that commands in optional packages are really - there, e.g. add a "precheck" block in scipts to avoid later failure when - doing the main job</para> - </section> - - - <section xml:id="check_usage_of_boolean_variables"> - <title>Check how boolean values are used/implemented in your application</title> - <para>Check how boolean values are used in your application.</para> - <para>For example: -<programlisting> -mybool=0 -# do something -if [ $mybool -eq 1 ] ; then do_something_1 ; fi -</programlisting> -could be rewritten like this: -<programlisting> -mybool=false # (valid values are "true" or "false", pointing -# to the builtin equivalents of /bin/true or /bin/false) -# do something -if ${mybool} ; then do_something_1 ; fi -</programlisting> -or -<programlisting> -integer mybool=0 # values are 0 or 1 -# do something -if (( mybool==1 )) ; then do_something_1 ; fi -</programlisting> - </para> - </section> - - <section xml:id="shell_uses_characters_not_bytes"> - <title>&tag_i18n;The shell always operates on <emphasis>characters</emphasis> not bytes</title> - <para>Shell scripts operate on characters and <emphasis>not</emphasis> bytes. - Some locales use multiple bytes (called "multibyte locales") to represent one character</para> - - <note><para>ksh93 has support for binary variables which explicitly - operate on bytes, not characters. This is the <emphasis>only</emphasis> allowed - exception.</para></note> - </section> - - - <section xml:id="multibyte_locale_input"> - <title>&tag_i18n;Multibyte locales and input</title> - <para>Think about whether your application has to handle file names or - variables in multibyte locales and make sure all commands used in your - script can handle such characters (e.g. lots of commands in Solaris's - <filename>/usr/bin/</filename> are <emphasis>not</emphasis> able to handle such values - either use ksh93 - builtin constructs (which are guaranteed to be multibyte-aware) or - commands from <filename>/usr/xpg4/bin/</filename> and/or <filename>/usr/xpg6/bin</filename>) - </para> - </section> - - - <section xml:id="use_external_filters_only_for_large_datasets"> - <title>&tag_performance;Only use external filters like <literal>grep</literal>/<literal>sed</literal>/<literal>awk</literal>/etc. - if you want to process lots of data with them</title> - <para>Only use external filters like <literal>grep</literal>/<literal>sed</literal>/<literal>awk</literal>/etc. - if a significant amount of data is processed by the filter or if - benchmarking shows that the use of builtin commands is significantly slower - (otherwise the time and resources needed to start the filter are - far greater then the amount of data being processed, - creating a performance problem).</para> - <para>For example: -<programlisting> -if [ "$(echo "$x" | egrep '.*foo.*')" != "" ] ; then - do_something ; -done -</programlisting> -can be re-written using ksh93 builtin constructs, saving several -<literal>|fork()|+|exec()|</literal>'s: -<programlisting> -if [[ "${x}" == ~(E).*foo.* ]] ; then - do_something ; -done -</programlisting> - </para> - </section> - - - <section xml:id="use_dashdash_if_first_arg_is_variable"> - <title>If the first operand of a command is a variable, use <literal>--</literal></title> - <para>If the first operand of a command is a variable, use <literal>--</literal> - for any command that accepts this as end of argument to - avoid problems if the variable expands to a value starting with <literal>-</literal>. - </para> - <note><para> - At least - <simplelist type="inline"> - <member>print</member> - <member>/usr/bin/fgrep</member><member>/usr/xpg4/bin/fgrep</member> - <member>/usr/bin/grep</member> <member>/usr/xpg4/bin/grep</member> - <member>/usr/bin/egrep</member><member>/usr/xpg4/bin/egrep</member> - </simplelist> - support <literal>--</literal> as "end of arguments"-terminator. - </para></note> - </section> - - <section xml:id="use_export"> - <title>&tag_kshonly;&tag_performance;Use <literal>$ export FOOBAR=val #</literal> instead of - <literal>$ FOOBAR=val ; export FOOBAR #</literal></title> - <para>Use <literal>$ export FOOBAR=val # instead of $ FOOBAR=val ; export FOOBAR #</literal> - - this is much faster.</para> - </section> - - - <section xml:id="use_subshell_around_set_dashdash_usage"> - <title>Use a subshell (e.g. <literal>$ ( mycmd ) #</literal>) around places which use - <literal>set -- $(mycmd)</literal> and/or <literal>shift</literal></title> - <para>Use a subshell (e.g. <literal>$ ( mycmd ) #</literal>) around places which use - <literal>set -- $(mycmd)</literal> and/or <literal>shift</literal> unless the variable - affected is either a local one or if it's guaranteed that this variable will no longer be used - (be careful for loadable functions, e.g. ksh/ksh93's <literal>autoload</literal> !!!!) - </para> - </section> - - - <section xml:id="be_careful_with_tabs_in_script_code"> - <title>Be careful with using TABS in script code, they are not portable - between editors or platforms</title> - <para>Be careful with using TABS in script code, they are not portable - between editors or platforms.</para> - <para>If you use ksh93 use <literal>$'\t'</literal> to include TABs in sources, not the TAB character itself.</para> - </section> - - - <section xml:id="centralise_error_exit"> - <title>If you have multiple points where your application exits with an error - message create a central function for this purpose</title> - <para>If you have multiple points where your application exits with an error - message create a central function for this, e.g. -<programlisting> -if [ -z "$tmpdir" ] ; then - print -u2 "mktemp failed to produce output; aborting." - exit 1 -fi -if [ ! -d $tmpdir ] ; then - print -u2 "mktemp failed to create a directory; aborting." - exit 1 -fi -</programlisting> -should be replaced with -<programlisting> -function fatal_error -{ - print -u2 "${progname}: $*" - exit 1 -} -# do something (and save ARGV[0] to variable "progname") -if [ -z "$tmpdir" ] ; then - fatal_error "mktemp failed to produce output; aborting." -fi -if [ ! -d "$tmpdir" ] ; then - fatal_error "mktemp failed to create a directory; aborting." -fi -</programlisting> - </para> - </section> - - - <section xml:id="use_set_o_nounset"> - <title>&tag_kshonly; Think about using <literal>$ set -o nounset #</literal> by default</title> - <para>Think about using <literal>$ set -o nounset #</literal> by default (or at least during the - script's development phase) to catch errors where variables are used - when they are not set (yet), e.g. -<screen> -$ <userinput>(set -o nounset ; print ${foonotset})</userinput> -<computeroutput>/bin/ksh93: foonotset: parameter not set</computeroutput> -</screen> - </para> - </section> - - - <section xml:id="avoid_eval_builtin"> - <title>Avoid using <literal>eval</literal> unless absolutely necessary</title> - <para>Avoid using <literal>eval</literal> unless absolutely necessary. Subtle things - can happen when a string is passed back through the shell - parser. You can use name references to avoid uses such as - <literal>eval $name="$value"</literal>. - </para> - </section> - - - <section xml:id="use_concatenation_operator"> - <title>&tag_ksh93only;Use the string/array concatenation operator <literal>+=</literal></title> - <para>Use <literal>+=</literal> instead of manually adding strings/array elements, e.g. -<programlisting> -foo="" -foo="${foo}a" -foo="${foo}b" -foo="${foo}c" -</programlisting> -should be replaced with -<programlisting> -foo="" -foo+="a" -foo+="b" -foo+="c" -</programlisting> - </para> - </section> - - <section xml:id="use_source_not_dot"> - <title>&tag_ksh93only;Use <literal>source</literal> instead of '<literal>.</literal> '(dot) - to include other shell script fragments</title> - <para>Use <literal>source</literal> instead of '<literal>.</literal>' - (dot) to include other shell script fragments - the new form is much - more readable than the tiny dot and a failure can be caught within the script.</para> - </section> - - - <section xml:id="use_builtin_localisation_support"> - <title>&tag_ksh93only;&tag_performance;&tag_l10n;Use <literal>$"..."</literal> instead of - <literal>gettext ... "..."</literal> for strings that need to be localized for different locales</title> - <para>Use $"..." instead of <literal>gettext ... "..."</literal> for strings that need to be - localized for different locales. <literal>gettext</literal> will require a - <literal>fork()+exec()</literal> and - reads the whole catalog each time it's called, creating a huge overhead for localisation - (and the <literal>$"..."</literal> is easier to use, e.g. you only have to put a - <literal>$</literal> in front of the catalog and the string will be localised). - </para> - </section> - - - <section xml:id="use_set_o_noglob"> - <title>&tag_kshonly;&tag_performance;Use <literal>set -o noglob</literal> if you do not need to expand files</title> - <para>If you don't expect to expand files, you can do set <literal>-f</literal> - (<literal>set -o noglob</literal>) as well. This way the need to use <literal>""</literal> is - greatly reduced.</para> - </section> - - - <section xml:id="use_empty_ifs_to_handle_spaces"> - <title>&tag_ksh93only;Use <literal>IFS=</literal> to avoid problems with spaces in filenames</title> - <para>Unless you want to do word splitting, put <literal>IFS=</literal> - at the beginning of a command. This way spaces in - file names won't be a problem. You can do - <literal>IFS='delims' read -r</literal> line - to override <envar>IFS</envar> just for the <literal>read</literal> command. However, - you can't do this for the <literal>set</literal> builtin.</para> - </section> - - - <section xml:id="set_locale_when_comparing_against_localised_output"> - <title>Set the message locale if you process output of tools which may be localised</title> - <para>Set the message locale (<envar>LC_MESSAGES</envar>) if you process output of tools which may be localised</para> - <example><title>Set <envar>LC_MESSAGES</envar> when testing for specific outout of the <filename>/usr/bin/file</filename> utility:</title> -<programlisting> -# set french as default message locale -export LC_MESSAGES=fr_FR.UTF-8 - -... - -# test whether the file "/tmp" has the filetype "directory" or not -# we set LC_MESSAGES to "C" to ensure the returned message is in english -if [[ "$(LC_MESSAGES=C file /tmp)" = *directory ]] ; then - print "is a directory" -fi -</programlisting> - <note><para>The environment variable <envar>LC_ALL</envar> always - overrides any other <envar>LC_*</envar> environment variables - (and <envar>LANG</envar>, too), - including <envar>LC_MESSAGES</envar>. - if there is the chance that <envar>LC_ALL</envar> may be set - replace <envar>LC_MESSAGES</envar> with <envar>LC_ALL</envar> - in the example above.</para></note> - </example> - </section> - - <section xml:id="cleanup_after_yourself"> - <title>Cleanup after yourself.</title> - <para>Cleanup after yourself. For example ksh/ksh93 have an <literal>EXIT</literal> trap which - is very useful for this. - </para> - <note><para> - Note that the <literal>EXIT</literal> trap is executed for a subshell and each subshell - level can run it's own <literal>EXIT</literal> trap, for example -<screen> -$ <userinput>(trap "print bam" EXIT ; (trap "print snap" EXIT ; print "foo"))</userinput> -<computeroutput>foo -snap -bam</computeroutput> -</screen> - </para></note> - </section> - - <section xml:id="use_proper_exit_code"> - <title>Use a proper <literal>exit</literal> code</title> - <para>Explicitly set the exit code of a script, otherwise the exit code - from the last command executed will be used which may trigger problems - if the value is unexpected.</para> - </section> - - - <section xml:id="shell_lint"> - <title>&tag_ksh93only;Use <literal>shcomp -n scriptname.sh /dev/null</literal> to check for common errors</title> - <para>Use <literal>shcomp -n scriptname.sh /dev/null</literal> to - check for common problems (such as insecure, depreciated or ambiguous constructs) in shell scripts.</para> - </section> - </section><!-- end of general --> - - - - - - <section xml:id="functions"> - <title>Functions</title> - - <section xml:id="use_functions"> - <title>Use functions to break up your code</title> - <para>Use functions to break up your code into smaller, logical blocks.</para> - </section> - - <section xml:id="do_not_reserved_keywords_for_function_names"> - <title>Do not use function names which are reserved keywords in C/C++/JAVA or the POSIX shell standard</title> - <para>Do not use function names which are reserved keywords (or function names) in C/C++/JAVA or the POSIX shell standard - (to avoid confusion and/or future changes/updates to the shell language). - </para> - </section> - - <section xml:id="use_ksh_style_function_syntax"> - <title>&tag_kshonly;&tag_performance;Use ksh-style <literal>function</literal></title> - <para>It is <emphasis>highly</emphasis> recommended to use ksh style functions - (<literal>function foo { ... }</literal>) instead - of Bourne-style functions (<literal>foo() { ... }</literal>) if possible - (and local variables instead of spamming the global namespace).</para> - - <warning><para> - The difference between old-style Bourne functions and ksh functions is one of the major differences - between ksh88 and ksh93 - ksh88 allowed variables to be local for Bourne-style functions while ksh93 - conforms to the POSIX standard and will use a function-local scope for variables declared in - Bourne-style functions.</para> - <para>Example (note that "<literal>integer</literal>" is an alias for "<literal>typeset -li</literal>"): -<programlisting> -# new style function with local variable -$ ksh93 -c 'integer x=2 ; function foo { integer x=5 ; } ; print "x=$x" -; foo ; print "x=$x" ;' -x=2 -x=2 -# old style function with an attempt to create a local variable -$ ksh93 -c 'integer x=2 ; foo() { integer x=5 ; } ; print "x=$x" ; foo ; -print "x=$x" ;' -x=2 -x=5 -</programlisting> - - <uri xlink:href="http://www.opensolaris.org/os/project/ksh93-integration/docs/ksh93r/general/compatibility/">usr/src/lib/libshell/common/COMPATIBILITY</uri> - says about this issue: -<blockquote><para> -Functions, defined with name() with ksh-93 are compatible with -the POSIX standard, not with ksh-88. No local variables are -permitted, and there is no separate scope. Functions defined -with the function name syntax, maintain compatibility. -This also affects function traces. -</para></blockquote> -(this issue also affects <filename>/usr/xpg4/bin/sh</filename> in Solaris 10 because it is based on ksh88. This is a bug.). - </para></warning> - - </section> - - - <section xml:id="use_proper_return_code"> - <title>Use a proper <literal>return</literal> code</title> - <para>Explicitly set the return code of a function - otherwise the exit code - from the last command executed will be used which may trigger problems - if the value is unexpected.</para> - <para>The only allowed exception is if a function uses the shell's <literal>errexit</literal> mode to leave - a function, subshell or the script if a command returns a non-zero exit code. - </para> - </section> - - <section xml:id="use_fpath_to_load_common_code"> - <title>&tag_kshonly;Use <envar>FPATH</envar> to load common functions, not <literal>source</literal></title> - <para> - Use the ksh <envar>FPATH</envar> (function path) feature to load functions which are shared between scripts - and not <literal>source</literal> - this allows to load such a function on demand and not all at once.</para> - </section> - - </section><!-- end of functions --> - - - - - <section xml:id="if_for_while"> - <title><literal>if</literal>, <literal>for</literal> and <literal>while</literal></title> - - <section xml:id="if_for_while_format"> - <title>Format</title> - <para>To match <literal>cstyle</literal>, the shell token equivalent to the <literal>C</literal> - "<literal>{</literal>" should appear on the same line, separated by a - "<literal>;</literal>", as in: -<programlisting> -if [ "$x" = "hello" ] ; then - echo $x -fi - -if [[ "$x" = "hello" ]] ; then - print $x -fi - -for i in 1 2 3; do - echo $i -done - -for ((i=0 ; i < 3 ; i++)); do - print $i -done - -while [ $# -gt 0 ]; do - echo $1 - shift -done - -while (( $# > 0 )); do - print $1 - shift -done -</programlisting> - </para> - </section> - - - <section xml:id="test_builtin"> - <title><literal>test</literal> Builtin</title> - <para>DO NOT use the test builtin. Sorry, executive decision.</para> - <para>In our Bourne shell, the <literal>test</literal> built-in is the same as the "[" - builtin (if you don't believe me, try "type test" or refer to <filename>usr/src/cmd/sh/msg.c</filename>).</para> - <para> - So please do not write: -<programlisting> -if test $# -gt 0 ; then -</programlisting> -instead use: -<programlisting> -if [ $# -gt 0 ] ; then -</programlisting> - </para> - </section> - - - <section xml:id="use_ksh_test_syntax"> - <title>&tag_kshonly;&tag_performance;Use "<literal>[[ expr ]]</literal>" instead of "<literal>[ expr ]</literal>"</title> - <para>Use "<literal>[[ expr ]]</literal>" instead of "<literal>[ expr ]</literal>" if possible - since it avoids going through the whole pattern expansion/etc. machinery and - adds additional operators not available in the Bourne shell, such as short-circuit - <literal>&&</literal> and <literal>||</literal>. - </para> - </section> - - - <section xml:id="use_posix_arithmetic_expressions"> - <title>&tag_kshonly; Use "<literal>(( ... ))</literal>" for arithmetic expressions</title> - <para>Use "<literal>(( ... ))</literal>" instead of "<literal>[ expr ]</literal>" - or "<literal>[[ expr ]]</literal>" expressions. - </para> - <para> - Example: Replace -<programlisting> -i=5 -# do something -if [ $i -gt 5 ] ; then -</programlisting> -with -<programlisting> -i=5 -# do something -if (( i > 5 )) ; then -</programlisting> - </para> - </section> - - - <section xml:id="compare_exit_code_using_math"> - <title>&tag_kshonly;&tag_performance;Compare exit code using arithmetic expressions expressions</title> - <para>Use POSIX arithmetic expressions to test for exit/return codes of commands and functions. - For example turn -<programlisting> -if [ $? -gt 0 ] ; then -</programlisting> -into -<programlisting> -if (( $? > 0 )) ; then -</programlisting> - </para> - </section> - - - <section xml:id="use_builtin_commands_in_loops"> - <title>&tag_bourneonly; Use builtin commands in conditions for <literal>while</literal> endless loops</title> - <para>Make sure that your shell has a "<literal>true</literal>" builtin (like ksh93) when - executing endless loops like <literal>$ while true ; do do_something ; done #</literal> - - otherwise each loop cycle runs a <literal>|fork()|+|exec()|</literal>-cycle to run - <filename>/bin/true</filename> - </para> - </section> - - - <section xml:id="single_line_if_statements"> - <title>Single-line if-statements</title> - <para>It is permissible to use <literal>&&</literal> and <literal>||</literal> to construct - shorthand for an "<literal>if</literal>" statement in the case where the if statement has a - single consequent line: -<programlisting> -[ $# -eq 0 ] && exit 0 -</programlisting> -instead of the longer: -<programlisting> -if [ $# -eq 0 ]; then - exit 0 -fi -</programlisting> - </para> - </section> - - - <section xml:id="exit_status_and_if_for_while"> - <title>Exit Status and <literal>if</literal>/<literal>while</literal> statements</title> - <para>Recall that "<literal>if</literal>" and "<literal>while</literal>" - operate on the exit status of the statement - to be executed. In the shell, zero (0) means true and non-zero means false. - The exit status of the last command which was executed is available in the $? - variable. When using "<literal>if</literal>" and "<literal>while</literal>", - it is typically not necessary to use - <literal>$?</literal> explicitly, as in: -<programlisting> -grep foo /etc/passwd >/dev/null 2>&1 -if [ $? -eq 0 ]; then - echo "found" -fi -</programlisting> -Instead, you can more concisely write: -<programlisting> -if grep foo /etc/passwd >/dev/null 2>&1; then - echo "found" -fi -</programlisting> -Or, when appropriate: -<programlisting> -grep foo /etc/passwd >/dev/null 2>&1 && echo "found" -</programlisting> - </para> - </section> - - </section><!-- end of if/for/while --> - - - - - - - <section xml:id="variables"> - <title>Variable types, naming and usage</title> - - <section xml:id="names_should_be_lowercase"> - <title>Names of local, non-environment, non-constant variables should be lowercase</title> - <para>Names of variables local to the current script which are not exported to the environment - should be lowercase while variable names which are exported to the - environment should be uppercase.</para> - <para>The only exception are global constants (=global readonly variables, - e.g. <literal>$ float -r M_PI=3.14159265358979323846 #</literal> (taken from <math.h>)) - which may be allowed to use uppercase names, too. - </para> - - <warning><para> - Uppercase variable names should be avoided because there is a good chance - of naming collisions with either special variable names used by the shell - (e.g. <literal>PWD</literal>, <literal>SECONDS</literal> etc.). - </para></warning> - </section> - - <section xml:id="do_not_reserved_keywords_for_variable_names"> - <title>Do not use variable names which are reserved keywords/variable names in C/C++/JAVA or the POSIX shell standard</title> - <para>Do not use variable names which are reserved keywords in C/C++/JAVA or the POSIX shell standard - (to avoid confusion and/or future changes/updates to the shell language). - </para> - <note> - <para>The Korn Shell and the POSIX shell standard have many more - reserved variable names than the original Bourne shell. All - these reserved variable names are spelled uppercase. - </para> - </note> - </section> - - <section xml:id="use_brackets_around_long_names"> - <title>Always use <literal>'{'</literal>+<literal>'}'</literal> when using variable - names longer than one character</title> - <para>Always use <literal>'{'</literal>+<literal>'}'</literal> when using - variable names longer than one character unless a simple variable name is - followed by a blank, <literal>/</literal>, <literal>;</literal>, or <literal>$</literal> - character (to avoid problems with array, - compound variables or accidental misinterpretation by users/shell) -<programlisting> -print "$foo=info" -</programlisting> -should be rewritten to -<programlisting> -print "${foo}=info" -</programlisting> - </para> - </section> - - - <section xml:id="quote_variables_containing_filenames_or_userinput"> - <title><emphasis>Always</emphasis> put variables into quotes when handling filenames or user input</title> - <para><emphasis>Always</emphasis> put variables into quotes when handling filenames or user input, even if - the values are hardcoded or the values appear to be fixed. Otherwise at - least two things may go wrong: - <itemizedlist> - <listitem><para>a malicious user may be able to exploit a script's inner working to - infect his/her own code</para></listitem> - <listitem><para>a script may (fatally) misbehave for unexpected input (e.g. file names - with blanks and/or special symbols which are interpreted by the shell)</para></listitem> - </itemizedlist> - </para> - - <note><para> - As alternative a script may set <literal>IFS='' ; set -o noglob</literal> to turn off the - interpretation of any field seperators and the pattern globbing. - </para></note> - </section> - - - - <section xml:id="use_typed_variables"> - <title>&tag_kshonly;&tag_performance;Use typed variables if possible.</title> - <para>For example the following is very - inefficient since it transforms the integer values to strings and back - several times: -<programlisting> -a=0 -b=1 -c=2 -# more code -if [ $a -lt 5 -o $b -gt c ] ; then do_something ; fi -</programlisting> -This could be rewritten using ksh constructs: -<programlisting> -integer a=0 -integer b=1 -integer c=2 -# more code -if (( a < 5 || b > c )) ; then do_something ; fi -</programlisting> - </para> - </section> - - - <section xml:id="store_lists_in_arrays"> - <title>&tag_ksh93only; Store lists in arrays or associative arrays</title> - <para>Store lists in arrays or associative arrays - this is usually easier - to manage.</para> - <para> - For example: -<programlisting> -x=" -/etc/foo -/etc/bar -/etc/baz -" -echo $x -</programlisting> -can be replaced with -<programlisting> -typeset -a mylist -mylist[0]="/etc/foo" -mylist[1]="/etc/bar" -mylist[2]="/etc/baz" -print "${mylist[@]}" -</programlisting> -or (ksh93-style append entries to a normal (non-associative) array) -<programlisting> -typeset -a mylist -mylist+=( "/etc/foo" ) -mylist+=( "/etc/bar" ) -mylist+=( "/etc/baz" ) -print "${mylist[@]}" -</programlisting> - </para> - <note> - <title>Difference between expanding arrays with mylist[@] and mylist[*] subscript operators</title> - <para> - Arrays may be expanded using two similar subscript operators, @ and *. These subscripts - differ only when the variable expansion appears within double quotes. If the variable expansion - is between double-quotes, "${mylist[*]}" expands to a single string with the value of each array - member separated by the first character of the <envar>IFS</envar> variable, and "${mylist[@]}" - expands each element of name to a separate string. - </para> - <example><title>Difference between [@] and [*] when expanding arrays</title> -<programlisting> -typeset -a mylist -mylist+=( "/etc/foo" ) -mylist+=( "/etc/bar" ) -mylist+=( "/etc/baz" ) -IFS="," -printf "mylist[*]={ 0=|%s| 1=|%s| 2=|%s| 3=|%s| }\n" "${mylist[*]}" -printf "mylist[@]={ 0=|%s| 1=|%s| 2=|%s| 3=|%s| }\n" "${mylist[@]}" -</programlisting> -<para>will print:</para> -<screen> -<computeroutput>mylist[*]={ 0=|/etc/foo,/etc/bar,/etc/baz| 1=|| 2=|| 3=|| } -mylist[@]={ 0=|/etc/foo| 1=|/etc/bar| 2=|/etc/baz| 3=|| } -</computeroutput> -</screen> - </example> - </note> - </section> - - - <section xml:id="use_compound_variables_or_lists_for_grouping"> - <title>&tag_ksh93only; Use compound variables or associative arrays to group similar variables together</title> - <para>Use compound variables or associative arrays to group similar variables together.</para> - <para> - For example: -<programlisting> -box_width=56 -box_height=10 -box_depth=19 -echo "${box_width} ${box_height} ${box_depth}" -</programlisting> -could be rewritten to ("associative array"-style) -<programlisting> -typeset -A -E box=( [width]=56 [height]=10 [depth]=19 ) -print -- "${box[width]} ${box[height]} ${box[depth]}" -</programlisting> -or ("compound variable"-style -<programlisting> -box=( - float width=56 - float height=10 - float depth=19 - ) -print -- "${box.width} ${box.height} ${box.depth}" -</programlisting> - </para> - </section> - </section><!-- end of variables --> - - - - - - - - <section xml:id="io"> - <title>I/O</title> - - <section xml:id="avoid_echo"> - <title>Avoid using the "<literal>echo</literal>" command for output</title> - <para>The behaviour of "<literal>echo</literal>" is not portable - (e.g. System V, BSD, UCB and ksh93/bash shell builtin versions all - slightly differ in functionality) and should be avoided if possible. - POSIX defines the "<literal>printf</literal>" command as replacement - which provides more flexible and portable behaviour.</para> - - <note> - <title>&tag_kshonly;Use "<literal>print</literal>" and not "<literal>echo</literal>" in Korn Shell scripts</title> - <para>Korn shell scripts should prefer the "<literal>print</literal>" - builtin which was introduced as replacement for "<literal>echo</literal>".</para> - <caution> - <para>Use <literal>$ print -- ${varname}" #</literal> when there is the slightest chance that the - variable "<literal>varname</literal>" may contain symbols like "-". Or better use "<literal>printf</literal>" - instead, for example -<programlisting> -integer fx -# do something -print $fx -</programlisting> -may fail if "f" contains a negative value. A better way may be to use -<programlisting> -integer fx -# do something -printf "%d\n" fx -</programlisting> - </para> - </caution> - </note> - </section> - - <section xml:id="use_redirect_not_exec_to_open_files"> - <title>&tag_ksh93only;Use <literal>redirect</literal> and not <literal>exec</literal> to open files</title> - <para>Use <literal>redirect</literal> and not <literal>exec</literal> to open files - <literal>exec</literal> - will terminate the current function or script if an error occurs while <literal>redirect</literal> - just returns a non-zero exit code which can be caught.</para> -<para>Example: -<programlisting> -if redirect 5</etc/profile ; then - print "file open ok" - head <&5 -else - print "could not open file" -fi -</programlisting> - </para> - </section> - - <section xml:id="group_identical_redirections_together"> - <title>&tag_performance;Avoid redirections per command when the output goes into the same file, - e.g. <literal>$ echo "foo" >xxx ; echo "bar" >>xxx ; echo "baz" >>xxx #</literal></title> - <para>Each of the redirections above trigger an - <literal>|open()|,|write()|,|close()|</literal>-sequence. It is much - more efficient (and faster) to group the rediction into a block, - e.g. <literal>{ echo "foo" ; echo "bar" ; echo "baz" } >xxx #</literal></para> - </section> - - - <section xml:id="avoid_using_temporary_files"> - <title>&tag_performance;Avoid the creation of temporary files and store the values in variables instead</title> - <para>Avoid the creation of temporary files and store the values in variables instead if possible</para> - <para> - Example: -<programlisting> -ls -1 >xxx -for i in $(cat xxx) ; do - do_something ; -done -</programlisting> -can be replaced with -<programlisting> -x="$(ls -1)" -for i in ${x} ; do - do_something ; -done -</programlisting> - </para> - <note><para>ksh93 supports binary variables (e.g. <literal>typeset -b varname</literal>) which can hold any value.</para></note> - </section> - - - <section xml:id="create_subdirs_for_multiple_temporary_files"> - <title>If you create more than one temporary file create an unique subdir</title> - <para>If you create more than one temporary file create an unique subdir for - these files and make sure the dir is writable. Make sure you cleanup - after yourself (unless you are debugging). - </para> - </section> - - - <section xml:id="use_dynamic_file_descriptors"> - <title>&tag_ksh93only;Use {n}<file instead of fixed file descriptor numbers</title> - <para>When opening a file use {n}<file, where <envar>n</envar> is an - integer variable rather than specifying a fixed descriptor number.</para> - <para>This is highly recommended in functions to avoid that fixed file - descriptor numbers interfere with the calling script.</para> -<example><title>Open a network connection and store the file descriptor number in a variable</title> -<programlisting> -function cat_http -{ - integer netfd - -... - - # open TCP channel - redirect {netfd}<>"/dev/tcp/${host}/${port}" - - # send HTTP request - request="GET /${path} HTTP/1.1\n" - request+="Host: ${host}\n" - request+="User-Agent: demo code/ksh93 (2007-08-30; $(uname -s -r -p))\n" - request+="Connection: close\n" - print "${request}\n" >&${netfd} - - # collect response and send it to stdout - cat <&${netfd} - - # close connection - exec {netfd}<&- - -... - -} -</programlisting> -</example> - </section> - - - <section xml:id="use_inline_here_documents"> - <title>&tag_ksh93only;&tag_performance;Use inline here documents - instead of <literal>echo "$x" | command</literal></title> - <para>Use inline here documents, for example -<programlisting> -command <<< $x -</programlisting> - rather than -<programlisting> -print -r -- "$x" | command -</programlisting> - </para> - </section> - - - <section xml:id="use_read_r"> - <title>&tag_ksh93only;Use the <literal>-r</literal> option of <literal>read</literal> to read a line</title> - <para>Use the <literal>-r</literal> option of <literal>read</literal> to read a line. - You never know when a line will end in <literal>\</literal> and without a - <literal>-r</literal> multiple - lines can be read.</para> - </section> - - - <section xml:id="print_compound_variables_using_print_C"> - <title>&tag_ksh93only;Print compound variables using <literal>print -C varname</literal> or <literal>print -v varname</literal></title> - <para>Print compound variables using <literal>print -C varname</literal> or - <literal>print -v varname</literal> to make sure that non-printable characters - are correctly encoded.</para> -<example><title>Print compound variable with non-printable characters</title> -<programlisting> -compound x=( - a=5 - b="hello" - c=( - d=9 - e="$(printf "1\v3")" <co xml:id="co.vertical_tab1" /> - ) -) -print -v x -</programlisting> -<para>will print:</para> -<screen> -<computeroutput>( - a=5 - b=hello - c=( - d=9 - e=$'1\0133' <co xml:id="co.vertical_tab2" /> - ) -)</computeroutput> -</screen> -<calloutlist> - <callout arearefs="co.vertical_tab1 co.vertical_tab2"> - <para>vertical tab, <literal>\v</literal>, octal=<literal>\013</literal>.</para> - </callout> -</calloutlist> -</example> - </section> - - <section xml:id="command_name_before_redirections"> - <title>Put the command name and arguments before redirections</title> - <para>Put the command name and arguments before redirections. - You can legally do <literal>$ > file date</literal> instead of <literal>date > file</literal> - but don't do it.</para> - </section> - - <section xml:id="enable_gmacs_editor_mode_for_user_prompts"> - <title>&tag_ksh93only;Enable the <literal>gmacs</literal> editor - mode when reading user input using the <literal>read</literal> builtin</title> - <para>Enable the <literal>gmacs</literal>editor mode before reading user - input using the <literal>read</literal> builtin to enable the use of - cursor+backspace+delete keys in the edit line</para> -<example><title>Prompt user for a string with gmacs editor mode enabled</title> -<programlisting> -set -o gmacs <co xml:id="co.enable_gmacs" /> -typeset inputstring="default value" -... -read -v<co xml:id="co.read_v" /> inputstring<co xml:id="co.readvar" />?"Please enter a string: "<co xml:id="co.prompt" /> -... -printf "The user entered the following string: '%s'\n" "${inputstring}" - -... -</programlisting> -<calloutlist> - <callout arearefs="co.enable_gmacs"> - <para>Enable gmacs editor mode.</para> - </callout> - <callout arearefs="co.read_v"> - <para>The value of the variable is displayed and used as a default value.</para> - </callout> - <callout arearefs="co.readvar"> - <para>Variable used to store the result.</para> - </callout> - <callout arearefs="co.prompt"> - <para>Prompt string which is displayed in stderr.</para> - </callout> -</calloutlist> -</example> - </section> - </section><!-- end of I/O --> - - - - - - - <section xml:id="math"> - <title>Math</title> - - <section xml:id="use_builtin_arithmetic_expressions"> - <title>&tag_kshonly;&tag_performance;Use builtin arithmetic expressions instead of external applications</title> - <para>Use builtin (POSIX shell) arithmetic expressions instead of - <filename>expr</filename>, - <filename>bc</filename>, - <filename>dc</filename>, - <filename>awk</filename>, - <filename>nawk</filename> or - <filename>perl</filename>. - </para> - <note> - <para>ksh93 supports C99-like floating-point arithmetic including special values - such as - <simplelist type="inline"> - <member>+Inf</member> - <member>-Inf</member> - <member>+NaN</member> - <member>-NaN</member> - </simplelist>. - </para> - </note> - </section> - - - <section xml:id="use_floating_point_arithmetic_expressions"> - <title>&tag_ksh93only; Use floating-point arithmetic expressions if - calculations may trigger a division by zero or other exceptions</title> - <para>Use floating-point arithmetic expressions if calculations may - trigger a division by zero or other exceptions - floating point arithmetic expressions in - ksh93 support special values such as <literal>+Inf</literal>/<literal>-Inf</literal> and - <literal>+NaN</literal>/<literal>-NaN</literal> which can greatly simplify testing for - error conditions, e.g. instead of a <literal>trap</literal> or explicit - <literal>if ... then... else</literal> checks for every sub-expression - you can check the results for such special values. - </para> - <para>Example: -<screen> -$ <userinput>ksh93 -c 'integer i=0 j=5 ; print -- "x=$((j/i)) "'</userinput> -<computeroutput>ksh93: line 1: j/i: divide by zero</computeroutput> -$ <userinput>ksh93 -c 'float i=0 j=-5 ; print -- "x=$((j/i)) "'</userinput> -<computeroutput>x=-Inf</computeroutput> -</screen> - </para> - </section> - - - <section xml:id="use_printf_a_for_passing_float_values"> - <title>&tag_ksh93only; Use <literal>printf "%a"</literal> when passing floating-point values</title> - <para>Use <literal>printf "%a"</literal> when passing floating-point values between scripts or - as output of a function to avoid rounding errors when converting between - bases.</para> - <para> - Example: -<programlisting> -function xxx -{ - float val - - (( val=sin(5.) )) - printf "%a\n" val -} -float out -(( out=$(xxx) )) -xxx -print -- $out -</programlisting> -This will print: -<programlisting> --0.9589242747 --0x1.eaf81f5e09933226af13e5563bc6p-01 -</programlisting> - </para> - </section> - - - <section xml:id="put_constants_into_readonly_variables"> - <title>&tag_kshonly;&tag_performance;Put constant values into readonly variables</title> - <para>Put constant values into readonly variables</para> - <para>For example: -<programlisting> -float -r M_PI=3.14159265358979323846 -</programlisting> -or -<programlisting> -float M_PI=3.14159265358979323846 -readonly M_PI -</programlisting> - </para> - </section> - - - <section xml:id="avoid_unnecessary_string_number_conversions"> - <title>&tag_kshonly;&tag_performance;Avoid string to number - (and/or number to string) conversions in arithmetic expressions - expressions</title> - <para>Avoid string to number and/or number to string conversions in - arithmetic expressions expressions to avoid performance degradation - and rounding errors.</para> - <example><title>(( x=$x*2 )) vs. (( x=x*2 ))</title> -<programlisting> -float x -... -(( x=$x*2 )) -</programlisting> -<para> -will convert the variable "x" (stored in the machine's native -<literal>|long double|</literal> datatype) to a string value in base10 format, -apply pattern expansion (globbing), then insert this string into the -arithmetic expressions and parse the value which converts it into the internal |long double| datatype format again. -This is both slow and generates rounding errors when converting the floating-point value between -the internal base2 and the base10 representation of the string. -</para> -<para> -The correct usage would be: -</para> -<programlisting> -float x -... -(( x=x*2 )) -</programlisting> -<para> -e.g. omit the '$' because it's (at least) redundant within arithmetic expressions. -</para> - </example> - - - <example><title>x=$(( y+5.5 )) vs. (( x=y+5.5 ))</title> -<programlisting> -float x -float y=7.1 -... -x=$(( y+5.5 )) -</programlisting> -<para> -will calculate the value of <literal>y+5.5</literal>, convert it to a -base-10 string value amd assign the value to the floating-point variable -<literal>x</literal> again which will convert the string value back to the -internal |long double| datatype format again. -</para> -<para> -The correct usage would be: -</para> -<programlisting> -float x -float y=7.1 -... -(( x=y+5.5 )) -</programlisting> -<para> -i.e. this will save the string conversions and avoid any base2-->base10-->base2-conversions. -</para> - </example> - </section> - - - <section xml:id="set_lc_numeric_when_using_floating_point"> - <title>&tag_ksh93only;Set <envar>LC_NUMERIC</envar> when using floating-point constants</title> - <para>Set <envar>LC_NUMERIC</envar> when using floating-point constants to avoid problems with radix-point - representations which differ from the representation used in the script, for example the <literal>de_DE.*</literal> locale - use ',' instead of '.' as default radix point symbol.</para> - <para>For example: -<programlisting> -# Make sure all math stuff runs in the "C" locale to avoid problems with alternative -# radix point representations (e.g. ',' instead of '.' in de_DE.*-locales). This -# needs to be set _before_ any floating-point constants are defined in this script) -if [[ "${LC_ALL}" != "" ]] ; then - export \ - LC_MONETARY="${LC_ALL}" \ - LC_MESSAGES="${LC_ALL}" \ - LC_COLLATE="${LC_ALL}" \ - LC_CTYPE="${LC_ALL}" - unset LC_ALL -fi -export LC_NUMERIC=C -... -float -r M_PI=3.14159265358979323846 -</programlisting> - </para> - - <note><para>The environment variable <envar>LC_ALL</envar> always overrides all other <envar>LC_*</envar> variables, - including <envar>LC_NUMERIC</envar>. The script should always protect itself against custom <envar>LC_NUMERIC</envar> and - <envar>LC_ALL</envar> values as shown in the example above. - </para></note> - </section> - - - - </section><!-- end of math --> - - - - - - - <section xml:id="misc"> - <title>Misc</title> - - <section xml:id="debug_use_lineno_in_ps4"> - <title>Put <literal>[${LINENO}]</literal> in your <envar>PS4</envar></title> - <para>Put <literal>[${LINENO}]</literal> in your <envar>PS4</envar> prompt so that you will get line - numbers with you run with <literal>-x</literal>. If you are looking at performance - issues put <literal>$SECONDS</literal> in the <envar>PS4</envar> prompt as well.</para> - </section> - - </section><!-- end of misc --> - - - - -</section><!-- end of RULES --> - - - - -</article> diff --git a/usr/src/lib/libsldap/Makefile.com b/usr/src/lib/libsldap/Makefile.com index d03823deb8..0d35b1f794 100644 --- a/usr/src/lib/libsldap/Makefile.com +++ b/usr/src/lib/libsldap/Makefile.com @@ -47,7 +47,7 @@ SRCDIR = ../common CFLAGS += $(CCVERBOSE) LOCFLAGS += -D_REENTRANT -DSUNW_OPTIONS CPPFLAGS += -I../common -I$(SRC)/lib/libldap5/include/ldap \ - -I/usr/include/mps $(LOCFLAGS) + -I$(ADJUNCT_PROTO)/usr/include/mps $(LOCFLAGS) LINTFLAGS += -erroff=E_BAD_PTR_CAST_ALIGN LINTFLAGS64 += -erroff=E_BAD_PTR_CAST_ALIGN diff --git a/usr/src/lib/libsmartsshd/Makefile b/usr/src/lib/libsmartsshd/Makefile new file mode 100644 index 0000000000..50d9545ef1 --- /dev/null +++ b/usr/src/lib/libsmartsshd/Makefile @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.lib + +SUBDIRS= $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +_msg: + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/libsmartsshd/Makefile.com b/usr/src/lib/libsmartsshd/Makefile.com new file mode 100644 index 0000000000..914aab055b --- /dev/null +++ b/usr/src/lib/libsmartsshd/Makefile.com @@ -0,0 +1,47 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +LIBRARY= libsmartsshd.a +VERS= .1 +OBJECTS= sshd-plugin.o + +include ../../Makefile.lib +include ../../Makefile.rootfs + +SRCDIR = ../common +SRCS = $(OBJECTS:%.o=$(SRCDIR)/%.c) + +CPPFLAGS += -I$(SRCDIR) -D_REENTRANT -D_FILE_OFFSET_BITS=64 +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc -ldoor + +$(LINTLIB) := SRCS= $(SRCDIR)/$(LINTSRC) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/libsmartsshd/amd64/Makefile b/usr/src/lib/libsmartsshd/amd64/Makefile new file mode 100644 index 0000000000..31be0ef7e6 --- /dev/null +++ b/usr/src/lib/libsmartsshd/amd64/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libsmartsshd/common/llib-lsmartsshd b/usr/src/lib/libsmartsshd/common/llib-lsmartsshd new file mode 100644 index 0000000000..ace7017d41 --- /dev/null +++ b/usr/src/lib/libsmartsshd/common/llib-lsmartsshd @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/*LINTLIBRARY*/ +/*PROTOLIB1*/ +/* + * + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + diff --git a/usr/src/lib/print/libipp-listener/common/mapfile b/usr/src/lib/libsmartsshd/common/mapfile-vers index 8aaaebddb2..ce5fc7a9c0 100644 --- a/usr/src/lib/print/libipp-listener/common/mapfile +++ b/usr/src/lib/libsmartsshd/common/mapfile-vers @@ -18,13 +18,7 @@ # # CDDL HEADER END # - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $ +# Copyright (c) 2011, Joyent Inc. All rights reserved. # # @@ -43,10 +37,9 @@ $mapfile_version 2 -SYMBOL_VERSION SUNWprivate_1.0 { - global: - ipp_configure_operation; - ipp_process_request; - local: - *; +SYMBOL_VERSION SUNWprivate_1.1 { + global: + sshd_user_rsa_key_allowed; + local: + *; }; diff --git a/usr/src/lib/libsmartsshd/common/sshd-plugin.c b/usr/src/lib/libsmartsshd/common/sshd-plugin.c new file mode 100644 index 0000000000..4f0f0bc1ad --- /dev/null +++ b/usr/src/lib/libsmartsshd/common/sshd-plugin.c @@ -0,0 +1,123 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <alloca.h> +#include <door.h> +#include <errno.h> +#include <fcntl.h> +#include <pwd.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <openssl/rsa.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define LOG_OOM(SZ) fprintf(stderr, "Unable to alloca %d bytes\n", SZ) + +static const char *DOOR = "/var/tmp/._joyent_sshd_key_is_authorized"; +static const char *REQ_FMT_STR = "%s %d %s"; /* name uid fp */ +static const int RETURN_SZ = 2; + +static const int MAX_ATTEMPTS = 2; +static const int SLEEP_PERIOD = 1; + +static int +sshd_allowed_in_capi(struct passwd *pw, const char *fp) +{ + int allowed = 0; + int fd = -1; + int blen = 0; + int attempts = 0; + char *buf = NULL; + door_arg_t door_args = {0}; + + if (pw == NULL || fp == NULL) + return (0); + + blen = snprintf(NULL, 0, REQ_FMT_STR, pw->pw_name, pw->pw_uid, fp) + 1; + + buf = (char *)alloca(blen); + if (buf == NULL) { + LOG_OOM(blen); + return (0); + } + + (void) snprintf(buf, blen, REQ_FMT_STR, pw->pw_name, pw->pw_uid, fp); + door_args.data_ptr = buf; + door_args.data_size = blen; + + door_args.rsize = RETURN_SZ; + door_args.rbuf = alloca(RETURN_SZ); + if (door_args.rbuf == NULL) { + LOG_OOM(RETURN_SZ); + return (0); + } + memset(door_args.rbuf, 0, RETURN_SZ); + + do { + fd = open(DOOR, O_RDWR); + if (fd < 0) + perror("smartplugin: open (of door FD) failed"); + + if (door_call(fd, &door_args) < 0) { + perror("smartplugin: door_call failed"); + } else { + allowed = atoi(door_args.rbuf); + munmap(door_args.rbuf, door_args.rsize); + return (allowed); + } + if (++attempts < MAX_ATTEMPTS) + sleep(SLEEP_PERIOD); + } while (attempts < MAX_ATTEMPTS); + + return (0); +} + +int +sshd_user_rsa_key_allowed(struct passwd *pw, RSA *key, const char *fp) +{ + return sshd_allowed_in_capi(pw, fp); +} + +int +sshd_user_dsa_key_allowed(struct passwd *pw, DSA *key, const char *fp) +{ + return sshd_allowed_in_capi(pw, fp); +} + + +#ifdef __cplusplus +} +#endif diff --git a/usr/src/lib/libsmartsshd/i386/Makefile b/usr/src/lib/libsmartsshd/i386/Makefile new file mode 100644 index 0000000000..2bfe8001d9 --- /dev/null +++ b/usr/src/lib/libsmartsshd/i386/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libumem/Makefile.com b/usr/src/lib/libumem/Makefile.com index 0e726c5646..9c10ded585 100644 --- a/usr/src/lib/libumem/Makefile.com +++ b/usr/src/lib/libumem/Makefile.com @@ -22,6 +22,8 @@ # Copyright 2008 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # +# Copyright (c) 2012, Joyent, Inc. All rights reserved. +# # # The build process for libumem is sightly different from that used by other @@ -65,10 +67,12 @@ SRCS_standalone = $(OBJECTS_standalone:%.o=../common/%.c) # Architecture-dependent files common to both versions of libumem OBJECTS_common_isadep = \ - asm_subr.o + asm_subr.o \ + umem_genasm.o SRCS_common_isadep = \ - $(ISASRCDIR)/asm_subr.s + $(ISASRCDIR)/asm_subr.s \ + $(ISASRCDIR)/umem_genasm.c # Architecture-independent files common to both versions of libumem OBJECTS_common_common = \ @@ -115,6 +119,8 @@ MAPFILE_SUPPLEMENTAL = $(MAPFILE_SUPPLEMENTAL_$(CURTYPE)) LDLIBS += -lc +DYNFLAGS += -Wl,-Plibumem_trampoline.so.1 + LDFLAGS_standalone = $(ZNOVERSION) $(BREDUCE) -M../common/mapfile-vers \ -M$(MAPFILE_SUPPLEMENTAL) -dy -r LDFLAGS = $(LDFLAGS_$(CURTYPE)) diff --git a/usr/src/lib/libumem/amd64/umem_genasm.c b/usr/src/lib/libumem/amd64/umem_genasm.c new file mode 100644 index 0000000000..7dad57505b --- /dev/null +++ b/usr/src/lib/libumem/amd64/umem_genasm.c @@ -0,0 +1,609 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + +/* + * Don't Panic! If you find the blocks of assembly that follow confusing and + * you're questioning why they exist, please go read section 8 of the umem.c big + * theory statement. Next familiarize yourself with the malloc and free + * implementations in libumem's malloc.c. + * + * What follows is the amd64 implementation of the thread caching automatic + * assembly generation. The amd64 calling conventions are documented in the + * 64-bit System V ABI. For our purposes what matters is that our first argument + * will come in rdi. Our functions have to preserve rbp, rbx, and r12->r15. We + * are free to do whatever we want with rax, rcx, rdx, rsi, rdi, and r8->r11. + * + * For both our implementation of malloc and free we only use the registers we + * don't have to preserve. + * + * Malloc register usage: + * o. rdi: Original size to malloc. This never changes and is preserved. + * o. rsi: Adjusted malloc size for malloc_data_tag(s). + * o. rcx: Pointer to the tmem_t in the ulwp_t. + * o. rdx: Pointer to the tmem_t array of roots + * o. r8: Size of the cache + * o. r9: Scratch register + * + * Free register usage: + * o. rdi: Original buffer to free. This never changes and is preserved. + * o. rax: The actual buffer, adjusted for the hidden malloc_data_t(s). + * o. rcx: Pointer to the tmem_t in the ulwp_t. + * o. rdx: Pointer to the tmem_t array of roots + * o. r8: Size of the cache + * o. r9: Scratch register + * + * Once we determine what cache we are using, we increment %rdx to the + * appropriate offset and set %r8 with the size of the cache. This means that + * when we break out to the normal buffer allocation point %rdx contains the + * head of the linked list and %r8 is the amount that we have to adjust the + * thread's cached amount by. + * + * Each block of assembly has psuedocode that describes its purpose. + */ + +#include <atomic.h> +#include <inttypes.h> +#include <sys/types.h> +#include <strings.h> +#include <umem_impl.h> +#include "umem_base.h" + +int umem_genasm_supported = 1; +uintptr_t umem_genasm_mptr; +uintptr_t umem_genasm_msize; +uintptr_t umem_genasm_fptr; +uintptr_t umem_genasm_fsize; +static uintptr_t umem_genasm_omptr; +static uintptr_t umem_genasm_ofptr; + +#define UMEM_GENASM_MAX64 (UINT32_MAX / sizeof (uintptr_t)) +#define PTC_JMPADDR(dest, src) (dest - (src + 4)) +#define PTC_ROOT_SIZE sizeof (uintptr_t) +#define MULTINOP 0x0000441f0f + +/* + * void *ptcmalloc(size_t orig_size); + * + * size_t size = orig_size + 8; + * if (size > UMEM_SECOND_ALIGN) + * size += 8; + * + * if (size < orig_size) + * goto tomalloc; ! This is overflow + * + * if (size > cache_max) + * goto tomalloc + * + * tmem_t *t = (uintptr_t)curthread() + umem_thr_offset; + * void **roots = t->tm_roots; + */ +#define PTC_MALINIT_JOUT 0x13 +#define PTC_MALINIT_MCS 0x1a +#define PTC_MALINIT_JOV 0x20 +#define PTC_MALINIT_SOFF 0x30 +static const uint8_t malinit[] = { + 0x48, 0x8d, 0x77, 0x08, /* leaq 0x8(%rdi),%rsi */ + 0x48, 0x83, 0xfe, 0x10, /* cmpq $0x10, %rsi */ + 0x76, 0x04, /* jbe +0x4 */ + 0x48, 0x8d, 0x77, 0x10, /* leaq 0x10(%rdi),%rsi */ + 0x48, 0x39, 0xfe, /* cmpq %rdi,%rsi */ + 0x0f, 0x82, 0x00, 0x00, 0x00, 0x00, /* jb +errout */ + 0x48, 0x81, 0xfe, + 0x00, 0x00, 0x00, 0x00, /* cmpq sizeof ($CACHE), %rsi */ + 0x0f, 0x87, 0x00, 0x00, 0x00, 0x00, /* ja +errout */ + 0x64, 0x48, 0x8b, 0x0c, 0x25, + 0x00, 0x00, 0x00, 0x00, /* movq %fs:0x0,%rcx */ + 0x48, 0x81, 0xc1, + 0x00, 0x00, 0x00, 0x00, /* addq $SOFF, %rcx */ + 0x48, 0x8d, 0x51, 0x08, /* leaq 0x8(%rcx),%rdx */ +}; + +/* + * void ptcfree(void *buf); + * + * if (buf == NULL) + * return; + * + * malloc_data_t *tag = buf; + * tag--; + * int size = tag->malloc_size; + * int tagval = UMEM_MALLOC_DECODE(tag->malloc_tag, size); + * if (tagval == MALLOC_SECOND_MAGIC) { + * tag--; + * } else if (tagval != MALLOC_MAGIC) { + * goto tofree; + * } + * + * if (size > cache_max) + * goto tofree; + * + * tmem_t *t = (uintptr_t)curthread() + umem_thr_offset; + * void **roots = t->tm_roots; + */ +#define PTC_FRINI_JDONE 0x05 +#define PTC_FRINI_JFREE 0x25 +#define PTC_FRINI_MCS 0x30 +#define PTC_FRINI_JOV 0x36 +#define PTC_FRINI_SOFF 0x46 +static const uint8_t freeinit[] = { + 0x48, 0x85, 0xff, /* testq %rdi,%rdi */ + 0x0f, 0x84, 0x00, 0x00, 0x00, 0x00, /* jmp $JDONE (done) */ + 0x8b, 0x77, 0xf8, /* movl -0x8(%rdi),%esi */ + 0x8b, 0x47, 0xfc, /* movl -0x4(%rdi),%eax */ + 0x01, 0xf0, /* addl %esi,%eax */ + 0x3d, 0x00, 0x70, 0xba, 0x16, /* cmpl $MALLOC_2_MAGIC, %eax */ + 0x75, 0x06, /* jne +0x6 (checkover) */ + 0x48, 0x8d, 0x47, 0xf0, /* leaq -0x10(%rdi),%eax */ + 0xeb, 0x0f, /* jmp +0xf (freebuf) */ + 0x3d, 0x00, 0xc0, 0x10, 0x3a, /* cmpl $MALLOC_MAGIC, %eax */ + 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, /* jmp +JFREE (goto torfree) */ + 0x48, 0x8d, 0x47, 0xf8, /* leaq -0x8(%rdi),%rax */ + 0x48, 0x81, 0xfe, + 0x00, 0x00, 0x00, 0x00, /* cmpq sizeof ($CACHE), %rsi */ + 0x0f, 0x87, 0x00, 0x00, 0x00, 0x00, /* ja +errout */ + 0x64, 0x48, 0x8b, 0x0c, 0x25, + 0x00, 0x00, 0x00, 0x00, /* movq %fs:0x0,%rcx */ + 0x48, 0x81, 0xc1, + 0x00, 0x00, 0x00, 0x00, /* addq $SOFF, %rcx */ + 0x48, 0x8d, 0x51, 0x08, /* leaq 0x8(%rcx),%rdx */ +}; + +/* + * if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * } else ... ! goto next cache + */ +#define PTC_INICACHE_CMP 0x03 +#define PTC_INICACHE_SIZE 0x0c +#define PTC_INICACHE_JMP 0x11 +static const uint8_t inicache[] = { + 0x48, 0x81, 0xfe, + 0x00, 0x00, 0x00, 0x00, /* cmpq sizeof ($CACHE), %rsi */ + 0x77, 0x0c, /* ja +0xc (next cache) */ + 0x49, 0xc7, 0xc0, + 0x00, 0x00, 0x00, 0x00, /* movq sizeof ($CACHE), %r8 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, /* jmp $JMP (allocbuf) */ +}; + +/* + * if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * roots += $CACHE_NUM; + * } else ... ! goto next cache + */ +#define PTC_GENCACHE_CMP 0x03 +#define PTC_GENCACHE_SIZE 0x0c +#define PTC_GENCACHE_NUM 0x13 +#define PTC_GENCACHE_JMP 0x18 +static const uint8_t gencache[] = { + 0x48, 0x81, 0xfe, + 0x00, 0x00, 0x00, 0x00, /* cmpq sizeof ($CACHE), %rsi */ + 0x77, 0x14, /* ja +0xc (next cache) */ + 0x49, 0xc7, 0xc0, + 0x00, 0x00, 0x00, 0x00, /* movq sizeof ($CACHE), %r8 */ + 0x48, 0x81, 0xc2, + 0x00, 0x00, 0x00, 0x00, /* addq $8*ii, %rdx */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp +$JMP (allocbuf ) */ +}; + +/* + * else if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * roots += $CACHE_NUM; + * } else { + * goto tofunc; ! goto tomalloc if ptcmalloc. + * } ! goto tofree if ptcfree. + */ +#define PTC_FINCACHE_CMP 0x03 +#define PTC_FINCACHE_JMP 0x08 +#define PTC_FINCACHE_SIZE 0x0c +#define PTC_FINCACHE_NUM 0x13 +static const uint8_t fincache[] = { + 0x48, 0x81, 0xfe, + 0x00, 0x00, 0x00, 0x00, /* cmpq sizeof ($CACHE), %rsi */ + 0x77, 0x00, /* ja +JMP (to real malloc) */ + 0x49, 0xc7, 0xc0, + 0x00, 0x00, 0x00, 0x00, /* movq sizeof ($CACHE), %r8 */ + 0x48, 0x81, 0xc2, + 0x00, 0x00, 0x00, 0x00, /* addq $8*ii, %rdx */ + +}; + +/* + * if (*root == NULL) + * goto tomalloc; + * + * malloc_data_t *ret = *root; + * *root = *(void **)ret; + * t->tm_size += csize; + * ret->malloc_size = size; + * + * if (size > UMEM_SECOND_ALIGN) { + * ret->malloc_data = UMEM_MALLOC_ENCODE(MALLOC_SECOND_MAGIC, size); + * ret += 2; + * } else { + * ret->malloc_data = UMEM_MALLOC_ENCODE(MALLOC_SECOND_MAGIC, size); + * ret += 1; + * } + * + * return ((void *)ret); + * tomalloc: + * return (malloc(orig_size)); + */ +#define PTC_MALFINI_ALLABEL 0x00 +#define PTC_MALFINI_JMLABEL 0x40 +#define PTC_MALFINI_JMADDR 0x41 +static const uint8_t malfini[] = { + 0x48, 0x8b, 0x02, /* movl (%rdx),%rax */ + 0x48, 0x85, 0xc0, /* testq %rax,%rax */ + 0x74, 0x38, /* je +0x38 (errout) */ + 0x4c, 0x8b, 0x08, /* movq (%rax),%r9 */ + 0x4c, 0x89, 0x0a, /* movq %r9,(%rdx) */ + 0x4c, 0x29, 0x01, /* subq %rsi,(%rcx) */ + 0x48, 0x83, 0xfe, 0x10, /* cmpq $0x10,%rsi */ + 0x76, 0x15, /* jbe +0x15 */ + 0x41, 0xb9, 0x00, 0x70, 0xba, 0x16, /* movl $MALLOC_MAGIC_2, %r9d */ + 0x89, 0x70, 0x08, /* movl %r9d,0x8(%rax) */ + 0x41, 0x29, 0xf1, /* subl %esi, %r9d */ + 0x44, 0x89, 0x48, 0x0c, /* movl %r9d, 0xc(%rax) */ + 0x48, 0x83, 0xc0, 0x10, /* addq $0x10, %rax */ + 0xc3, /* ret */ + 0x41, 0xb9, 0x00, 0xc0, 0x10, 0x3a, /* movl %MALLOC_MAGIC, %r9d */ + 0x89, 0x30, /* movl %esi,(%rax) */ + 0x41, 0x29, 0xf1, /* subl %esi,%r9d */ + 0x44, 0x89, 0x48, 0x04, /* movl %r9d,0x4(%rax) */ + 0x48, 0x83, 0xc0, 0x08, /* addq $0x8,%rax */ + 0xc3, /* ret */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp $MALLOC */ +}; + +/* + * if (t->tm_size + csize > umem_ptc_size) + * goto tofree; + * + * t->tm_size += csize + * *(void **)tag = *root; + * *root = tag; + * return; + * tofree: + * free(buf); + * return; + */ +#define PTC_FRFINI_RBUFLABEL 0x00 +#define PTC_FRFINI_CACHEMAX 0x09 +#define PTC_FRFINI_DONELABEL 0x1b +#define PTC_FRFINI_JFLABEL 0x1c +#define PTC_FRFINI_JFADDR 0x1d +static const uint8_t freefini[] = { + 0x4c, 0x8b, 0x09, /* movq (%rcx),%r9 */ + 0x4d, 0x01, 0xc1, /* addq %r8, %r9 */ + 0x49, 0x81, 0xf9, + 0x00, 0x00, 0x00, 0x00, /* cmpl $THR_CACHE_MAX, %r9 */ + 0x77, 0x0d, /* jae +0xd (torfree) */ + 0x4c, 0x01, 0x01, /* addq %r8,(%rcx) */ + 0x4c, 0x8b, 0x0a, /* movq (%rdx),%r9 */ + 0x4c, 0x89, 0x08, /* movq %r9,(%rax) */ + 0x48, 0x89, 0x02, /* movq %rax,(%rdx) */ + 0xc3, /* ret */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp free */ +}; + +/* + * Construct the initial part of malloc. off contains the offset from curthread + * to the root of the tmem structure. ep is the address of the label to error + * and jump to free. csize is the size of the largest umem_cache in ptcumem. + */ +static int +genasm_malinit(uint8_t *bp, uint32_t off, uint32_t ep, uint32_t csize) +{ + uint32_t addr; + + bcopy(malinit, bp, sizeof (malinit)); + addr = PTC_JMPADDR(ep, PTC_MALINIT_JOUT); + bcopy(&addr, bp + PTC_MALINIT_JOUT, sizeof (addr)); + bcopy(&csize, bp + PTC_MALINIT_MCS, sizeof (csize)); + addr = PTC_JMPADDR(ep, PTC_MALINIT_JOV); + bcopy(&addr, bp + PTC_MALINIT_JOV, sizeof (addr)); + bcopy(&off, bp + PTC_MALINIT_SOFF, sizeof (off)); + + return (sizeof (malinit)); +} + +static int +genasm_frinit(uint8_t *bp, uint32_t off, uint32_t dp, uint32_t ep, uint32_t mcs) +{ + uint32_t addr; + + bcopy(freeinit, bp, sizeof (freeinit)); + addr = PTC_JMPADDR(dp, PTC_FRINI_JDONE); + bcopy(&addr, bp + PTC_FRINI_JDONE, sizeof (addr)); + addr = PTC_JMPADDR(ep, PTC_FRINI_JFREE); + bcopy(&addr, bp + PTC_FRINI_JFREE, sizeof (addr)); + bcopy(&mcs, bp + PTC_FRINI_MCS, sizeof (mcs)); + addr = PTC_JMPADDR(ep, PTC_FRINI_JOV); + bcopy(&addr, bp + PTC_FRINI_JOV, sizeof (addr)); + bcopy(&off, bp + PTC_FRINI_SOFF, sizeof (off)); + return (sizeof (freeinit)); +} + + +/* + * Create the initial cache entry of the specified size. The value of ap tells + * us what the address of the label to try and allocate a buffer. This value is + * an offset from the current base to that value. + */ +static int +genasm_firstcache(uint8_t *bp, uint32_t csize, uint32_t ap) +{ + uint32_t addr; + + bcopy(inicache, bp, sizeof (inicache)); + bcopy(&csize, bp + PTC_INICACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_INICACHE_SIZE, sizeof (csize)); + addr = PTC_JMPADDR(ap, PTC_INICACHE_JMP); + ASSERT(addr != 0); + bcopy(&addr, bp + PTC_INICACHE_JMP, sizeof (addr)); + + return (sizeof (inicache)); +} + +static int +genasm_gencache(uint8_t *bp, int num, uint32_t csize, uint32_t ap) +{ + uint32_t addr; + uint32_t coff; + + ASSERT(UINT32_MAX / PTC_ROOT_SIZE > num); + ASSERT(num != 0); + bcopy(gencache, bp, sizeof (gencache)); + bcopy(&csize, bp + PTC_GENCACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_GENCACHE_SIZE, sizeof (csize)); + coff = num * PTC_ROOT_SIZE; + bcopy(&coff, bp + PTC_GENCACHE_NUM, sizeof (coff)); + addr = PTC_JMPADDR(ap, PTC_GENCACHE_JMP); + bcopy(&addr, bp + PTC_GENCACHE_JMP, sizeof (addr)); + + return (sizeof (gencache)); +} + +static int +genasm_lastcache(uint8_t *bp, int num, uint32_t csize, uint32_t ep) +{ + uint8_t eap; + uint32_t coff; + + ASSERT(ep <= 0xff && ep > 7); + ASSERT(UINT32_MAX / PTC_ROOT_SIZE > num); + bcopy(fincache, bp, sizeof (fincache)); + bcopy(&csize, bp + PTC_FINCACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_FINCACHE_SIZE, sizeof (csize)); + coff = num * PTC_ROOT_SIZE; + bcopy(&coff, bp + PTC_FINCACHE_NUM, sizeof (coff)); + eap = ep - PTC_FINCACHE_JMP - 1; + bcopy(&eap, bp + PTC_FINCACHE_JMP, sizeof (eap)); + + return (sizeof (fincache)); +} + +static int +genasm_malfini(uint8_t *bp, uintptr_t mptr) +{ + uint32_t addr; + + bcopy(malfini, bp, sizeof (malfini)); + addr = PTC_JMPADDR(mptr, ((uintptr_t)bp + PTC_MALFINI_JMADDR)); + bcopy(&addr, bp + PTC_MALFINI_JMADDR, sizeof (addr)); + + return (sizeof (malfini)); +} + +static int +genasm_frfini(uint8_t *bp, uint32_t maxthr, uintptr_t fptr) +{ + uint32_t addr; + + bcopy(freefini, bp, sizeof (freefini)); + bcopy(&maxthr, bp + PTC_FRFINI_CACHEMAX, sizeof (maxthr)); + addr = PTC_JMPADDR(fptr, ((uintptr_t)bp + PTC_FRFINI_JFADDR)); + bcopy(&addr, bp + PTC_FRFINI_JFADDR, sizeof (addr)); + + return (sizeof (freefini)); +} + +/* + * The malloc inline assembly is constructed as follows: + * + * o Malloc prologue assembly + * o Generic first-cache check + * o n Generic cache checks (where n = _tmem_get_entries() - 2) + * o Generic last-cache check + * o Malloc epilogue assembly + * + * Generally there are at least three caches. When there is only one cache we + * only use the generic last-cache. In the case where there are two caches, we + * just leave out the middle ones. + */ +static int +genasm_malloc(void *base, size_t len, int nents, int *umem_alloc_sizes) +{ + int ii, off; + uint8_t *bp; + size_t total; + uint32_t allocoff, erroff; + + total = sizeof (malinit) + sizeof (malfini) + sizeof (fincache); + + if (nents >= 2) + total += sizeof (inicache) + sizeof (gencache) * (nents - 2); + + if (total > len) + return (1); + + erroff = total - sizeof (malfini) + PTC_MALFINI_JMLABEL; + allocoff = total - sizeof (malfini) + PTC_MALFINI_ALLABEL; + + bp = base; + + off = genasm_malinit(bp, umem_tmem_off, erroff, + umem_alloc_sizes[nents-1]); + bp += off; + allocoff -= off; + erroff -= off; + + if (nents > 1) { + off = genasm_firstcache(bp, umem_alloc_sizes[0], allocoff); + bp += off; + allocoff -= off; + erroff -= off; + } + + for (ii = 1; ii < nents - 1; ii++) { + off = genasm_gencache(bp, ii, umem_alloc_sizes[ii], allocoff); + bp += off; + allocoff -= off; + erroff -= off; + } + + bp += genasm_lastcache(bp, nents - 1, umem_alloc_sizes[nents - 1], + erroff); + bp += genasm_malfini(bp, umem_genasm_omptr); + ASSERT(((uintptr_t)bp - total) == (uintptr_t)base); + + return (0); +} + +static int +genasm_free(void *base, size_t len, int nents, int *umem_alloc_sizes) +{ + uint8_t *bp; + int ii, off; + size_t total; + uint32_t rbufoff, retoff, erroff; + + /* Assume that nents has already been audited for us */ + total = sizeof (freeinit) + sizeof (freefini) + sizeof (fincache); + if (nents >= 2) + total += sizeof (inicache) + sizeof (gencache) * (nents - 2); + + if (total > len) + return (1); + + erroff = total - (sizeof (freefini) - PTC_FRFINI_JFLABEL); + rbufoff = total - (sizeof (freefini) - PTC_FRFINI_RBUFLABEL); + retoff = total - (sizeof (freefini) - PTC_FRFINI_DONELABEL); + + bp = base; + + off = genasm_frinit(bp, umem_tmem_off, retoff, erroff, + umem_alloc_sizes[nents - 1]); + bp += off; + erroff -= off; + rbufoff -= off; + + if (nents > 1) { + off = genasm_firstcache(bp, umem_alloc_sizes[0], rbufoff); + bp += off; + erroff -= off; + rbufoff -= off; + } + + for (ii = 1; ii < nents - 1; ii++) { + off = genasm_gencache(bp, ii, umem_alloc_sizes[ii], rbufoff); + bp += off; + rbufoff -= off; + erroff -= off; + } + + bp += genasm_lastcache(bp, nents - 1, umem_alloc_sizes[nents - 1], + erroff); + bp += genasm_frfini(bp, umem_ptc_size, umem_genasm_ofptr); + ASSERT(((uintptr_t)bp - total) == (uintptr_t)base); + + return (0); +} + +/*ARGSUSED*/ +int +umem_genasm(int *cp, umem_cache_t **caches, int nc) +{ + int nents, i; + uint8_t *mptr; + uint8_t *fptr; + uint32_t *ptr; + uint64_t v, *vptr; + + mptr = (void *)((uintptr_t)&umem_genasm_mptr + 5); + fptr = (void *)((uintptr_t)&umem_genasm_fptr + 5); + if (umem_genasm_mptr == 0 || umem_genasm_msize == 0 || + umem_genasm_fptr == 0 || umem_genasm_fsize == 0) + return (1); + + /* + * The total number of caches that we can service is the minimum of: + * o the amount supported by libc + * o the total number of umem caches + * o we use a single byte addl, so its MAX_UINT32 / sizeof (uintptr_t). + * For 64-bit, this is MAX_UINT32 >> 3, a lot. + */ + nents = _tmem_get_nentries(); + + if (UMEM_GENASM_MAX64 < nents) + nents = UMEM_GENASM_MAX64; + + if (nc < nents) + nents = nc; + + /* Based on our constraints, this is not an error */ + if (nents == 0 || umem_ptc_size == 0) + return (0); + + /* Grab the original malloc and free locations */ + ptr = (void *)(mptr - 4); + umem_genasm_omptr = *ptr + (uintptr_t)mptr; + ptr = (void *)(fptr - 4); + umem_genasm_ofptr = *ptr + (uintptr_t)fptr; + + /* Take into account the jump */ + if (genasm_malloc(mptr, umem_genasm_fsize - 5, nents, cp) != 0) + return (1); + + if (genasm_free(fptr, umem_genasm_fsize - 5, nents, cp) != 0) + return (1); + + /* nop out the jump with a multibyte jump */ + vptr = (void *)&umem_genasm_mptr; + v = MULTINOP; + v |= *vptr & (0xffffffULL << 40); + (void) atomic_swap_64(vptr, v); + vptr = (void *)&umem_genasm_fptr; + v = MULTINOP; + v |= *vptr & (0xffffffULL << 40); + (void) atomic_swap_64(vptr, v); + + + for (i = 0; i < nents; i++) + caches[i]->cache_flags |= UMF_PTC; + + return (0); +} diff --git a/usr/src/lib/libumem/common/envvar.c b/usr/src/lib/libumem/common/envvar.c index fc3d490a01..2fdf7824c3 100644 --- a/usr/src/lib/libumem/common/envvar.c +++ b/usr/src/lib/libumem/common/envvar.c @@ -25,6 +25,10 @@ * Copyright 2012 Joyent, Inc. All rights reserved. */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + #include <ctype.h> #include <errno.h> #include <limits.h> @@ -151,7 +155,10 @@ static umem_env_item_t umem_options_items[] = { NULL, 0, NULL, &vmem_sbrk_pagesize }, #endif - + { "perthread_cache", "Evolving", ITEM_SIZE, + "Size (in bytes) of per-thread allocation cache", + NULL, 0, NULL, &umem_ptc_size + }, { NULL, "-- end of UMEM_OPTIONS --", ITEM_INVALID } }; diff --git a/usr/src/lib/libumem/common/mapfile-vers b/usr/src/lib/libumem/common/mapfile-vers index 102bd989f7..6a05f0cfaa 100644 --- a/usr/src/lib/libumem/common/mapfile-vers +++ b/usr/src/lib/libumem/common/mapfile-vers @@ -20,6 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # @@ -72,6 +73,10 @@ SYMBOL_VERSION SUNWprivate_1.1 { vmem_walk; vmem_xalloc; vmem_xfree; + umem_genasm_mptr; + umem_genasm_fptr; + umem_genasm_fsize; + umem_genasm_msize; local: *; }; diff --git a/usr/src/lib/libumem/common/stub_stand.c b/usr/src/lib/libumem/common/stub_stand.c index 54635558c3..1a90c6be75 100644 --- a/usr/src/lib/libumem/common/stub_stand.c +++ b/usr/src/lib/libumem/common/stub_stand.c @@ -23,6 +23,9 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ /* * Stubs for the standalone to reduce the dependence on external libraries @@ -125,3 +128,29 @@ issetugid(void) { return (1); } + +int +_tmem_get_nentries(void) +{ + return (0); +} + +uintptr_t +_tmem_get_base(void) +{ + return (0); +} + +/*ARGSUSED*/ +void +_tmem_set_cleanup(void (*f)(int, void *)) +{ +} + +uint64_t +atomic_swap_64(volatile uint64_t *t, uint64_t v) +{ + uint64_t old = *t; + *t = v; + return (old); +} diff --git a/usr/src/lib/libumem/common/umem.c b/usr/src/lib/libumem/common/umem.c index a3eb0b8e6c..e22106e979 100644 --- a/usr/src/lib/libumem/common/umem.c +++ b/usr/src/lib/libumem/common/umem.c @@ -24,7 +24,9 @@ * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ /* * based on usr/src/uts/common/os/kmem.c r1.64 from 2001/12/18 @@ -44,7 +46,7 @@ * * 1. Overview * ----------- - * umem is very close to kmem in implementation. There are four major + * umem is very close to kmem in implementation. There are seven major * areas of divergence: * * * Initialization @@ -57,6 +59,10 @@ * * * lock ordering * + * * changing UMEM_MAXBUF + * + * * Per-thread caching for malloc/free + * * 2. Initialization * ----------------- * kmem is initialized early on in boot, and knows that no one will call @@ -355,6 +361,248 @@ * umem_log_header_t's: * lh_cpu[*].clh_lock * lh_lock + * + * 7. Changing UMEM_MAXBUF + * ----------------------- + * + * When changing UMEM_MAXBUF extra care has to be taken. It is not sufficient to + * simply increase this number. First, one must update the umem_alloc_table to + * have the appropriate number of entires based upon the new size. If this is + * not done, this will lead to libumem blowing an assertion. + * + * The second place to update, which is not required, is the umem_alloc_sizes. + * These determine the default cache sizes that we're going to support. + * + * 8. Per-thread caching for malloc/free + * ------------------------------------- + * + * "Time is an illusion. Lunchtime doubly so." -- Douglas Adams + * + * Time may be an illusion, but CPU cycles aren't. While libumem is designed + * to be a highly scalable allocator, that scalability comes with a fixed cycle + * penalty even in the absence of contention: libumem must acquire (and release + * a per-CPU lock for each allocation. When contention is low and malloc(3C) + * frequency is high, this overhead can dominate execution time. To alleviate + * this, we allow for per-thread caching, a lock-free means of caching recent + * deallocations on a per-thread basis for use in satisfying subsequent calls + * + * In addition to improving performance, we also want to: + * * Minimize fragmentation + * * Not add additional memory overhead (no larger malloc tags) + * + * In the ulwp_t of each thread there is a private data structure called a + * umem_t that looks like: + * + * typedef struct { + * size_t tm_size; + * void *tm_roots[NTMEMBASE]; (Currently 16) + * } tmem_t; + * + * Each of the roots is treated as the head of a linked list. Each entry in the + * list can be thought of as a void ** which points to the next entry, until one + * of them points to NULL. If the head points to NULL, the list is empty. + * + * Each head corresponds to a umem_cache. Currently there is a linear mapping + * where the first root corresponds to the first cache, second root to the + * second cache, etc. This works because every allocation that malloc makes to + * umem_alloc that can be satisified by a umem_cache will actually return a + * number of bytes equal to the size of that cache. Because of this property and + * a one to one mapping between caches and roots we can guarantee that every + * entry in a given root's list will be able to satisfy the same requests as the + * corresponding cache. + * + * The maximum amount of memory that can be cached in each thread is determined + * by the perthread_cache UMEM_OPTION. It corresponds to the umem_ptc_size + * value. The default value for this is currently 1 MB. Once umem_init() has + * finished this cannot be directly tuned without directly modifying the + * instruction text. If, upon calling free(3C), the amount cached would exceed + * this maximum, we instead actually return the buffer to the umem_cache instead + * of holding onto it in the thread. + * + * When a thread calls malloc(3C) it first determines which umem_cache it + * would be serviced by. If the allocation is not covered by ptcumem it goes to + * the normal malloc instead. Next, it checks if the tmem_root's list is empty + * or not. If it is empty, we instead go and allocate the memory from + * umem_alloc. If it is not empty, we remove the head of the list, set the + * appropriate malloc tags, and return that buffer. + * + * When a thread calls free(3C) it first looks at the malloc tag and if it is + * invalid or the allocation exceeds the largest cache in ptcumem and sends it + * off to the original free() to handle and clean up appropriately. Next, it + * checks if the allocation size is covered by one of the per-thread roots and + * if it isn't, it passes it off to the original free() to be released. Finally, + * before it inserts this buffer as the head, it checks if adding this buffer + * would put the thread over its maximum cache size. If it would, it frees the + * buffer back to the umem_cache. Otherwise it increments the threads total + * cached amount and makes the buffer the new head of the appropriate tm_root. + * + * When a thread exits, all of the buffers that it has in its per-thread cache + * will be passed to umem_free() and returned to the appropriate umem_cache. + * + * 8.1 Handling addition and removal of umem_caches + * ------------------------------------------------ + * + * The set of umem_caches that are used to back calls to umem_alloc() and + * ultimately malloc() are determined at program execution time. The default set + * of caches is defined below in umem_alloc_sizes[]. Various umem_options exist + * that modify the set of caches: size_add, size_clear, and size_remove. Because + * the set of caches can only be determined once umem_init() has been called and + * we have the additional goals of minimizing additional fragmentation and + * metadata space overhead in the malloc tags, this forces our hand to go down a + * slightly different path: the one tread by fasttrap and trapstat. + * + * During umem_init we're going to dynamically construct a new version of + * malloc(3C) and free(3C) that utilizes the known cache sizes and then ensure + * that ptcmalloc and ptcfree replace malloc and free as entries in the plt. If + * ptcmalloc and ptcfree cannot handle a request, they simply jump to the + * original libumem implementations. + * + * After creating all of the umem_caches, but before making them visible, + * umem_cache_init checks that umem_genasm_supported is non-zero. This value is + * set by each architecture in $ARCH/umem_genasm.c to indicate whether or not + * they support this. If the value is zero, then this process is skipped. + * Similarly, if the cache size has been tuned to zero by UMEM_OPTIONS, then + * this is also skipped. + * + * In umem_genasm.c, each architecture's implementation implements a single + * function called umem_genasm() that is responsible for generating the + * appropriate versions of ptcmalloc() and ptcfree(), placing them in the + * appropriate memory location, and finally doing the switch from malloc() and + * free() to ptcmalloc() and ptcfree(). Once the change has been made, there is + * no way to switch back, short of restarting the program or modifying program + * text with mdb. + * + * 8.2 Modifying the Procedure Linkage Table (PLT) + * ----------------------------------------------- + * + * The last piece of this puzzle is how we actually jam ptcmalloc() into the + * PLT. The dyanmic linker has support for global and local audit libraries. + * For the full explanation of audit libraries consult the Linkers and Libraries + * guide or the linker source. A local auditer can attach to a single library + * and interpose on all of the relocations that come in from and leave to that + * same library. To facilitate our work, we have created a local audit library + * for libumem that is called libumem_trampoline and is located in + * lib/libumem_trampoline/. + * + * When any resolution is done to malloc(), the audit library allows us to + * replace the address with an address that it specifies. There are two 4k + * sections in the libumem_trampoline's bss which we use as the stomping grounds + * for ptcmalloc and ptcfree. When the audit library audits the malloc and free + * functions from libumem, it encodes their address and sets its buffers to + * contain a simple trampoline which consists of a jmp instruction and a four + * byte offset to the original malloc and free. libumem_trampoline's mapfile + * explicitly makes its bss rwx instead of rw to support this. + * + * When umem_genasm() is called, it uses a similar mechanism to get the address + * and size of the trampoline libraries malloc (mbuf) and free (fbuf) buffers. + * After validating that the size will be able to contain all of the + * instructions, it starts laying out ptcmalloc and ptcfree at mbuf[4] and + * fbuf[4]. Once both have been successfully generated, umem_genasm() stores a + * single five byte nop over the original jump. + * + * 8.3 umem_genasm() + * ----------------- + * + * umem_genasm() is currently implemented for i386 and amd64. This section + * describes the theory behind the construction. For specific byte code to + * assembly instructions and niceish C and asm versions of ptcmalloc and + * ptcfree, see the individual umem_genasm.c files. The layout consists of the + * following sections: + * + * o. function-specfic prologue + * o. function-generic cache-selecting elements + * o. function-specific epilogue + * + * There are three different generic cache elements that exist: + * + * o. the last or only cache + * o. the intermediary caches if more than two + * o. the first one if more than one cache + * + * The malloc and free prologues and epilogues mimic the necessary portions of + * libumem's malloc and free. This includes things like checking for size + * overflow, setting and verifying the malloc tags. + * + * It is an important constraint that these functions do not make use of the + * call instruction. The only jmp outside of the individual functions is to the + * original libumem malloc and free respectively. Because doing things like + * setting errno or raising an internal umem error on improper malloc tags would + * require using calls into the PLT, whenever we encounter one of those cases we + * just jump to the original malloc and free functions reusing the same stack + * frame. + * + * Each of the above sections, the three caches, and the malloc and free + * prologue and epilogue are implemented as blocks of machine code with the + * corresponding assembly in comments. There are known offsets into each block + * that corresponds to locations of data and addresses that we only know at run + * time. These blocks are copied as necessary and the blanks filled in + * appropriately. + * + * As mentioned in section 8.2, the trampoline library uses specifically named + * variables to communicate the buffers and size to use. These variables are: + * + * o. umem_genasm_mptr: The buffer for ptcmalloc + * o. umem_genasm_msize: The size in bytes of the above buffer + * o. umem_genasm_fptr: The buffer for ptcfree + * o. umem_genasm_fsize: The size in bytes of the above buffer + * + * Finally, to enable the generated assembly we need to remove the previous jump + * to the actual malloc that exists at the start of these buffers. This is a + * five byte region. We could zero out the jump offset to be a jmp +0, but + * using nops can be faster. We specifically use a single five byte nop which is + * faster. The opcode for the five byte nop is 0x 0f 1f 44 00 00. On x86, + * remember integers are little endian, so it will be written the other way + * around. + * + * 8.4 Interface with libc.so + * -------------------------- + * + * The tmem_t structure as described in the beginning of section 8, is part of a + * private interface with libc. There are three functions that exist to cover + * this. They are not documented in man pages or header files. They are in the + * SUNWprivate part of libc's makefile. + * + * o. _tmem_get_base(void) + * + * Returns the offset from the ulwp_t (curthread) to the tmem_t structure. + * This is a constant for all threads and is effectively a way to to do + * ::offsetof ulwp_t ul_tmem without having to know the specifics of the + * structure outside of libc. + * + * o. _tmem_get_nentries(void) + * + * Returns the number of roots that exist in the tmem_t. This is one part + * of the cap on the number of umem_caches that we can back with tmem. + * + * o. _tmem_set_cleanup(void (*)(void *, int)) + * + * This sets a clean up handler that gets called back when a thread exits. + * There is one call per buffer, the void * is a pointer to the buffer on + * the list, the int is the index into the roots array for this buffer. + * + * 8.5 Tuning and disabling per-thread caching + * ------------------------------------------- + * + * There is only one tunable for per-thread caching: the amount of memory each + * thread should be able to cache. This is specified via the perthread_cache + * UMEM_OPTION option. No attempt is made to to sanity check the specified + * value; the limit is simply the maximum value of a size_t. + * + * If the perthread_cache UMEM_OPTION is set to zero, nomagazines was requested, + * or UMEM_DEBUG has been turned on then we will never call into umem_genasm; + * however, the trampoline audit library and jump will still be in place. + * + * 8.6 Observing efficacy of per-thread caching + * -------------------------------------------- + * + * To understand the efficacy of per-thread caching, use the ::umastat dcmd + * to see the percentage of capacity consumed on a per-thread basis, the + * degree to which each umem cache contributes to per-thread cache consumption, + * and the number of buffers in per-thread caches on a per-umem cache basis. + * If more detail is required, the specific buffers in a per-thread cache can + * be iterated over with the umem_ptc_* walkers. (These walkers allow an + * optional ulwp_t to be specified to iterate only over a particular thread's + * cache.) */ #include <umem_impl.h> @@ -420,7 +668,9 @@ static int umem_alloc_sizes[] = { P2ALIGN(8192 / 2, 64), 4544, P2ALIGN(8192 / 1, 64), 9216, 4096 * 3, - UMEM_MAXBUF, /* = 8192 * 2 */ + 8192 * 2, /* = 8192 * 2 */ + 24576, 32768, 40960, 49152, 57344, 65536, 73728, 81920, + 90112, 98304, 106496, 114688, 122880, UMEM_MAXBUF, /* 128k */ /* 24 slots for user expansion */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -461,8 +711,10 @@ size_t umem_lite_minsize = 0; /* minimum buffer size for UMF_LITE */ size_t umem_lite_maxalign = 1024; /* maximum buffer alignment for UMF_LITE */ size_t umem_maxverify; /* maximum bytes to inspect in debug routines */ size_t umem_minfirewall; /* hardware-enforced redzone threshold */ +size_t umem_ptc_size = 1048576; /* size of per-thread cache (in bytes) */ uint_t umem_flags = 0; +uintptr_t umem_tmem_off; mutex_t umem_init_lock; /* locks initialization */ cond_t umem_init_cv; /* initialization CV */ @@ -470,6 +722,8 @@ thread_t umem_init_thr; /* thread initializing */ int umem_init_env_ready; /* environ pre-initted */ int umem_ready = UMEM_READY_STARTUP; +int umem_ptc_enabled; /* per-thread caching enabled */ + static umem_nofail_callback_t *nofail_callback; static mutex_t umem_nofail_exit_lock; static thread_t umem_nofail_exit_thr; @@ -592,6 +846,20 @@ umem_cache_t umem_null_cache = { static umem_cache_t *umem_alloc_table[UMEM_MAXBUF >> UMEM_ALIGN_SHIFT] = { ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, + ALLOC_TABLE_1024, ALLOC_TABLE_1024 }; @@ -2812,6 +3080,24 @@ umem_alloc_sizes_remove(size_t size) umem_alloc_sizes[i] = 0; } +/* + * We've been called back from libc to indicate that thread is terminating and + * that it needs to release the per-thread memory that it has. We get to know + * which entry in the thread's tmem array the allocation came from. Currently + * this refers to first n umem_caches which makes this a pretty simple indexing + * job. + */ +static void +umem_cache_tmem_cleanup(void *buf, int entry) +{ + size_t size; + umem_cache_t *cp; + + size = umem_alloc_sizes[entry]; + cp = umem_alloc_table[(size - 1) >> UMEM_ALIGN_SHIFT]; + _umem_cache_free(cp, buf); +} + static int umem_cache_init(void) { @@ -2927,6 +3213,16 @@ umem_cache_init(void) umem_alloc_caches[i] = cp; } + umem_tmem_off = _tmem_get_base(); + _tmem_set_cleanup(umem_cache_tmem_cleanup); + + if (umem_genasm_supported && !(umem_flags & UMF_DEBUG) && + !(umem_flags & UMF_NOMAGAZINE) && + umem_ptc_size > 0) { + umem_ptc_enabled = umem_genasm(umem_alloc_sizes, + umem_alloc_caches, i) == 0 ? 1 : 0; + } + /* * Initialization cannot fail at this point. Make the caches * visible to umem_alloc() and friends. diff --git a/usr/src/lib/libumem/common/umem_base.h b/usr/src/lib/libumem/common/umem_base.h index e78bebfb58..26e00bc282 100644 --- a/usr/src/lib/libumem/common/umem_base.h +++ b/usr/src/lib/libumem/common/umem_base.h @@ -22,12 +22,13 @@ * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ #ifndef _UMEM_BASE_H #define _UMEM_BASE_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <umem_impl.h> #ifdef __cplusplus @@ -75,6 +76,8 @@ extern volatile uint32_t umem_reaping; #define UMEM_REAP_ADDING 0x00000001 /* umem_reap() is active */ #define UMEM_REAP_ACTIVE 0x00000002 /* update thread is reaping */ +extern uintptr_t umem_tmem_off; + /* * umem.c: tunables */ @@ -97,6 +100,7 @@ extern size_t umem_lite_minsize; extern size_t umem_lite_maxalign; extern size_t umem_maxverify; extern size_t umem_minfirewall; +extern size_t umem_ptc_size; extern uint32_t umem_flags; @@ -139,6 +143,12 @@ extern int umem_create_update_thread(void); void umem_setup_envvars(int); void umem_process_envvars(void); +/* + * umem_genasm.c: private interfaces + */ +extern int umem_genasm_supported; +extern int umem_genasm(int *, umem_cache_t **, int); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libumem/common/umem_impl.h b/usr/src/lib/libumem/common/umem_impl.h index c6481d9751..f63246e166 100644 --- a/usr/src/lib/libumem/common/umem_impl.h +++ b/usr/src/lib/libumem/common/umem_impl.h @@ -24,11 +24,13 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + #ifndef _UMEM_IMPL_H #define _UMEM_IMPL_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <umem.h> #include <sys/sysmacros.h> @@ -64,6 +66,7 @@ extern "C" { #define UMF_HASH 0x00000200 /* cache has hash table */ #define UMF_RANDOMIZE 0x00000400 /* randomize other umem_flags */ +#define UMF_PTC 0x00000800 /* cache has per-thread caching */ #define UMF_BUFTAG (UMF_DEADBEEF | UMF_REDZONE) #define UMF_TOUCH (UMF_BUFTAG | UMF_LITE | UMF_CONTENTS) @@ -353,7 +356,7 @@ typedef struct umem_cpu { uint32_t cpu_number; } umem_cpu_t; -#define UMEM_MAXBUF 16384 +#define UMEM_MAXBUF 131072 #define UMEM_ALIGN 8 /* min guaranteed alignment */ #define UMEM_ALIGN_SHIFT 3 /* log2(UMEM_ALIGN) */ @@ -396,6 +399,13 @@ extern void umem_startup(caddr_t, size_t, size_t, caddr_t, caddr_t); extern int umem_add(caddr_t, size_t); #endif +/* + * Private interface with libc for tcumem. + */ +extern uintptr_t _tmem_get_base(void); +extern int _tmem_get_nentries(void); +extern void _tmem_set_cleanup(void(*)(void *, int)); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/libumem/i386/umem_genasm.c b/usr/src/lib/libumem/i386/umem_genasm.c new file mode 100644 index 0000000000..0bfa338e2b --- /dev/null +++ b/usr/src/lib/libumem/i386/umem_genasm.c @@ -0,0 +1,603 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + +/* + * Don't Panic! If you find the blocks of assembly that follow confusing and + * you're questioning why they exist, please go read section 8 of the umem.c big + * theory statement. Next familiarize yourself with the malloc and free + * implementations in libumem's malloc.c. + * + * What follows is the i386 implementation of the thread caching automatic + * assembly generation. With i386 a function only has three registers its + * allowed to change without restoring them: eax, ecx, and edx. All others have + * to be preserved. Since the set of registers we have available is so small, we + * have to make use of esi, ebx, and edi and save their original values to the + * stack. + * + * Malloc register usage: + * o. esi: Size of the malloc (passed into us and modified) + * o. edi: Size of the cache + * o. eax: Buffer to return + * o. ebx: Scratch space and temporary values + * o. ecx: Pointer to the tmem_t in the ulwp_t. + * o. edx: Pointer to the tmem_t array of roots + * + * Free register usage: + * o. esi: Size of the malloc (passed into us and modified) + * o. edi: Size of the cache + * o. eax: Buffer to free + * o. ebx: Scratch space and temporary values + * o. ecx: Pointer to the tmem_t in the ulwp_t. + * o. edx: Pointer to the tmem_t array of roots + * + * Once we determine what cache we are using, we increment %edx to the + * appropriate offset and set %edi with the size of the cache. This means that + * when we break out to the normal buffer allocation point %edx contains the + * head of the linked list and %edi is the amount that we have to adjust the + * total amount cached by the thread. + * + * Each block of assembly has psuedocode that describes its purpose. + */ + +#include <inttypes.h> +#include <strings.h> +#include <umem_impl.h> +#include "umem_base.h" + +#include <atomic.h> + +int umem_genasm_supported = 1; +uintptr_t umem_genasm_mptr; +size_t umem_genasm_msize; +uintptr_t umem_genasm_fptr; +size_t umem_genasm_fsize; +static uintptr_t umem_genasm_omptr; +static uintptr_t umem_genasm_ofptr; + +/* + * The maximum number of caches we can support. We use a single byte addl so + * this is 255 (UINT8_MAX) / sizeof (uintptr_t). In this case 63 + */ +#define UMEM_GENASM_MAX32 63 + +#define PTC_JMPADDR(dest, src) (dest - (src + 4)) +#define PTC_ROOT_SIZE sizeof (uintptr_t) +#define MULTINOP 0x0000441f0f + +/* + * void *ptcmalloc(size_t orig_size); + * + * size_t size = orig_size + 8; + * + * if (size < orig_size) + * goto tomalloc; ! This is overflow + * + * if (size > cache_size) + * goto tomalloc; + * + * tmem_t *t = (uintptr_t)curthread() + umem_thr_offset; + * void **roots = t->tm_roots; + */ +#define PTC_MALINIT_JOUT 0x0e +#define PTC_MALINIT_MCS 0x14 +#define PTC_MALINIT_JOV 0x1a +#define PTC_MALINIT_SOFF 0x27 +static const uint8_t malinit[] = { + 0x55, /* pushl %ebp */ + 0x89, 0xe5, /* movl %esp, %ebp */ + 0x57, /* pushl %edi */ + 0x56, /* pushl %esi */ + 0x53, /* pushl %ebx */ + 0x8b, 0x75, 0x08, /* movl 0x8(%ebp), %esi */ + 0x83, 0xc6, 0x08, /* addl $0x8,%esi */ + 0x0f, 0x82, 0x00, 0x00, 0x00, 0x00, /* jc +$JMP (errout) */ + 0x81, 0xfe, 0x00, 0x00, 0x00, 0x00, /* cmpl sizeof ($C0), %esi */ + 0x0f, 0x87, 0x00, 0x00, 0x00, 0x00, /* ja +$JMP (errout) */ + 0x65, 0x8b, 0x0d, 0x00, 0x0, 0x00, 0x00, /* movl %gs:0x0,%ecx */ + 0x81, 0xc1, 0x00, 0x00, 0x00, 0x00, /* addl $OFF, %ecx */ + 0x8d, 0x51, 0x04 /* leal 0x4(%ecx), %edx */ +}; + +/* + * void ptcfree(void *buf); + * + * if (buf == NULL) + * return; + * + * malloc_data_t *tag = buf; + * tag--; + * int size = tag->malloc_size; + * int tagtval = UMEM_MALLOC_DECODE(tag->malloc_tag, size); + * + * if (tagval != MALLOC_MAGIC) + * goto tofree; + * + * if (size > cache_max) + * goto tofree; + * + * tmem_t *t = (uintptr_t)curthread() + umem_thr_offset; + * void **roots = t->tm_roots; + */ +#define PTC_FRINI_JDONE 0x0d +#define PTC_FRINI_JFREE 0x23 +#define PTC_FRINI_MCS 0x29 +#define PTC_FRINI_JOV 0x2f +#define PTC_FRINI_SOFF 0x3c +static const uint8_t freeinit[] = { + 0x55, /* pushl %ebp */ + 0x89, 0xe5, /* movl %esp, %ebp */ + 0x57, /* pushl %edi */ + 0x56, /* pushl %esi */ + 0x53, /* pushl %ebx */ + 0x8b, 0x45, 0x08, /* movl 0x8(%ebp), %eax */ + 0x85, 0xc0, /* testl %eax, %eax */ + 0x0f, 0x84, 0x00, 0x00, 0x00, 0x00, /* je $JDONE (done) */ + 0x83, 0xe8, 0x08, /* subl $0x8,%eax */ + 0x8b, 0x30, /* movl (%eax),%esi */ + 0x8b, 0x50, 0x04, /* movl 0x4(%eax),%edx */ + 0x01, 0xf2, /* addl %esi,%edx */ + 0x81, 0xfa, 0x00, 0xc0, 0x10, 0x3a, /* cmpl MAGIC32, %edx */ + 0x0f, 0x85, 0x00, 0x00, 0x00, 0x00, /* jne +JFREE (goto freebuf) */ + + 0x81, 0xfe, 0x00, 0x00, 0x00, 0x00, /* cmpl sizeof ($C0), %esi */ + 0x0f, 0x87, 0x00, 0x00, 0x00, 0x00, /* ja +$JMP (errout) */ + 0x65, 0x8b, 0x0d, 0x00, 0x0, 0x00, 0x00, /* movl %gs:0x0,%ecx */ + 0x81, 0xc1, 0x00, 0x00, 0x00, 0x00, /* addl $0xOFF, %ecx */ + 0x8d, 0x51, 0x04 /* leal 0x4(%ecx),%edx */ +}; + +/* + * if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * } else ... ! goto next cache + */ +#define PTC_INICACHE_CMP 0x02 +#define PTC_INICACHE_SIZE 0x09 +#define PTC_INICACHE_JMP 0x0e +static const uint8_t inicache[] = { + 0x81, 0xfe, 0xff, 0x00, 0x00, 0x00, /* cmpl sizeof ($C0), %esi */ + 0x77, 0x0a, /* ja +0xa */ + 0xbf, 0xff, 0x00, 0x00, 0x00, /* movl sizeof ($C0), %edi */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp +$JMP (allocbuf) */ +}; + +/* + * if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * roots += $CACHE_NUM; + * } else ... ! goto next cache + */ +#define PTC_GENCACHE_CMP 0x02 +#define PTC_GENCACHE_NUM 0x0a +#define PTC_GENCACHE_SIZE 0x0c +#define PTC_GENCACHE_JMP 0x11 +static const uint8_t gencache[] = { + 0x81, 0xfe, 0x00, 0x00, 0x00, 0x00, /* cmpl sizeof ($CACHE), %esi */ + 0x77, 0x0d, /* ja +0xd (next cache) */ + 0x83, 0xc2, 0x00, /* addl $4*$ii, %edx */ + 0xbf, 0x00, 0x00, 0x00, 0x00, /* movl sizeof ($CACHE), %edi */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp +$JMP (allocbuf) */ +}; + +/* + * else if (size <= $CACHE_SIZE) { + * csize = $CACHE_SIZE; + * roots += $CACHE_NUM; + * } else { + * goto tofunc; ! goto tomalloc if ptcmalloc. + * } ! goto tofree if ptcfree. + */ +#define PTC_FINCACHE_CMP 0x02 +#define PTC_FINCACHE_JMP 0x07 +#define PTC_FINCACHE_NUM 0x0a +#define PTC_FINCACHE_SIZE 0x0c +static const uint8_t fincache[] = { + 0x81, 0xfe, 0xff, 0x00, 0x00, 0x00, /* cmpl sizeof ($CLAST), %esi */ + 0x77, 0x00, /* ja +$JMP (to errout) */ + 0x83, 0xc2, 0x00, /* addl $4*($NCACHES-1), %edx */ + 0xbf, 0x00, 0x00, 0x00, 0x00, /* movl sizeof ($CLAST), %edi */ +}; + +/* + * if (*root == NULL) + * goto tomalloc; + * + * malloc_data_t *ret = *root; + * *root = *(void **)ret; + * t->tm_size += csize; + * ret->malloc_size = size; + * + * ret->malloc_data = UMEM_MALLOC_ENCODE(MALLOC_SECOND_MAGIC, size); + * ret++; + * + * return ((void *)ret); + * tomalloc: + * return (malloc(orig_size)); + */ +#define PTC_MALFINI_ALLABEL 0x00 +#define PTC_MALFINI_JMLABEL 0x20 +#define PTC_MALFINI_JMADDR 0x25 +static const uint8_t malfini[] = { + /* allocbuf: */ + 0x8b, 0x02, /* movl (%edx), %eax */ + 0x85, 0xc0, /* testl %eax, %eax */ + 0x74, 0x1a, /* je +0x1a (errout) */ + 0x8b, 0x18, /* movl (%eax), %esi */ + 0x89, 0x1a, /* movl %esi, (%edx) */ + 0x29, 0x39, /* subl %edi, (%ecx) */ + 0x89, 0x30, /* movl %esi, ($eax) */ + 0xba, 0x00, 0xc0, 0x10, 0x3a, /* movl $0x3a10c000,%edx */ + 0x29, 0xf2, /* subl %esi, %edx */ + 0x89, 0x50, 0x04, /* movl %edx, 0x4(%eax) */ + 0x83, 0xc0, 0x08, /* addl %0x8, %eax */ + 0x5b, /* popl %ebx */ + 0x5e, /* popl %esi */ + 0x5f, /* popl %edi */ + 0xc9, /* leave */ + 0xc3, /* ret */ + /* errout: */ + 0x5b, /* popl %ebx */ + 0x5e, /* popl %esi */ + 0x5f, /* popl %edi */ + 0xc9, /* leave */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp $malloc */ +}; + +/* + * if (t->tm_size + csize > umem_ptc_size) + * goto tofree; + * + * t->tm_size += csize + * *(void **)tag = *root; + * *root = tag; + * return; + * tofree: + * free(buf); + * return; + */ +#define PTC_FRFINI_RBUFLABEL 0x00 +#define PTC_FRFINI_CACHEMAX 0x06 +#define PTC_FRFINI_DONELABEL 0x14 +#define PTC_FRFINI_JFLABEL 0x19 +#define PTC_FRFINI_JFADDR 0x1e +static const uint8_t freefini[] = { + /* freebuf: */ + 0x8b, 0x19, /* movl (%ecx),%ebx */ + 0x01, 0xfb, /* addl %edi,%ebx */ + 0x81, 0xfb, 0x00, 0x00, 0x00, 0x00, /* cmpl maxsize, %ebx */ + 0x73, 0x0d, /* jae +0xd <tofree> */ + 0x01, 0x39, /* addl %edi,(%ecx) */ + 0x8b, 0x3a, /* movl (%edx),%edi */ + 0x89, 0x38, /* movl %edi,(%eax) */ + 0x89, 0x02, /* movl %eax,(%edx) */ + /* done: */ + 0x5b, /* popl %ebx */ + 0x5e, /* popl %esi */ + 0x5f, /* popl %edi */ + 0xc9, /* leave */ + 0xc3, /* ret */ + /* realfree: */ + 0x5b, /* popl %ebx */ + 0x5e, /* popl %esi */ + 0x5f, /* popl %edi */ + 0xc9, /* leave */ + 0xe9, 0x00, 0x00, 0x00, 0x00 /* jmp free */ +}; + +/* + * Construct the initial part of malloc. off contains the offset from curthread + * to the root of the tmem structure. ep is the address of the label to error + * and jump to free. csize is the size of the largest umem_cache in ptcumem. + */ +static int +genasm_malinit(uint8_t *bp, uint32_t off, uint32_t ep, uint32_t csize) +{ + uint32_t addr; + + bcopy(malinit, bp, sizeof (malinit)); + addr = PTC_JMPADDR(ep, PTC_MALINIT_JOUT); + bcopy(&addr, bp + PTC_MALINIT_JOUT, sizeof (addr)); + bcopy(&csize, bp + PTC_MALINIT_MCS, sizeof (csize)); + addr = PTC_JMPADDR(ep, PTC_MALINIT_JOV); + bcopy(&addr, bp + PTC_MALINIT_JOV, sizeof (addr)); + bcopy(&off, bp + PTC_MALINIT_SOFF, sizeof (off)); + + return (sizeof (malinit)); +} + +static int +genasm_frinit(uint8_t *bp, uint32_t off, uint32_t dp, uint32_t ep, uint32_t mc) +{ + uint32_t addr; + + bcopy(freeinit, bp, sizeof (freeinit)); + addr = PTC_JMPADDR(dp, PTC_FRINI_JDONE); + bcopy(&addr, bp + PTC_FRINI_JDONE, sizeof (addr)); + addr = PTC_JMPADDR(ep, PTC_FRINI_JFREE); + bcopy(&addr, bp + PTC_FRINI_JFREE, sizeof (addr)); + bcopy(&mc, bp + PTC_FRINI_MCS, sizeof (mc)); + addr = PTC_JMPADDR(ep, PTC_FRINI_JOV); + bcopy(&addr, bp + PTC_FRINI_JOV, sizeof (addr)); + bcopy(&off, bp + PTC_FRINI_SOFF, sizeof (off)); + return (sizeof (freeinit)); +} + +/* + * Create the initial cache entry of the specified size. The value of ap tells + * us what the address of the label to try and allocate a buffer. This value is + * an offset from the current base to that value. + */ +static int +genasm_firstcache(uint8_t *bp, uint32_t csize, uint32_t ap) +{ + uint32_t addr; + + bcopy(inicache, bp, sizeof (inicache)); + bcopy(&csize, bp + PTC_INICACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_INICACHE_SIZE, sizeof (csize)); + addr = PTC_JMPADDR(ap, PTC_INICACHE_JMP); + ASSERT(addr != 0); + bcopy(&addr, bp + PTC_INICACHE_JMP, sizeof (addr)); + + return (sizeof (inicache)); +} + +static int +genasm_gencache(uint8_t *bp, int num, uint32_t csize, uint32_t ap) +{ + uint32_t addr; + uint8_t coff; + + ASSERT(256 / PTC_ROOT_SIZE > num); + ASSERT(num != 0); + bcopy(gencache, bp, sizeof (gencache)); + bcopy(&csize, bp + PTC_GENCACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_GENCACHE_SIZE, sizeof (csize)); + coff = num * PTC_ROOT_SIZE; + bcopy(&coff, bp + PTC_GENCACHE_NUM, sizeof (coff)); + addr = PTC_JMPADDR(ap, PTC_GENCACHE_JMP); + bcopy(&addr, bp + PTC_GENCACHE_JMP, sizeof (addr)); + + return (sizeof (gencache)); +} + +static int +genasm_lastcache(uint8_t *bp, int num, uint32_t csize, uint32_t ep) +{ + uint8_t addr; + + ASSERT(ep <= 0xff && ep > 7); + ASSERT(256 / PTC_ROOT_SIZE > num); + bcopy(fincache, bp, sizeof (fincache)); + bcopy(&csize, bp + PTC_FINCACHE_CMP, sizeof (csize)); + bcopy(&csize, bp + PTC_FINCACHE_SIZE, sizeof (csize)); + addr = num * PTC_ROOT_SIZE; + bcopy(&addr, bp + PTC_FINCACHE_NUM, sizeof (addr)); + addr = ep - PTC_FINCACHE_JMP - 1; + bcopy(&addr, bp + PTC_FINCACHE_JMP, sizeof (addr)); + + return (sizeof (fincache)); +} + +static int +genasm_malfini(uint8_t *bp, uintptr_t mptr) +{ + uint32_t addr; + + bcopy(malfini, bp, sizeof (malfini)); + addr = PTC_JMPADDR(mptr, ((uintptr_t)bp + PTC_MALFINI_JMADDR)); + bcopy(&addr, bp + PTC_MALFINI_JMADDR, sizeof (addr)); + + return (sizeof (malfini)); +} + +static int +genasm_frfini(uint8_t *bp, uint32_t maxthr, uintptr_t fptr) +{ + uint32_t addr; + + bcopy(freefini, bp, sizeof (freefini)); + bcopy(&maxthr, bp + PTC_FRFINI_CACHEMAX, sizeof (maxthr)); + addr = PTC_JMPADDR(fptr, ((uintptr_t)bp + PTC_FRFINI_JFADDR)); + bcopy(&addr, bp + PTC_FRFINI_JFADDR, sizeof (addr)); + + return (sizeof (freefini)); +} + +/* + * The malloc inline assembly is constructed as follows: + * + * o Malloc prologue assembly + * o Generic first-cache check + * o n Generic cache checks (where n = _tmem_get_entries() - 2) + * o Generic last-cache check + * o Malloc epilogue assembly + * + * Generally there are at least three caches. When there is only one cache we + * only use the generic last-cache. In the case where there are two caches, we + * just leave out the middle ones. + */ +static int +genasm_malloc(void *base, size_t len, int nents, int *umem_alloc_sizes) +{ + int ii, off; + uint8_t *bp; + size_t total; + uint32_t allocoff, erroff; + + total = sizeof (malinit) + sizeof (malfini) + sizeof (fincache); + + if (nents >= 2) + total += sizeof (inicache) + sizeof (gencache) * (nents - 2); + + if (total > len) + return (1); + + erroff = total - sizeof (malfini) + PTC_MALFINI_JMLABEL; + allocoff = total - sizeof (malfini) + PTC_MALFINI_ALLABEL; + + bp = base; + + off = genasm_malinit(bp, umem_tmem_off, erroff, + umem_alloc_sizes[nents-1]); + bp += off; + allocoff -= off; + erroff -= off; + + if (nents > 1) { + off = genasm_firstcache(bp, umem_alloc_sizes[0], allocoff); + bp += off; + allocoff -= off; + erroff -= off; + } + + for (ii = 1; ii < nents - 1; ii++) { + off = genasm_gencache(bp, ii, umem_alloc_sizes[ii], allocoff); + bp += off; + allocoff -= off; + erroff -= off; + } + + bp += genasm_lastcache(bp, nents - 1, umem_alloc_sizes[nents - 1], + erroff); + bp += genasm_malfini(bp, umem_genasm_omptr); + ASSERT(((uintptr_t)bp - total) == (uintptr_t)base); + + return (0); +} + +static int +genasm_free(void *base, size_t len, int nents, int *umem_alloc_sizes) +{ + uint8_t *bp; + int ii, off; + size_t total; + uint32_t rbufoff, retoff, erroff; + + /* Assume that nents has already been audited for us */ + total = sizeof (freeinit) + sizeof (freefini) + sizeof (fincache); + if (nents >= 2) + total += sizeof (inicache) + sizeof (gencache) * (nents - 2); + + if (total > len) + return (1); + + erroff = total - (sizeof (freefini) - PTC_FRFINI_JFLABEL); + rbufoff = total - (sizeof (freefini) - PTC_FRFINI_RBUFLABEL); + retoff = total - (sizeof (freefini) - PTC_FRFINI_DONELABEL); + + bp = base; + + off = genasm_frinit(bp, umem_tmem_off, retoff, erroff, + umem_alloc_sizes[nents - 1]); + bp += off; + erroff -= off; + rbufoff -= off; + + if (nents > 1) { + off = genasm_firstcache(bp, umem_alloc_sizes[0], rbufoff); + bp += off; + erroff -= off; + rbufoff -= off; + } + + for (ii = 1; ii < nents - 1; ii++) { + off = genasm_gencache(bp, ii, umem_alloc_sizes[ii], rbufoff); + bp += off; + rbufoff -= off; + erroff -= off; + } + + bp += genasm_lastcache(bp, nents - 1, umem_alloc_sizes[nents - 1], + erroff); + bp += genasm_frfini(bp, umem_ptc_size, umem_genasm_ofptr); + ASSERT(((uintptr_t)bp - total) == (uintptr_t)base); + + return (0); +} + +int +umem_genasm(int *alloc_sizes, umem_cache_t **caches, int ncaches) +{ + int nents, i; + uint8_t *mptr; + uint8_t *fptr; + uint32_t *ptr; + uint64_t v, *vptr; + + mptr = (void *)((uintptr_t)&umem_genasm_mptr + 5); + fptr = (void *)((uintptr_t)&umem_genasm_fptr + 5); + if (umem_genasm_mptr == 0 || umem_genasm_msize == 0 || + umem_genasm_fptr == 0 || umem_genasm_fsize == 0) + return (1); + + /* + * The total number of caches that we can service is the minimum of: + * o the amount supported by libc + * o the total number of umem caches + * o we use a single byte addl, so its 255 / sizeof (uintptr_t). For + * 32-bit, this is 63. + */ + nents = _tmem_get_nentries(); + + if (UMEM_GENASM_MAX32 < nents) + nents = UMEM_GENASM_MAX32; + + if (ncaches < nents) + nents = ncaches; + + /* Based on our constraints, this is not an error */ + if (nents == 0 || umem_ptc_size == 0) + return (0); + + /* Grab the original malloc and free locations */ + ptr = (void *)(mptr - 4); + umem_genasm_omptr = *ptr + (uintptr_t)mptr; + ptr = (void *)(fptr - 4); + umem_genasm_ofptr = *ptr + (uintptr_t)fptr; + + /* Take into account the jump */ + if (genasm_malloc(mptr, umem_genasm_fsize - 5, nents, + alloc_sizes) != 0) + return (1); + + if (genasm_free(fptr, umem_genasm_fsize - 5, nents, + alloc_sizes) != 0) + return (1); + + /* nop out the jump with a multibyte jump */ + vptr = (void *)&umem_genasm_mptr; + v = MULTINOP; + v |= *vptr & (0xffffffULL << 40); + (void) atomic_swap_64(vptr, v); + vptr = (void *)&umem_genasm_fptr; + v = MULTINOP; + v |= *vptr & (0xffffffULL << 40); + (void) atomic_swap_64(vptr, v); + + for (i = 0; i < nents; i++) + caches[i]->cache_flags |= UMF_PTC; + + return (0); +} diff --git a/usr/src/lib/libumem/sparc/umem_genasm.c b/usr/src/lib/libumem/sparc/umem_genasm.c new file mode 100644 index 0000000000..77dcc4a6a5 --- /dev/null +++ b/usr/src/lib/libumem/sparc/umem_genasm.c @@ -0,0 +1,38 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + +/* + * Don't Panic! If you wonder why this seemingly empty file exists, it's because + * there is no sparc implementation for ptcumem. Go read libumem's big theory + * statement in lib/libumem/common/umem.c, particularly section eight. + */ + +int umem_genasm_supported = 0; + +/*ARGSUSED*/ +int +umem_genasm(int *cp, int nc) +{ + return (1); +} diff --git a/usr/src/lib/print/libprint/Makefile b/usr/src/lib/libumem_trampoline/Makefile index 55847e0be0..e1140efa8c 100644 --- a/usr/src/lib/print/libprint/Makefile +++ b/usr/src/lib/libumem_trampoline/Makefile @@ -19,36 +19,32 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright (c) 2012 Joyent, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# -include ../../Makefile.lib +include ../Makefile.lib -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) +SUBDIRS= $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint +all := TARGET= all +clean := TARGET= clean +clobber := TARGET= clobber +install := TARGET= install +lint := TARGET= lint .KEEP_STATE: -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) +all clean clobber install lint: $(SUBDIRS) -install_h: +install_h: $(ROOTHDRS) -check: +check: $(CHECKHDRS) -$(SUBDIRS): FRC +$(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: -include ../../Makefile.targ +include ../Makefile.targ diff --git a/usr/src/lib/libumem_trampoline/Makefile.com b/usr/src/lib/libumem_trampoline/Makefile.com new file mode 100644 index 0000000000..a43fad0fd5 --- /dev/null +++ b/usr/src/lib/libumem_trampoline/Makefile.com @@ -0,0 +1,49 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright (c) 2012 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +LIBRARY = libumem_trampoline.a +VERS = .1 +OBJECTS = trampoline.o + +include ../../Makefile.lib + +# install this library in the root filesystem +include ../../Makefile.rootfs + +LIBS = $(DYNLIB) $(LINTLIB) + +SRCDIR = ../common + +$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC) + +CFLAGS += $(CCVERBOSE) + +.KEEP_STATE: + +all: $(LIBS) + +lint: lintcheck + +include ../../Makefile.targ diff --git a/usr/src/lib/print/libhttp-core/sparc/Makefile b/usr/src/lib/libumem_trampoline/amd64/Makefile index 0bc3313291..132720332b 100644 --- a/usr/src/lib/print/libhttp-core/sparc/Makefile +++ b/usr/src/lib/libumem_trampoline/amd64/Makefile @@ -19,12 +19,11 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2012 (c) Joyent, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../Makefile.com +include ../../Makefile.lib.64 -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libumem_trampoline/common/llib-lumem_trampoline b/usr/src/lib/libumem_trampoline/common/llib-lumem_trampoline new file mode 100644 index 0000000000..8fda64fc80 --- /dev/null +++ b/usr/src/lib/libumem_trampoline/common/llib-lumem_trampoline @@ -0,0 +1,28 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* LINTLIBRARY */ +/* PROTOLIB1 */ diff --git a/usr/src/lib/print/libhttp-core/common/mapfile b/usr/src/lib/libumem_trampoline/common/mapfile-vers index 1d641d73e1..c52eeda977 100644 --- a/usr/src/lib/print/libhttp-core/common/mapfile +++ b/usr/src/lib/libumem_trampoline/common/mapfile-vers @@ -18,13 +18,8 @@ # # CDDL HEADER END # - # -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # @@ -41,31 +36,27 @@ # MAPFILE HEADER END # +$mapfile_version 2 + # -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. +# The BSS must me executable for ptcumem to work properly. If it is not, +# programs will get a SEGV. For more information read section of 8 libumem's big +# theory statement in lib/libumem/common/umem.c. # +LOAD_SEGMENT bss { + FLAGS = READ WRITE EXECUTE; +}; -$mapfile_version 2 - -SYMBOL_VERSION SUNWprivate_1.0 { +SYMBOL_VERSION SUNWprivate_1.1 { global: - httpCheck ; - httpClose ; - httpConnectEncrypt ; - httpDumpData ; - httpEncode64 ; - httpEncryption ; - httpFlush ; - httpGetSubField ; - httpPost ; - httpRead ; - httpReconnect ; - httpSetField ; - httpUpdate ; - httpWait ; - httpWrite ; - + la_version; + la_objopen; +$if _ELF32 + la_symbind32; +$endif +$if _ELF64 + la_symbind64; +$endif local: - * ; -} ; + *; +}; diff --git a/usr/src/lib/libumem_trampoline/common/trampoline.c b/usr/src/lib/libumem_trampoline/common/trampoline.c new file mode 100644 index 0000000000..200f32aabc --- /dev/null +++ b/usr/src/lib/libumem_trampoline/common/trampoline.c @@ -0,0 +1,166 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2012 Joyent, Inc. All rights reserved. + */ + +/* + * This is a local link auditing library for libumem(3LIB). It provides a means + * for us to implement the per-thread caching component of libumem. When any + * binary or library attempts to bind to libumem's malloc and free symbols we + * instead point them to a private buffer in our own BSS. Our mapfile ensures + * that this BSS is readable, writeable, and executable. By default these + * private buffers contain a jmp instruction to the original libumem malloc and + * free. + * + * When libumem tries to generate its assembly, we key off of private symbol + * names and replace their values with pointers to our values. For more + * information on this process, see section 8 of the big theory statement for + * libumem in lib/libumem/common/umem.c. + * + * Note that this is very x86 specific currently. This includes x86 instructions + * and making assumptions about alignment of variables, see the lint warnings. + * By the current construction, SPARC is basically a no-op. + */ +#include <dlfcn.h> +#include <unistd.h> +#include <sys/types.h> +#include <libelf.h> +#include <link.h> + +#if defined(__i386) || defined(__amd64) +#define LIBUMEM_TRAMPOLINE_JMP32 0xe9 +#endif /* defined(__i386) || defined(__amd64) */ + +/* + * This is our malloc trampoline. We give it the name "malloc" to make it + * appear somewhat like malloc. + */ +static uint8_t malloc[4096]; +static uint8_t free[4096]; +static size_t msize = sizeof (malloc); +static size_t fsize = sizeof (free); + +/* + * We don't want to link against libc, so we define our own versions of the + * string functions as necessary. + */ +static int +la_strcmp(const char *s1, const char *s2) +{ + if (s1 == s2) + return (0); + while (*s1 == *s2++) + if (*s1++ == '\0') + return (0); + + return (*(unsigned char *)s1 - *(unsigned char *)--s2); +} + +static char * +la_strrchr(char *str, char c) +{ + char *r; + + r = NULL; + do { + if (*str == c) + r = str; + } while (*str++); + return (r); +} + +/*ARGSUSED*/ +uint_t +la_version(uint_t version) +{ + return (LAV_CURRENT); +} + +/*ARGSUSED*/ +uint_t +la_objopen(Link_map *lmp, Lmid_t lmid, uintptr_t *cookie) +{ +#if defined(__i386) || defined(__amd64) + char *objname; + + if ((objname = la_strrchr(lmp->l_name, '/')) == NULL || + *(++objname) == '\0') + objname = lmp->l_name; + + if (la_strcmp(objname, "libumem.so.1") == 0 || + la_strcmp(objname, "libumem.so") == 0) + return (LA_FLG_BINDFROM | LA_FLG_BINDTO); +#endif /* defined(__i386) || defined(__amd64) */ + + return (0); +} + +#if defined(_LP64) +/*ARGSUSED*/ +uintptr_t +la_symbind64(Elf64_Sym *symp, uint_t symndx, uintptr_t *refcook, + uintptr_t *defcook, uint_t *sb_flags, char const *sym_name) +#else +/*ARGSUSED*/ +uintptr_t +la_symbind32(Elf32_Sym *symp, uint_t symndx, uintptr_t *refcook, + uintptr_t *defcook, uint_t *sb_flags) +#endif +{ +#if defined(__i386) || defined(__amd64) + int i = 0; + +#if !defined(_LP64) + char const *sym_name = (char const *) symp->st_name; +#endif + + if (la_strcmp(sym_name, "malloc") == 0) { + if (malloc[i] == '\0') { + malloc[i++] = LIBUMEM_TRAMPOLINE_JMP32; + /*LINTED E_BAD_PTR_CAST_ALIGN*/ + *(uint32_t *)&malloc[i] = (uint32_t)(symp->st_value - + (uintptr_t)&malloc[i + sizeof (uint32_t)]); + } + + return ((uintptr_t)malloc); + } else if (la_strcmp(sym_name, "free") == 0) { + if (free[i] == '\0') { + free[i++] = LIBUMEM_TRAMPOLINE_JMP32; + /*LINTED E_BAD_PTR_CAST_ALIGN*/ + *(uint32_t *)&free[i] = (uint32_t)(symp->st_value - + (uintptr_t)&free[i + sizeof (uint32_t)]); + } + + return ((uintptr_t)free); + } else if (la_strcmp(sym_name, "umem_genasm_mptr") == 0) { + return ((uintptr_t)malloc); + } else if (la_strcmp(sym_name, "umem_genasm_msize") == 0) { + return ((uintptr_t)&msize); + } else if (la_strcmp(sym_name, "umem_genasm_fptr") == 0) { + return ((uintptr_t)free); + } else if (la_strcmp(sym_name, "umem_genasm_fsize") == 0) { + return ((uintptr_t)&fsize); + } else { + return (symp->st_value); + } +#endif /* defined(__i386) || defined(__amd64) */ +} diff --git a/usr/src/lib/libumem_trampoline/i386/Makefile b/usr/src/lib/libumem_trampoline/i386/Makefile new file mode 100644 index 0000000000..76c3ccc672 --- /dev/null +++ b/usr/src/lib/libumem_trampoline/i386/Makefile @@ -0,0 +1,29 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2012 (c) Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libumem_trampoline/sparc/Makefile b/usr/src/lib/libumem_trampoline/sparc/Makefile new file mode 100644 index 0000000000..76c3ccc672 --- /dev/null +++ b/usr/src/lib/libumem_trampoline/sparc/Makefile @@ -0,0 +1,29 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2012 (c) Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-core/i386/Makefile b/usr/src/lib/libumem_trampoline/sparcv9/Makefile index 3b985583a4..132720332b 100644 --- a/usr/src/lib/print/libipp-core/i386/Makefile +++ b/usr/src/lib/libumem_trampoline/sparcv9/Makefile @@ -19,12 +19,11 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2012 (c) Joyent, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# include ../Makefile.com +include ../../Makefile.lib.64 -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libvrrpadm/common/libvrrpadm.c b/usr/src/lib/libvrrpadm/common/libvrrpadm.c index 2e9cb06aaf..15365864a1 100644 --- a/usr/src/lib/libvrrpadm/common/libvrrpadm.c +++ b/usr/src/lib/libvrrpadm/common/libvrrpadm.c @@ -24,6 +24,10 @@ * Use is subject to license terms. */ +/* + * Copyright (c) 2012, Joyent, Inc. All rights reserved. + */ + #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> @@ -692,7 +696,8 @@ lookup_vnic(dladm_handle_t dh, datalink_id_t vnicid, void *arg) if (vrrp_is_vrrp_vnic(lva->lva_vh, vnicid, &linkid, &vid, &vrid, &af) && lva->lva_vrid == vrid && lva->lva_linkid == linkid && - lva->lva_vid == vid && lva->lva_af == af) { + (lva->lva_vid == VLAN_ID_NONE || lva->lva_vid == vid) && + lva->lva_af == af) { if (dladm_datalink_id2info(dh, vnicid, NULL, NULL, NULL, lva->lva_vnic, sizeof (lva->lva_vnic)) == DLADM_STATUS_OK) { return (DLADM_WALK_TERMINATE); @@ -714,6 +719,7 @@ vrrp_get_vnicname(vrrp_handle_t vh, vrid_t vrid, int af, char *link, uint16_t vid = VLAN_ID_NONE; datalink_class_t class; dladm_vlan_attr_t vlan_attr; + dladm_vnic_attr_t vnic_attr; struct lookup_vnic_arg lva; uint32_t media; @@ -736,11 +742,20 @@ vrrp_get_vnicname(vrrp_handle_t vh, vrid_t vrid, int af, char *link, } } + if (class == DATALINK_CLASS_VNIC) { + if (dladm_vnic_info(vh->vh_dh, linkid, &vnic_attr, + DLADM_OPT_ACTIVE) != DLADM_STATUS_OK) { + return (VRRP_EINVAL); + } + linkid = vnic_attr.va_link_id; + vid = vnic_attr.va_vid; + } + /* - * For now, Only VRRP over aggr and physical ethernet links is supported + * Only VRRP over vnics, aggrs and physical ethernet links is supported */ - if ((class != DATALINK_CLASS_PHYS && class != DATALINK_CLASS_AGGR) || - media != DL_ETHER) { + if ((class != DATALINK_CLASS_PHYS && class != DATALINK_CLASS_AGGR && + class != DATALINK_CLASS_VNIC) || media != DL_ETHER) { return (VRRP_EINVAL); } diff --git a/usr/src/lib/libzdoor/Makefile b/usr/src/lib/libzdoor/Makefile new file mode 100644 index 0000000000..50d9545ef1 --- /dev/null +++ b/usr/src/lib/libzdoor/Makefile @@ -0,0 +1,48 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# + +include ../Makefile.lib + +SUBDIRS= $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) + +all := TARGET = all +clean := TARGET = clean +clobber := TARGET = clobber +install := TARGET = install +lint := TARGET = lint + +.KEEP_STATE: + +all clean clobber install lint: $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +_msg: + +FRC: + +include ../Makefile.targ diff --git a/usr/src/lib/print/libpapi-common/Makefile.com b/usr/src/lib/libzdoor/Makefile.com index 7948a2261e..09bde0f1b4 100644 --- a/usr/src/lib/print/libpapi-common/Makefile.com +++ b/usr/src/lib/libzdoor/Makefile.com @@ -18,34 +18,28 @@ # # CDDL HEADER END # -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2011 Joyent, Inc. All rights reserved. # Use is subject to license terms. # -LIBRARY = libpapi-common.a -VERS = .0 -OBJECTS = attribute.o common.o library.o list.o misc.o status.o uri.o - -include ../../../Makefile.lib -include ../../../Makefile.rootfs +LIBRARY= libzdoor.a +VERS= .1 +OBJECTS= zdoor.o \ + zdoor-int.o \ + ztree.o \ + zerror.o -ROOTLIBDIR= $(ROOT)/usr/lib +include ../../Makefile.lib +include ../../Makefile.rootfs SRCDIR = ../common +SRCS = $(OBJECTS:%.o=$(SRCDIR)/%.c) -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) - -CERRWARN += -_gcc=-Wno-switch - -MAPFILES = $(SRCDIR)/mapfile +CPPFLAGS += -I$(SRCDIR) -D_REENTRANT -D_FILE_OFFSET_BITS=64 +LIBS = $(DYNLIB) $(LINTLIB) +LDLIBS += -lc -lzonecfg -lcontract -LDLIBS += -lc -lsocket -lnsl +$(LINTLIB) := SRCS= $(SRCDIR)/$(LINTSRC) .KEEP_STATE: @@ -53,4 +47,4 @@ all: $(LIBS) lint: lintcheck -include ../../../Makefile.targ +include ../../Makefile.targ diff --git a/usr/src/lib/libzdoor/amd64/Makefile b/usr/src/lib/libzdoor/amd64/Makefile new file mode 100644 index 0000000000..31be0ef7e6 --- /dev/null +++ b/usr/src/lib/libzdoor/amd64/Makefile @@ -0,0 +1,32 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com +include ../../Makefile.lib.64 + +install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64) diff --git a/usr/src/lib/libzdoor/common/llib-lzdoor b/usr/src/lib/libzdoor/common/llib-lzdoor new file mode 100644 index 0000000000..a21a904b11 --- /dev/null +++ b/usr/src/lib/libzdoor/common/llib-lzdoor @@ -0,0 +1,34 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/*LINTLIBRARY*/ +/*PROTOLIB1*/ +/* + * + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + * + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <zdoor.h> diff --git a/usr/src/lib/print/libipp-core/common/mapfile b/usr/src/lib/libzdoor/common/mapfile-vers index 19a947feb5..38eba57ee2 100644 --- a/usr/src/lib/print/libipp-core/common/mapfile +++ b/usr/src/lib/libzdoor/common/mapfile-vers @@ -18,13 +18,7 @@ # # CDDL HEADER END # - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile 151 2006-04-25 16:55:34Z njacobs $ +# Copyright (c) 2011, Joyent Inc. All rights reserved. # # @@ -43,18 +37,12 @@ $mapfile_version 2 -# -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. -# - -SYMBOL_VERSION SUNWprivate_1.0 { +SYMBOL_VERSION SUNWprivate_1.1 { global: - ipp_read_message ; - ipp_write_message ; - ipp_validate_request ; - ipp_set_status ; - + zdoor_handle_init; + zdoor_handle_destroy; + zdoor_open; + zdoor_close; local: - * ; -} ; + *; +}; diff --git a/usr/src/lib/libzdoor/common/zdoor-int.c b/usr/src/lib/libzdoor/common/zdoor-int.c new file mode 100644 index 0000000000..f77c1453d4 --- /dev/null +++ b/usr/src/lib/libzdoor/common/zdoor-int.c @@ -0,0 +1,324 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2012 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <errno.h> +#include <fcntl.h> +#include <sys/fork.h> +#include <libcontract.h> +#include <libzonecfg.h> +#include <sys/contract/process.h> +#include <sys/ctfs.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "zdoor-int.h" +#include "zerror.h" + +#define ZDOOR_FMT_STR "/var/tmp/.%s" + + +static int +init_template(void) +{ + int fd = 0; + int err = 0; + + fd = open64(CTFS_ROOT "/process/template", O_RDWR); + if (fd == -1) + return (-1); + + err |= ct_tmpl_set_critical(fd, 0); + err |= ct_tmpl_set_informative(fd, 0); + err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR); + err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT); + if (err || ct_tmpl_activate(fd)) { + (void) close(fd); + return (-1); + } + + return (fd); +} + +static int +contract_latest(ctid_t *id) +{ + int cfd = 0; + int r = 0; + ct_stathdl_t st = {0}; + ctid_t result = {0}; + + if ((cfd = open64(CTFS_ROOT "/process/latest", O_RDONLY)) == -1) + return (errno); + if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) { + (void) close(cfd); + return (r); + } + + result = ct_status_get_id(st); + ct_status_free(st); + (void) close(cfd); + + *id = result; + return (0); +} + +static int +close_on_exec(int fd) +{ + int flags = fcntl(fd, F_GETFD, 0); + if ((flags != -1) && (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1)) + return (0); + return (-1); +} + +static int +contract_open(ctid_t ctid, const char *type, const char *file, int oflag) +{ + char path[PATH_MAX]; + int n = 0; + int fd = 0; + + if (type == NULL) + type = "all"; + + n = snprintf(path, PATH_MAX, CTFS_ROOT "/%s/%ld/%s", type, ctid, file); + if (n >= sizeof (path)) { + errno = ENAMETOOLONG; + return (-1); + } + + fd = open64(path, oflag); + if (fd != -1) { + if (close_on_exec(fd) == -1) { + int err = errno; + (void) close(fd); + errno = err; + return (-1); + } + } + return (fd); +} + +static int +contract_abandon_id(ctid_t ctid) +{ + int fd = 0; + int err = 0; + + fd = contract_open(ctid, "all", "ctl", O_WRONLY); + if (fd == -1) + return (errno); + + err = ct_ctl_abandon(fd); + (void) close(fd); + + return (err); +} + +/* + * zdoor_fattach(zone,service,door,detach_only) is heavily borrowed from + * zonestatd. Basically this forks, zone_enter's the targeted zone, + * fattaches to /var/tmp/.<service> with the door you've opened. + * detach_only gets passed in on door_stop to fdetach in the targeted zone. + * Note that this code really does require all the contract calls, which are + * all the static functions preceding this (have a look at zone_enter; without + * that code zone_enter will kick back EINVAL). + */ +int +zdoor_fattach(zoneid_t zoneid, const char *service, int door, int detach_only) +{ + int fd = 0; + int len = 0; + int pid = 0; + int stat = 0; + int tmpl_fd = 0; + char path[MAXPATHLEN] = {0}; + ctid_t ct = -1; + + if (zoneid < 0) { + zdoor_debug("zdoor_fattach: zoneid < 0"); + return (ZDOOR_ARGS_ERROR); + } + + if (service == NULL) { + zdoor_debug("zdoor_fattach: NULL service"); + return (ZDOOR_ARGS_ERROR); + } + + if ((tmpl_fd = init_template()) < 0) { + zdoor_warn("zdoor_fattach: init contract for %d:%s failed", + zoneid, service); + return (ZDOOR_ERROR); + } + + len = snprintf(NULL, 0, ZDOOR_FMT_STR, service) + 1; + if (len > MAXPATHLEN) + return (ZDOOR_ARGS_ERROR); + (void) snprintf(path, len, ZDOOR_FMT_STR, service); + + zdoor_info("zdoor_fattach: ensuring %s", path); + + pid = fork(); + if (pid < 0) { + (void) ct_tmpl_clear(tmpl_fd); + zdoor_error("zdoor_fattach: unable to fork for zone_enter: %s", + strerror(errno)); + return (ZDOOR_OK); + } + + if (pid == 0) { + zdoor_debug("zdoor_fattach(CHILD): starting"); + (void) ct_tmpl_clear(tmpl_fd); + (void) close(tmpl_fd); + if (zone_enter(zoneid) != 0) { + zdoor_debug("zdoor_fattach(CHILD): zone_enter fail %s", + strerror(errno)); + if (errno == EINVAL) { + _exit(0); + } + _exit(1); + } + (void) fdetach(path); + (void) unlink(path); + if (detach_only) { + zdoor_debug("zdoor_fattach(CHILD): detach only, done"); + _exit(0); + } + fd = open(path, O_CREAT|O_RDWR, 0644); + if (fd < 0) { + zdoor_debug("zdoor_fattach(CHILD): open failed: %s", + strerror(errno)); + _exit(2); + } + if (fattach(door, path) != 0) { + zdoor_debug("zdoor_fattach(CHILD): fattach failed: %s", + strerror(errno)); + _exit(3); + } + _exit(0); + } + if (contract_latest(&ct) == -1) + ct = -1; + (void) ct_tmpl_clear(tmpl_fd); + (void) close(tmpl_fd); + (void) contract_abandon_id(ct); + + zdoor_debug("zdoor_fattach: waiting for child..."); + while (waitpid(pid, &stat, 0) != pid) + ; + if (WIFEXITED(stat) && WEXITSTATUS(stat) == 0) { + zdoor_debug(" child exited with success"); + zdoor_debug("zdoor_fattach: returning ZDOOR_OK"); + return (ZDOOR_OK); + } + + zdoor_debug(" child exited with %d", WEXITSTATUS(stat)); + zdoor_debug("zdoor_fattach: returning ZDOOR_ERROR"); + return (ZDOOR_ERROR); +} + +/* + * zdoor_zone_is_running(zone) returns 1 if the specified zone is running, or 0 + * if it is any other state. It additionally eats any other errors it + * encounters and returns 0 upon encountering them. + */ +boolean_t +zdoor_zone_is_running(zoneid_t zoneid) +{ + zone_state_t state; + char zone[ZONENAME_MAX]; + if (zoneid < 0) + return (B_FALSE); + + if (getzonenamebyid(zoneid, zone, ZONENAME_MAX) < 0) + return (B_FALSE); + + if (!zone_get_state((char *)zone, &state) == Z_OK) + return (B_FALSE); + + return (state == ZONE_STATE_RUNNING); +} + +/* + * zdoor_cookie_create simply allocates and initializes + * memory. Returns NULL on any error. + */ +zdoor_cookie_t * +zdoor_cookie_create(const char *zonename, const char *service, +const void *biscuit) +{ + zdoor_cookie_t *cookie = NULL; + + if (zonename == NULL || service == NULL) + return (NULL); + + cookie = (zdoor_cookie_t *)calloc(1, sizeof (zdoor_cookie_t)); + if (cookie == NULL) { + OUT_OF_MEMORY(); + return (NULL); + } + cookie->zdc_biscuit = (void *)biscuit; + cookie->zdc_zonename = strdup((char *)zonename); + if (cookie->zdc_zonename == NULL) { + zdoor_cookie_free(cookie); + OUT_OF_MEMORY(); + return (NULL); + } + cookie->zdc_service = strdup((char *)service); + if (cookie->zdc_service == NULL) { + zdoor_cookie_free(cookie); + OUT_OF_MEMORY(); + return (NULL); + } + + return (cookie); +} + +/* + * zdoor_cookie_free(cookie) cleans up any memory associated with the + * specified cookie. + */ +void +zdoor_cookie_free(zdoor_cookie_t *cookie) +{ + if (cookie == NULL) + return; + + if (cookie->zdc_zonename != NULL) { + free(cookie->zdc_zonename); + cookie->zdc_zonename = NULL; + } + + if (cookie->zdc_service != NULL) { + free(cookie->zdc_service); + cookie->zdc_service = NULL; + } + + free(cookie); +} diff --git a/usr/src/lib/print/libpapi-common/common/uri.h b/usr/src/lib/libzdoor/common/zdoor-int.h index 5dd714a199..782452c426 100644 --- a/usr/src/lib/print/libpapi-common/common/uri.h +++ b/usr/src/lib/libzdoor/common/zdoor-int.h @@ -18,49 +18,47 @@ * * CDDL HEADER END */ - /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2011 Joyent, Inc. All rights reserved. * Use is subject to license terms. - * */ -#ifndef _URI_H -#define _URI_H +#ifndef _ZDOOR_INT_H +#define _ZDOOR_INT_H -/* $Id: uri.h 146 2006-03-24 00:26:54Z njacobs $ */ +#pragma ident "%Z%%M% %I% %E% SMI" -#pragma ident "%Z%%M% %I% %E% SMI" +#include <pthread.h> +#include <zdoor.h> #ifdef __cplusplus extern "C" { #endif -/* - * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]] - */ -typedef struct { - char *scheme; - char *scheme_part; - char *user; - char *password; - char *host; - char *port; - char *path; - char *fragment; - char *query; - /* really for testing, but left in */ - char *user_part; - char *host_part; - char *path_part; -} uri_t; +typedef enum zdoor_action_t { + ZDOOR_ACTION_NOOP, + ZDOOR_ACTION_STOP, + ZDOOR_ACTION_START +} zdoor_action_t; + +struct zdoor_handle { + pthread_mutex_t zdh_lock; + void *zdh_zonecfg_handle; + void *zdh_ztree; +}; + +zdoor_cookie_t *zdoor_cookie_create(const char *zonename, const char *service, + const void *biscuit); + +void zdoor_cookie_free(zdoor_cookie_t *cookie); + +boolean_t zdoor_zone_is_running(zoneid_t zoneid); -extern int uri_from_string(char *string, uri_t **uri); -extern int uri_to_string(uri_t *uri, char *buffer, size_t buflen); -extern void uri_free(uri_t *uri); +int zdoor_fattach(zoneid_t zoneid, const char *service, int door, + int detach_only); #ifdef __cplusplus } #endif -#endif /* _URI_H */ +#endif /* _ZDOOR_INT_H */ diff --git a/usr/src/lib/libzdoor/common/zdoor.c b/usr/src/lib/libzdoor/common/zdoor.c new file mode 100644 index 0000000000..f2996b4e2d --- /dev/null +++ b/usr/src/lib/libzdoor/common/zdoor.c @@ -0,0 +1,437 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <alloca.h> +#include <door.h> +#include <errno.h> +#include <fcntl.h> +#include <libzonecfg.h> +#include <pthread.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <syslog.h> +#include <stdlib.h> +#include <string.h> +#include <stropts.h> +#include <unistd.h> +#include <zdoor.h> +#include <zone.h> + +#include "zdoor-int.h" +#include "zerror.h" +#include "ztree.h" + +extern void * +zonecfg_notify_bind(int(*func)(const char *zonename, zoneid_t zid, + const char *newstate, const char *oldstate, + hrtime_t when, void *p), void *p); + +extern void +zonecfg_notify_unbind(void *handle); + +/* + * _callback(cookie, door_args...) is our private function that we tell + * the Solaris door API about. This function does some sanity checking on + * arguments and issues a callback to the owner of this door. That API + * will return us memory that needs to be sent back to the client on the + * other end of the door, but since the door_return API never gives you + * back control of the function, this does a simple alloca/memcpy and + * frees up the memory pointed to by the parent. While this really doesn't + * let a client do much other than pass a simple struct of primitives (or + * more likely more common a char *), that's the way the door API works, + * and so this isn't really imposing any restriction that didn't already + * need to be dealt with by someone. This is why the zdoor_result structure + * takes a char *, rather than a void * for the data pointer. + */ +static void +_callback(void *cookie, char *argp, size_t arg_size, door_desc_t *dp, + uint_t n_desc) +{ + zdoor_result_t *result = NULL; + void *door_response = NULL; + int size = 0; + dtree_entry_t *entry = (dtree_entry_t *)cookie; + + if (entry == NULL) { + zdoor_warn("_callback: NULL cookie? door_returning"); + (void) door_return(NULL, 0, NULL, 0); + } + + (void) pthread_mutex_lock(&entry->dte_parent->zte_parent->zdh_lock); + zdoor_debug("_callback: calling back with %p", entry->dte_cookie); + result = entry->dte_callback(entry->dte_cookie, argp, arg_size); + zdoor_debug("_callback: app callback returned %p", result); + (void) pthread_mutex_unlock(&entry->dte_parent->zte_parent->zdh_lock); + + if (result == NULL) { + zdoor_debug("_callback: door_returning NULL"); + (void) door_return(NULL, 0, NULL, 0); + } + + if (result->zdr_data != NULL && result->zdr_size > 0) { + door_response = alloca(result->zdr_size); + if (door_response != NULL) { + size = result->zdr_size; + (void) memcpy(door_response, + (void *) result->zdr_data, size); + } + } + + if (result->zdr_data != NULL) + free(result->zdr_data); + free(result); + + zdoor_debug("_callback: door_returning %p, %d", door_response, size); + (void) door_return(door_response, size, NULL, 0); +} + +static void +zdoor_stop(dtree_entry_t *entry) +{ + zoneid_t zid = -1; + + if (entry == NULL) { + zdoor_debug("zdoor_stop: NULL arguments"); + return; + } + + zdoor_debug("zdoor_stop: entry=%p, zone=%s, service=%s", + entry, entry->dte_parent->zte_zonename, entry->dte_service); + + zid = getzoneidbyname(entry->dte_parent->zte_zonename); + (void) zdoor_fattach(zid, entry->dte_service, entry->dte_door, 1); + (void) door_revoke(entry->dte_door); + entry->dte_door = -1; + + zdoor_debug("zdoor_stop returning"); +} + +/* + * zdoor_create is called both by the main API + * call zdoor_open, as well as by the zone_monitor code upon a zone restart + * (assuming it already has a door in it). This code assumes that the + * permissions were correct (e.g., the target door is not a GZ, that this + * program is being run out of the GZ), but does not assume that the target + * door file has not changed out from under us, so that is explicitly rechecked. + * + * This also assumes the parent has already locked handle. + */ +static int +zdoor_create(dtree_entry_t *entry) +{ + int status = ZDOOR_OK; + zoneid_t zid = -1; + zdoor_handle_t handle = NULL; + + if (entry == NULL) { + zdoor_debug("zdoor_create: NULL arguments"); + return (ZDOOR_ARGS_ERROR); + } + + zdoor_debug("zdoor_create: entry=%p, zone=%s, service=%s", + entry, entry->dte_parent->zte_zonename, entry->dte_service); + + handle = entry->dte_parent->zte_parent; + + zid = getzoneidbyname(entry->dte_parent->zte_zonename); + if (zid < 0) { + zdoor_info("zdoor_create: %s is a non-existient zone", + entry->dte_parent->zte_zonename); + return (ZDOOR_ERROR); + } + if (!zdoor_zone_is_running(zid)) { + zdoor_debug("zdoor_create: %s is not running", + entry->dte_parent->zte_zonename); + return (ZDOOR_ZONE_NOT_RUNNING); + } + + entry->dte_door = door_create(_callback, entry, 0); + zdoor_info("zdoor_create: door_create returned %d", entry->dte_door); + if (entry->dte_door < 0) { + zdoor_stop(entry); + return (ZDOOR_ERROR); + } + + status = zdoor_fattach(zid, entry->dte_service, entry->dte_door, 0); + + zdoor_debug("zdoor_create: returning %d", status); + return (status); +} + + +/* + * door_visitor(entry) is a callback from the ztree code that checks whether + * or not we should be taking some action on a given door. Note that the + * callpath to this API is: + * SYSTEM -> + * zone_monitor -> + * ztree_walk -> + * door_visitor + * + * Which is important to note that this API assumes that all things needing + * locking are locked by a parent caller (which is the zone_monitor). + */ +static void +zdoor_visitor(dtree_entry_t *entry) +{ + if (entry == NULL) { + zdoor_info("zdoor_visitor: entered with NULL entry"); + return; + } + + zdoor_debug("zdoor_visitor: entered for entry=%p, service=%s", + entry, entry->dte_service); + + if (entry->dte_parent->zte_action == ZDOOR_ACTION_STOP) { + zdoor_debug(" stopping zdoor"); + zdoor_stop(entry); + } else if (entry->dte_parent->zte_action == ZDOOR_ACTION_START) { + zdoor_debug(" starting zdoor"); + if (zdoor_create(entry) != ZDOOR_OK) { + zdoor_error("door_visitor: Unable to restart zdoor\n"); + } + } +} + +/* + * zone_monitor(zonename, zid, newstate, oldstate, when, cookie) is our + * registered callback with libzonecfg to notify us of any changes to a + * given zone. This activates a walk on all doors for a zone iff the state + * is changing from running or into running. + */ +static int +zone_monitor(const char *zonename, zoneid_t zid, const char *newstate, + const char *oldstate, hrtime_t when, void *p) +{ + zdoor_handle_t handle = (zdoor_handle_t)p; + ztree_entry_t *entry = NULL; + + if (handle == NULL) { + zdoor_warn("zone_monitor: entered with NULL handle?"); + return (-1); + } + + zdoor_info("zone_monitor: zone=%s, zid=%d, newst=%s, oldst=%s, p=%p", + zonename, zid, newstate, oldstate, p); + + (void) pthread_mutex_lock(&(handle->zdh_lock)); + entry = ztree_zone_find(handle, zonename); + if (entry != NULL) { + zdoor_debug(" found entry in ztree"); + entry->zte_action = ZDOOR_ACTION_NOOP; + if (strcmp("running", newstate) == 0) { + if (strcmp("ready", oldstate) == 0) + entry->zte_action = ZDOOR_ACTION_START; + } else if (strcmp("shutting_down", newstate) == 0) { + if (strcmp("running", oldstate) == 0) + entry->zte_action = ZDOOR_ACTION_STOP; + } + zdoor_debug(" set state to: %d", entry->zte_action); + if (entry->zte_action != ZDOOR_ACTION_NOOP) + ztree_walk_doors(handle, zonename); + } + (void) pthread_mutex_unlock(&(handle->zdh_lock)); + + zdoor_info("zone_monitor: returning"); + return (0); +} + +zdoor_handle_t +zdoor_handle_init() +{ + zdoor_handle_t handle = NULL; + + zdoor_debug("zdoor_handle_init entered"); + + handle = (zdoor_handle_t)calloc(1, sizeof (struct zdoor_handle)); + if (handle == NULL) { + OUT_OF_MEMORY(); + return (NULL); + } + + (void) pthread_mutex_init(&(handle->zdh_lock), NULL); + handle->zdh_zonecfg_handle = zonecfg_notify_bind(zone_monitor, handle); + if (handle->zdh_zonecfg_handle == NULL) { + zdoor_error("zonecfg_notify_bind failure: %s", strerror(errno)); + return (NULL); + } + + zdoor_debug("zdoor_handle_init returning %p", handle); + return (handle); +} + +void +zdoor_handle_destroy(zdoor_handle_t handle) +{ + if (handle == NULL) { + zdoor_debug("zdoor_handle_destroy: NULL arguments"); + return; + } + + zdoor_debug("zdoor_handle_destroy: handle=%p", handle); + + (void) pthread_mutex_lock(&(handle->zdh_lock)); + zonecfg_notify_unbind(handle->zdh_zonecfg_handle); + (void) pthread_mutex_unlock(&(handle->zdh_lock)); + (void) pthread_mutex_destroy(&(handle->zdh_lock)); + free(handle); +} + +/* + * zdoor_open(zone, service, biscuit, callback) is the main public facing API in + * libzdoor. It will open a door with the name .[service] under + * [zonepath]/root/var/tmp, where [zonepath] is resolved on the fly. Note this + * API can only be invoked from the global zone, and will not allow you to open + * a zdoor in the global zone. + */ +int +zdoor_open(zdoor_handle_t handle, const char *zonename, const char *service, + void *biscuit, zdoor_callback callback) +{ + zdoor_cookie_t *zdoor_cookie = NULL; + int rc = -1; + int status = ZDOOR_OK; + zoneid_t zid = -1; + dtree_entry_t *entry = NULL; + + if (handle == NULL || zonename == NULL || + service == NULL || callback == NULL) { + zdoor_debug("zdoor_open: NULL arguments"); + return (ZDOOR_ARGS_ERROR); + } + zdoor_debug("zdoor_open: entered: handle=%p, zone=%s, service=%s", + handle, zonename, service); + + if (getzoneid() != GLOBAL_ZONEID) { + zdoor_warn("zdoor_open: not invoked from global zone"); + return (ZDOOR_NOT_GLOBAL_ZONE); + } + + + zid = getzoneidbyname(zonename); + if (zid < 0) { + zdoor_info("zdoor_open: %s is a non-existent zone", zonename); + return (ZDOOR_ARGS_ERROR); + } + + if (zid == GLOBAL_ZONEID) { + zdoor_warn("zdoor_open: zdoors not allowed in global zone"); + return (ZDOOR_ZONE_FORBIDDEN); + } + + if (!zdoor_zone_is_running(zid)) { + zdoor_info("zdoor_open: %s is not running", zonename); + return (ZDOOR_ZONE_NOT_RUNNING); + } + + zdoor_cookie = zdoor_cookie_create(zonename, service, biscuit); + if (zdoor_cookie == NULL) { + OUT_OF_MEMORY(); + return (ZDOOR_OUT_OF_MEMORY); + } + + (void) pthread_mutex_lock(&(handle->zdh_lock)); + rc = ztree_zone_add(handle, zonename, zdoor_visitor); + if (rc != ZTREE_SUCCESS && rc != ZTREE_ALREADY_EXISTS) { + zdoor_debug("zdoor_open: unable to add zone to ztree: %d", rc); + status = ZDOOR_ERROR; + goto out; + } + rc = ztree_door_add(handle, zonename, service, callback, + zdoor_cookie); + if (rc != ZTREE_SUCCESS) { + zdoor_debug("zdoor_open: unable to add door to ztree: %d", rc); + if (rc == ZTREE_ALREADY_EXISTS) { + zdoor_warn("service %s already has a zdoor", service); + } + status = ZDOOR_ERROR; + goto out; + } + + entry = ztree_door_find(handle, zonename, service); + if (entry == NULL) { + zdoor_debug("zdoor_open: unable to find door in ztree?"); + status = ZDOOR_ERROR; + goto out; + } + if (zdoor_create(entry) != ZDOOR_OK) { + zdoor_info("zdoor_open: zdoor_create failed."); + status = ZDOOR_ERROR; + goto out; + } +out: + if (status != ZDOOR_OK) { + zdoor_debug("zdoor_open: status not ok, stopping and cleaning"); + zdoor_stop(entry); + ztree_door_remove(handle, entry); + zdoor_cookie_free(zdoor_cookie); + } + (void) pthread_mutex_unlock(&(handle->zdh_lock)); + zdoor_debug("zdoor_open: returning %d", status); + return (status); +} + +/* + * zdoor_close(zone, service) unregisters a previously created zdoor, and + * returns the biscuit provided at creation time, so the caller can free it. + * Returns NULL on any error. + */ +void * +zdoor_close(zdoor_handle_t handle, const char *zonename, const char *service) +{ + dtree_entry_t *entry = NULL; + zdoor_cookie_t *cookie = NULL; + void *biscuit = NULL; + + if (handle == NULL || zonename == NULL || service == NULL) { + zdoor_debug("zdoor_close: NULL arguments"); + return (NULL); + } + + zdoor_debug("zdoor_close: entered handle=%p, zone=%s, service=%s", + handle, zonename, service); + + (void) pthread_mutex_lock(&(handle->zdh_lock)); + + entry = ztree_door_find(handle, zonename, service); + if (entry != NULL) { + zdoor_debug("zdoor_close: found door in ztree, stopping"); + zdoor_stop(entry); + cookie = ztree_door_remove(handle, entry); + if (cookie != NULL) { + biscuit = cookie->zdc_biscuit; + zdoor_cookie_free(cookie); + } + } else { + zdoor_debug("zdoor_close: didn't find door in ztree"); + } + + (void) pthread_mutex_unlock(&(handle->zdh_lock)); + + zdoor_debug("zdoor_close: returning %p", biscuit); + return (biscuit); +} diff --git a/usr/src/lib/libzdoor/common/zerror.c b/usr/src/lib/libzdoor/common/zerror.c new file mode 100644 index 0000000000..5ccb449e1b --- /dev/null +++ b/usr/src/lib/libzdoor/common/zerror.c @@ -0,0 +1,117 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <pthread.h> +#include <sys/types.h> +#include <stdarg.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "zerror.h" + +static const char *PREFIX = "%s ZDOOR:%s:T(%d): "; + +static const char *DEBUG_ENV_VAR = "ZDOOR_TRACE"; + +static boolean_t +is_debug_enabled() +{ + boolean_t enabled = B_FALSE; + const char *_envp = getenv(DEBUG_ENV_VAR); + if (_envp != NULL && atoi(_envp) >= 2) + enabled = B_TRUE; + + return (enabled); +} + +static boolean_t +is_info_enabled() +{ + boolean_t enabled = B_FALSE; + const char *_envp = getenv(DEBUG_ENV_VAR); + if (_envp != NULL && atoi(_envp) >= 1) + enabled = B_TRUE; + + return (enabled); +} + +void +zdoor_debug(const char *fmt, ...) +{ + va_list alist; + + if (!is_debug_enabled()) + return; + + va_start(alist, fmt); + + (void) fprintf(stderr, PREFIX, __TIME__, "DEBUG", pthread_self()); + (void) vfprintf(stderr, fmt, alist); + (void) fprintf(stderr, "\n"); + va_end(alist); +} + +void +zdoor_info(const char *fmt, ...) +{ + va_list alist; + + if (!is_info_enabled()) + return; + + va_start(alist, fmt); + + (void) fprintf(stderr, PREFIX, __TIME__, "INFO", pthread_self()); + (void) vfprintf(stderr, fmt, alist); + (void) fprintf(stderr, "\n"); + va_end(alist); +} + +void +zdoor_warn(const char *fmt, ...) +{ + va_list alist; + + va_start(alist, fmt); + + (void) fprintf(stderr, PREFIX, __TIME__, "WARN", pthread_self()); + (void) vfprintf(stderr, fmt, alist); + (void) fprintf(stderr, "\n"); + va_end(alist); +} + +void +zdoor_error(const char *fmt, ...) +{ + va_list alist; + + va_start(alist, fmt); + + (void) fprintf(stderr, PREFIX, __TIME__, "ERROR", pthread_self()); + (void) vfprintf(stderr, fmt, alist); + (void) fprintf(stderr, "\n"); + va_end(alist); +} diff --git a/usr/src/lib/print/libprint/common/list.h b/usr/src/lib/libzdoor/common/zerror.h index cb9b62df78..afc848fcea 100644 --- a/usr/src/lib/print/libprint/common/list.h +++ b/usr/src/lib/libzdoor/common/zerror.h @@ -19,32 +19,30 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2011 Joyent, Inc. All rights reserved. * Use is subject to license terms. */ -#ifndef _LIST_H -#define _LIST_H +#ifndef _ZERROR_H +#define _ZERROR_H -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/va_list.h> +#include <stdio.h> +#include <stdlib.h> #ifdef __cplusplus extern "C" { #endif -#define VFUNC_T int (*)(void *, __va_list) /* for casting */ -#define COMP_T int (*)(void *, void *) /* for casting */ +extern void zdoor_debug(const char *fmt, ...); +extern void zdoor_info(const char *fmt, ...); +extern void zdoor_warn(const char *fmt, ...); +extern void zdoor_error(const char *fmt, ...); -extern void **list_append(void **, void *); -extern void **list_append_unique(void **, void *, int (*)(void *, void*)); -extern void **list_concatenate(void **, void **); -extern void * list_locate(void **, int (*)(void *, void *), void *); -extern int list_iterate(void **, int (*)(void *, __va_list), ...); +#define OUT_OF_MEMORY() \ + zdoor_error("Out of Memory at %s:%d", __FILE__, __LINE__) #ifdef __cplusplus } #endif -#endif /* _LIST_H */ +#endif /* _ZERROR_H */ diff --git a/usr/src/lib/libzdoor/common/ztree.c b/usr/src/lib/libzdoor/common/ztree.c new file mode 100644 index 0000000000..25c67f62fb --- /dev/null +++ b/usr/src/lib/libzdoor/common/ztree.c @@ -0,0 +1,344 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <search.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "zerror.h" +#include "ztree.h" + + +/* + * ztree is just a helpful wrapper over a tsearch binary tree that deals with + * all of the libzdoor types. + * + * So what this ztree actually is is a tree of trees. The outer tree is a tree + * of zones, and each node holds a tree of doors. + */ + +/* + * _ztree_compare(p1, p2) is the tsearch callback for comparing the "outer" + * tree (e.g., the one of zones). + */ +static int +_ztree_compare(const void *p1, const void *p2) +{ + ztree_entry_t *z1 = (ztree_entry_t *)p1; + ztree_entry_t *z2 = (ztree_entry_t *)p2; + + if (z1 == NULL && z2 == NULL) + return (0); + if (z1 == NULL && z2 != NULL) + return (-1); + if (z1 != NULL && z2 == NULL) + return (1); + + return (strcmp(z1->zte_zonename, z2->zte_zonename)); +} + +/* + * _dtree_compare(p1, p2) is the tsearch callback for comparing the "inner" + * tree (e.g., the one of doors). + */ +static int +_dtree_compare(const void *p1, const void *p2) +{ + dtree_entry_t *d1 = (dtree_entry_t *)p1; + dtree_entry_t *d2 = (dtree_entry_t *)p2; + + if (d1 == NULL && d2 == NULL) + return (0); + if (d1 == NULL && d2 != NULL) + return (-1); + if (d1 != NULL && d2 == NULL) + return (1); + + return (strcmp(d1->dte_service, d2->dte_service)); +} + +static void +ztree_entry_free(ztree_entry_t *entry) +{ + if (entry == NULL) + return; + + if (entry->zte_zonename != NULL) + free(entry->zte_zonename); + + free(entry); +} + +static void +dtree_entry_free(dtree_entry_t *entry) +{ + if (entry == NULL) + return; + + if (entry->dte_service) + free(entry->dte_service); + + free(entry); +} + + +/* + * ztree_zone_add inserts a new zone into the tree iff + * there is not already an entry for that zone. This method returns one of + * four possible return codes, ZTREE_SUCCESS on :), ZTREE_ARGUMENT_ERROR if + * zone is NULL, ZTREE_ERROR if there is internal failure (e.g., OOM), and + * ZTREE_ALREADY_EXISTS if the zone is already in the tree. + */ +int +ztree_zone_add(struct zdoor_handle *handle, const char *zonename, +ztree_door_visitor visitor) +{ + ztree_entry_t *entry = NULL; + void *ret = NULL; + int status = ZTREE_SUCCESS; + + if (handle == NULL || zonename == NULL) + return (ZTREE_ARGUMENT_ERROR); + + entry = (ztree_entry_t *)calloc(1, sizeof (ztree_entry_t)); + if (entry == NULL) { + OUT_OF_MEMORY(); + return (ZTREE_ERROR); + } + entry->zte_zonename = strdup(zonename); + if (entry->zte_zonename == NULL) { + ztree_entry_free(entry); + OUT_OF_MEMORY(); + return (ZTREE_ERROR); + } + entry->zte_action = ZDOOR_ACTION_NOOP; + entry->zte_parent = handle; + entry->zte_visitor = visitor; + + ret = tsearch(entry, &(handle->zdh_ztree), _ztree_compare); + if (ret == NULL) { + ztree_entry_free(entry); + status = ZTREE_ERROR; + OUT_OF_MEMORY(); + } else if ((*(ztree_entry_t **)ret) != entry) { + ztree_entry_free(entry); + status = ZTREE_ALREADY_EXISTS; + } + + return (status); +} + + +/* + * ztree_zone_find returns the entry in the "outer" tree representing + * this zone, if it exists, NULL otherwise. + */ +ztree_entry_t * +ztree_zone_find(struct zdoor_handle *handle, const char *zonename) +{ + ztree_entry_t key = {0}; + void *ret = NULL; + + if (handle == NULL || zonename == NULL) + return (NULL); + + key.zte_zonename = (char *)zonename; + ret = tfind(&key, &(handle->zdh_ztree), _ztree_compare); + + return (ret != NULL ? *(ztree_entry_t **)ret : NULL); +} + + +/* + * ztree_zone_remove removes an entry from the "outer" zone iff the + * zone exists. The cookie set by the creator is returned. + */ +void +ztree_zone_remove(struct zdoor_handle *handle, ztree_entry_t *entry) +{ + if (handle == NULL || entry == NULL) + return; + + tdelete(entry, &(handle->zdh_ztree), _ztree_compare); + ztree_entry_free(entry); +} + + +/* + * ztree_door_add inserts a new door into the inner tree iff + * there is not already an entry for that door. This method returns one of + * four possible return codes, ZTREE_SUCCESS on :), ZTREE_ARGUMENT_ERROR if + * zone is NULL, ZTREE_ERROR if there is internal failure (e.g., OOM), and + * ZTREE_ALREADY_EXISTS if the door is already in the tree. + */ +int +ztree_door_add(struct zdoor_handle *handle, const char *zonename, +const char *service, zdoor_callback callback, zdoor_cookie_t *cookie) +{ + dtree_entry_t *entry = NULL; + ztree_entry_t *znode = NULL; + void *ret = NULL; + int status = ZTREE_SUCCESS; + + if (handle == NULL || zonename == NULL || service == NULL) + return (ZTREE_ARGUMENT_ERROR); + + znode = ztree_zone_find(handle, zonename); + if (znode == NULL) + return (ZTREE_NOT_FOUND); + + entry = (dtree_entry_t *)calloc(1, sizeof (dtree_entry_t)); + if (entry == NULL) { + OUT_OF_MEMORY(); + return (ZTREE_ERROR); + } + entry->dte_parent = znode; + entry->dte_callback = callback; + entry->dte_cookie = cookie; + entry->dte_service = strdup(service); + if (entry->dte_service == NULL) { + free(entry); + OUT_OF_MEMORY(); + return (ZTREE_ERROR); + } + + ret = tsearch(entry, &(znode->zte_door_tree), _dtree_compare); + if (ret == NULL) { + dtree_entry_free(entry); + OUT_OF_MEMORY(); + status = ZTREE_ERROR; + } else if ((*(dtree_entry_t **)ret) != entry) { + dtree_entry_free(entry); + status = ZTREE_ALREADY_EXISTS; + } else { + znode->zte_num_doors++; + } + + return (status); +} + + +/* + * ztree_door_find returns the entry in the "inner" tree + * representing this zone, if it exists, NULL otherwise. + */ +dtree_entry_t * +ztree_door_find(struct zdoor_handle *handle, const char *zonename, +const char *service) +{ + dtree_entry_t key = {0}; + ztree_entry_t *znode = NULL; + void *ret = NULL; + + if (handle == NULL || zonename == NULL || service == NULL) + return (NULL); + + znode = ztree_zone_find(handle, zonename); + if (znode == NULL) + return (NULL); + + key.dte_service = (char *)service; + ret = tfind(&key, &(znode->zte_door_tree), _dtree_compare); + + return (ret != NULL ? *(dtree_entry_t **)ret : NULL); +} + + +/* + * ztree_door_remove(zone, door) removes a node from the inner tree iff + * both the door and zone exist. Note this frees the node as well. The + * cookie set by the creator is returned. + */ +zdoor_cookie_t * +ztree_door_remove(struct zdoor_handle *handle, dtree_entry_t *entry) +{ + zdoor_cookie_t *cookie = NULL; + ztree_entry_t *znode = NULL; + + if (handle == NULL || entry == NULL) + return (NULL); + + znode = entry->dte_parent; + cookie = entry->dte_cookie; + + tdelete(entry, &(znode->zte_door_tree), _dtree_compare); + dtree_entry_free(entry); + + znode->zte_num_doors--; + if (znode->zte_num_doors == 0) { + zdoor_debug("ztree: zone %s has no doors left, removing", + znode->zte_zonename); + ztree_zone_remove(handle, znode); + } + + return (cookie); +} + + +/* + * _ztree_door_visitor(nodep, which, depth) is the private function we use + * to wrap up tsearch's goofy API. We're really just using this to ensure + * zdoor doesn't get called > 1 times for a given entity in the ztree. + */ +static void +_ztree_door_visitor(const void *nodep, const VISIT which, const int depth) +{ + dtree_entry_t *entry = *(dtree_entry_t **)nodep; + + if (entry == NULL) + return; + + switch (which) { + case preorder: + case endorder: + break; + case postorder: + case leaf: + if (entry->dte_parent->zte_visitor != NULL) + entry->dte_parent->zte_visitor(entry); + break; + } +} + + +/* + * ztree_walk_doors(zone) will proceed to visit every node in the "inner" tree + * for this zone, and callback the visitor that was registered on tree creation. + */ +void +ztree_walk_doors(struct zdoor_handle *handle, const char *zonename) +{ + ztree_entry_t *znode = NULL; + + if (handle == NULL || zonename == NULL) + return; + + znode = ztree_zone_find(handle, zonename); + if (znode == NULL) + return; + + twalk(znode->zte_door_tree, _ztree_door_visitor); +} diff --git a/usr/src/lib/libzdoor/common/ztree.h b/usr/src/lib/libzdoor/common/ztree.h new file mode 100644 index 0000000000..b46dace287 --- /dev/null +++ b/usr/src/lib/libzdoor/common/ztree.h @@ -0,0 +1,88 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2011 Joyent, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _ZTREE_H +#define _ZTREE_H + +#include <zdoor.h> +#include <zone.h> +#include "zdoor-int.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct dtree_entry; + +typedef void (*ztree_door_visitor)(struct dtree_entry *entry); + +typedef struct ztree_entry { + char *zte_zonename; + zdoor_action_t zte_action; + int zte_num_doors; + void *zte_door_tree; + ztree_door_visitor zte_visitor; + struct zdoor_handle *zte_parent; +} ztree_entry_t; + +typedef struct dtree_entry { + char *dte_service; + int dte_door; + zdoor_callback dte_callback; + zdoor_cookie_t *dte_cookie; + ztree_entry_t *dte_parent; +} dtree_entry_t; + +#define ZTREE_SUCCESS 0 +#define ZTREE_ERROR -1 +#define ZTREE_ARGUMENT_ERROR -2 +#define ZTREE_ALREADY_EXISTS -3 +#define ZTREE_NOT_FOUND -4 + +extern int ztree_zone_add(struct zdoor_handle *handle, + const char *zonename, ztree_door_visitor visitor); + +extern ztree_entry_t *ztree_zone_find(struct zdoor_handle *handle, + const char *zonename); + +extern void ztree_zone_remove(struct zdoor_handle *handle, + ztree_entry_t *entry); + +extern int ztree_door_add(struct zdoor_handle *handle, const char *zonename, + const char *service, zdoor_callback callback, zdoor_cookie_t *cookie); + +extern dtree_entry_t *ztree_door_find(struct zdoor_handle *handle, + const char *zonename, const char *service); + +extern zdoor_cookie_t *ztree_door_remove(struct zdoor_handle *handle, + dtree_entry_t *entry); + +extern void ztree_walk_doors(struct zdoor_handle *handle, const char *zonename); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZTREE_H */ diff --git a/usr/src/lib/libzdoor/i386/Makefile b/usr/src/lib/libzdoor/i386/Makefile new file mode 100644 index 0000000000..2bfe8001d9 --- /dev/null +++ b/usr/src/lib/libzdoor/i386/Makefile @@ -0,0 +1,31 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2011 Joyent, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +include ../Makefile.com + +install: all $(ROOTLIBS) $(ROOTLINKS) $(ROOTLINT) diff --git a/usr/src/lib/libzfs/common/libzfs.h b/usr/src/lib/libzfs/common/libzfs.h index 4d1e8186d2..4b57c61400 100644 --- a/usr/src/lib/libzfs/common/libzfs.h +++ b/usr/src/lib/libzfs/common/libzfs.h @@ -62,6 +62,7 @@ typedef enum zfs_error { EZFS_PROPTYPE, /* property does not apply to dataset type */ EZFS_PROPNONINHERIT, /* property is not inheritable */ EZFS_PROPSPACE, /* bad quota or reservation */ + EZFS_PROPCACHED, /* prop unavail since cachedprops flag set */ EZFS_BADTYPE, /* dataset is not of appropriate type */ EZFS_BUSY, /* pool or dataset is busy */ EZFS_EXISTS, /* pool or dataset already exists */ @@ -182,6 +183,7 @@ extern libzfs_handle_t *zpool_get_handle(zpool_handle_t *); extern libzfs_handle_t *zfs_get_handle(zfs_handle_t *); extern void libzfs_print_on_error(libzfs_handle_t *, boolean_t); +extern void libzfs_set_cachedprops(libzfs_handle_t *, boolean_t); extern void zfs_save_arguments(int argc, char **, char *, int); extern int zpool_log_history(libzfs_handle_t *, const char *); @@ -264,7 +266,7 @@ extern int zpool_label_disk(libzfs_handle_t *, zpool_handle_t *, char *); */ extern int zpool_set_prop(zpool_handle_t *, const char *, const char *); extern int zpool_get_prop(zpool_handle_t *, zpool_prop_t, char *, - size_t proplen, zprop_source_t *); + size_t proplen, zprop_source_t *, boolean_t); extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *); diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c index 6121a0f161..16700bb6a6 100644 --- a/usr/src/lib/libzfs/common/libzfs_dataset.c +++ b/usr/src/lib/libzfs/common/libzfs_dataset.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved. * Copyright 2012 Nexenta Systems, Inc. All rights reserved. @@ -326,6 +327,10 @@ get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc) { libzfs_handle_t *hdl = zhp->zfs_hdl; + if (hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(hdl, zc) != 0) + return (-1); + (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name)); while (ioctl(hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, zc) != 0) { @@ -1822,6 +1827,11 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src, case ZFS_PROP_NORMALIZE: case ZFS_PROP_UTF8ONLY: case ZFS_PROP_CASE: + if (zhp->zfs_hdl->libzfs_cachedprops) { + return (zfs_error(zhp->zfs_hdl, EZFS_PROPCACHED, + "property unavailable since not cached")); + } + if (!zfs_prop_valid_for_type(prop, zhp->zfs_head_type) || zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); @@ -2058,6 +2068,7 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, char *str; const char *strval; boolean_t received = zfs_is_recvd_props_mode(zhp); + boolean_t printerr; /* * Check to see if this property applies to our object @@ -2068,6 +2079,16 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, if (received && zfs_prop_readonly(prop)) return (-1); + if (zhp->zfs_hdl->libzfs_cachedprops && + zfs_prop_cacheable(prop)) { + printerr = zhp->zfs_hdl->libzfs_printerr; + libzfs_print_on_error(zhp->zfs_hdl, B_FALSE); + (void) zfs_error(zhp->zfs_hdl, EZFS_PROPCACHED, + "property unavailable since not cached"); + libzfs_print_on_error(zhp->zfs_hdl, printerr); + return (-1); + } + if (src) *src = ZPROP_SRC_NONE; @@ -2125,8 +2146,8 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen, } if ((zpool_get_prop(zhp->zpool_hdl, - ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL)) || - (strcmp(root, "-") == 0)) + ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL, + B_FALSE)) || (strcmp(root, "-") == 0)) root[0] = '\0'; /* * Special case an alternate root of '/'. This will diff --git a/usr/src/lib/libzfs/common/libzfs_impl.h b/usr/src/lib/libzfs/common/libzfs_impl.h index 576b2af5d2..62793dcda1 100644 --- a/usr/src/lib/libzfs/common/libzfs_impl.h +++ b/usr/src/lib/libzfs/common/libzfs_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -79,6 +80,7 @@ struct libzfs_handle { libzfs_fru_t **libzfs_fru_hash; libzfs_fru_t *libzfs_fru_list; char libzfs_chassis_id[256]; + boolean_t libzfs_cachedprops; }; #define ZFSSHARE_MISS 0x01 /* Didn't find entry in cache */ @@ -149,6 +151,7 @@ int zpool_standard_error_fmt(libzfs_handle_t *, int, const char *, ...); int get_dependents(libzfs_handle_t *, boolean_t, const char *, char ***, size_t *); zfs_handle_t *make_dataset_handle_zc(libzfs_handle_t *, zfs_cmd_t *); +int libzfs_cmd_set_cachedprops(libzfs_handle_t *, zfs_cmd_t *); int zprop_parse_value(libzfs_handle_t *, nvpair_t *, int, zfs_type_t, diff --git a/usr/src/lib/libzfs/common/libzfs_iter.c b/usr/src/lib/libzfs/common/libzfs_iter.c index be5767f542..48333df7d9 100644 --- a/usr/src/lib/libzfs/common/libzfs_iter.c +++ b/usr/src/lib/libzfs/common/libzfs_iter.c @@ -22,6 +22,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2010 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -110,6 +111,10 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data) if (zhp->zfs_type != ZFS_TYPE_FILESYSTEM) return (0); + if (zhp->zfs_hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(zhp->zfs_hdl, &zc) != 0) + return (-1); + if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); @@ -120,9 +125,8 @@ zfs_iter_filesystems(zfs_handle_t *zhp, zfs_iter_f func, void *data) * that the pool has since been removed. */ if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, - &zc)) == NULL) { + &zc)) == NULL) continue; - } if ((ret = func(nzhp, data)) != 0) { zcmd_free_nvlists(&zc); @@ -146,15 +150,19 @@ zfs_iter_snapshots(zfs_handle_t *zhp, zfs_iter_f func, void *data) if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) return (0); + if (zhp->zfs_hdl->libzfs_cachedprops && + libzfs_cmd_set_cachedprops(zhp->zfs_hdl, &zc) != 0) + return (-1); + if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0) return (-1); + while ((ret = zfs_do_list_ioctl(zhp, ZFS_IOC_SNAPSHOT_LIST_NEXT, &zc)) == 0) { if ((nzhp = make_dataset_handle_zc(zhp->zfs_hdl, - &zc)) == NULL) { + &zc)) == NULL) continue; - } if ((ret = func(nzhp, data)) != 0) { zcmd_free_nvlists(&zc); diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c index 1c6fb371e3..8315e1404b 100644 --- a/usr/src/lib/libzfs/common/libzfs_pool.c +++ b/usr/src/lib/libzfs/common/libzfs_pool.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. */ #include <ctype.h> @@ -211,7 +212,7 @@ zpool_state_to_name(vdev_state_t state, vdev_aux_t aux) */ int zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, - zprop_source_t *srctype) + zprop_source_t *srctype, boolean_t literal) { uint64_t intval; const char *strval; @@ -271,6 +272,12 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, case PROP_TYPE_NUMBER: intval = zpool_get_prop_int(zhp, prop, &src); + if (literal && prop != ZPOOL_PROP_HEALTH) { + (void) snprintf(buf, len, "%llu", + (u_longlong_t)intval); + break; + } + switch (prop) { case ZPOOL_PROP_SIZE: case ZPOOL_PROP_ALLOCATED: @@ -310,6 +317,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpool_prop_t prop, char *buf, size_t len, default: (void) snprintf(buf, len, "%llu", intval); } + break; case PROP_TYPE_INDEX: @@ -376,7 +384,7 @@ zpool_is_bootable(zpool_handle_t *zhp) char bootfs[ZPOOL_MAXNAMELEN]; return (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs, - sizeof (bootfs), NULL) == 0 && strncmp(bootfs, "-", + sizeof (bootfs), NULL, B_FALSE) == 0 && strncmp(bootfs, "-", sizeof (bootfs)) != 0); } @@ -774,7 +782,7 @@ zpool_expand_proplist(zpool_handle_t *zhp, zprop_list_t **plp) if (entry->pl_prop != ZPROP_INVAL && zpool_get_prop(zhp, entry->pl_prop, buf, sizeof (buf), - NULL) == 0) { + NULL, B_FALSE) == 0) { if (strlen(buf) > entry->pl_width) entry->pl_width = strlen(buf); } @@ -3974,9 +3982,7 @@ supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf) uint_t children, c; verify(nvlist_lookup_string(config, ZPOOL_CONFIG_TYPE, &type) == 0); - if (strcmp(type, VDEV_TYPE_RAIDZ) == 0 || - strcmp(type, VDEV_TYPE_FILE) == 0 || - strcmp(type, VDEV_TYPE_LOG) == 0 || + if (strcmp(type, VDEV_TYPE_FILE) == 0 || strcmp(type, VDEV_TYPE_HOLE) == 0 || strcmp(type, VDEV_TYPE_MISSING) == 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, @@ -3995,8 +4001,12 @@ supported_dump_vdev_type(libzfs_handle_t *hdl, nvlist_t *config, char *errbuf) } /* - * check if this zvol is allowable for use as a dump device; zero if - * it is, > 0 if it isn't, < 0 if it isn't a zvol + * Check if this zvol is allowable for use as a dump device; zero if + * it is, > 0 if it isn't, < 0 if it isn't a zvol. + * + * Allowable storage configurations include mirrors, all raidz variants, and + * pools with log, cache, and spare devices. Pools which are backed by files or + * have missing/hole vdevs are not suitable. */ int zvol_check_dump_config(char *arg) @@ -4058,12 +4068,6 @@ zvol_check_dump_config(char *arg) verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &top, &toplevels) == 0); - if (toplevels != 1) { - zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, - "'%s' has multiple top level vdevs"), poolname); - (void) zfs_error(hdl, EZFS_DEVOVERFLOW, errbuf); - goto out; - } if (!supported_dump_vdev_type(hdl, top[0], errbuf)) { goto out; diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c index 41e25e9100..8706a6fdbb 100644 --- a/usr/src/lib/libzfs/common/libzfs_util.c +++ b/usr/src/lib/libzfs/common/libzfs_util.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2012 by Delphix. All rights reserved. */ @@ -81,6 +82,9 @@ libzfs_error_description(libzfs_handle_t *hdl) return (dgettext(TEXT_DOMAIN, "property cannot be inherited")); case EZFS_PROPSPACE: return (dgettext(TEXT_DOMAIN, "invalid quota or reservation")); + case EZFS_PROPCACHED: + return (dgettext(TEXT_DOMAIN, "property unavailable since " + "cachedprops flag set")); case EZFS_BADTYPE: return (dgettext(TEXT_DOMAIN, "operation not applicable to " "datasets of this type")); @@ -609,6 +613,42 @@ libzfs_print_on_error(libzfs_handle_t *hdl, boolean_t printerr) hdl->libzfs_printerr = printerr; } +/* + * Set the value of the cachedprops flag. If the cachedprops flag is set, + * operations which get ZFS properties will only retrieve a property if the + * property is cached somewhere in memory. + * + * Consumers of libzfs should take care when setting this flag, as they will + * prevent themselves from listing the full set of ZFS properties. + * + * ZFS properties which always require disk I/O are ZPL properties (utf8only, + * normalization, etc.) and the volsize and volblocksize properties for volumes. + */ +void +libzfs_set_cachedprops(libzfs_handle_t *hdl, boolean_t cachedprops) +{ + hdl->libzfs_cachedprops = cachedprops; +} + +/* + * Adds a src nvlist to a zfs_cmd_t which specifies that only cached (i.e., will + * not require a disk access) properties should be retrieved. + */ +int +libzfs_cmd_set_cachedprops(libzfs_handle_t *hdl, zfs_cmd_t *zc) +{ + nvlist_t *nvl; + int ret; + + if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 || + nvlist_add_boolean_value(nvl, "cachedpropsonly", B_TRUE) != 0) + return (no_memory(hdl)); + + ret = zcmd_write_src_nvlist(hdl, zc, nvl); + nvlist_free(nvl); + return (ret); +} + libzfs_handle_t * libzfs_init(void) { @@ -644,6 +684,8 @@ libzfs_init(void) zpool_feature_init(); libzfs_mnttab_init(hdl); + hdl->libzfs_cachedprops = B_FALSE; + return (hdl); } diff --git a/usr/src/lib/libzfs/common/mapfile-vers b/usr/src/lib/libzfs/common/mapfile-vers index 1cc52f5f79..d2ce523cf8 100644 --- a/usr/src/lib/libzfs/common/mapfile-vers +++ b/usr/src/lib/libzfs/common/mapfile-vers @@ -21,6 +21,7 @@ # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2011 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2012 by Delphix. All rights reserved. +# Copyright (c) 2012, Joyent, Inc. All rights reserved. # # MAPFILE HEADER START # @@ -59,6 +60,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { libzfs_init; libzfs_mnttab_cache; libzfs_print_on_error; + libzfs_set_cachedprops; spa_feature_table; zfs_allocatable_devs; zfs_asprintf; @@ -101,6 +103,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zfs_path_to_zhandle; zfs_promote; zfs_prop_align_right; + zfs_prop_cacheable; zfs_prop_column_name; zfs_prop_default_numeric; zfs_prop_default_string; diff --git a/usr/src/lib/libzonecfg/Makefile.com b/usr/src/lib/libzonecfg/Makefile.com index 4c94fe6dd6..ce29f58a9b 100644 --- a/usr/src/lib/libzonecfg/Makefile.com +++ b/usr/src/lib/libzonecfg/Makefile.com @@ -35,6 +35,7 @@ LDLIBS += -lc -lsocket -lnsl -luuid -lnvpair -lsysevent -lsec -lbrand \ $(DYNLIB) := LDLIBS += -lxml2 SRCDIR = ../common +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/libxml2 -I$(SRCDIR) -D_REENTRANT CPPFLAGS += -I/usr/include/libxml2 -I$(SRCDIR) -D_REENTRANT CERRWARN += -_gcc=-Wno-uninitialized CERRWARN += -_gcc=-Wno-parentheses diff --git a/usr/src/lib/libzonecfg/common/getzoneent.c b/usr/src/lib/libzonecfg/common/getzoneent.c index 8155f7272a..76664fcc92 100644 --- a/usr/src/lib/libzonecfg/common/getzoneent.c +++ b/usr/src/lib/libzonecfg/common/getzoneent.c @@ -403,14 +403,6 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation) */ if (ze->zone_state >= 0) { zone_state = zone_state_str(ze->zone_state); - - /* - * If the caller is uninstalling this zone, - * then wipe out the uuid. The zone's contents - * are no longer known. - */ - if (ze->zone_state < ZONE_STATE_INSTALLED) - zone_uuid = ""; } /* If a new name is supplied, use it. */ @@ -419,6 +411,12 @@ putzoneent(struct zoneent *ze, zoneent_op_t operation) if (ze->zone_path[0] != '\0') zone_path = ze->zone_path; + + /* If new UUID provided, replace it */ + if (!uuid_is_null(ze->zone_uuid)) { + uuid_unparse(ze->zone_uuid, uuidstr); + zone_uuid = uuidstr; + } break; case PZE_REMOVE: diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 9a664b8824..55e0e58c82 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, Joyent Inc. All rights reserved. */ #include <libsysevent.h> @@ -77,6 +78,8 @@ #define ZONE_EVENT_PING_SUBCLASS "ping" #define ZONE_EVENT_PING_PUBLISHER "solaris" +#define DEBUGID_FILE "/etc/zones/did.txt" + /* Hard-code the DTD element/attribute/entity names just once, here. */ #define DTD_ELEM_ATTR (const xmlChar *) "attr" #define DTD_ELEM_COMMENT (const xmlChar *) "comment" @@ -84,6 +87,7 @@ #define DTD_ELEM_FS (const xmlChar *) "filesystem" #define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption" #define DTD_ELEM_NET (const xmlChar *) "network" +#define DTD_ELEM_NETATTR (const xmlChar *) "net-attr" #define DTD_ELEM_RCTL (const xmlChar *) "rctl" #define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" #define DTD_ELEM_ZONE (const xmlChar *) "zone" @@ -103,10 +107,12 @@ #define DTD_ATTR_IPTYPE (const xmlChar *) "ip-type" #define DTD_ATTR_DEFROUTER (const xmlChar *) "defrouter" #define DTD_ATTR_DIR (const xmlChar *) "directory" +#define DTD_ATTR_GNIC (const xmlChar *) "global-nic" #define DTD_ATTR_LIMIT (const xmlChar *) "limit" #define DTD_ATTR_LIMITPRIV (const xmlChar *) "limitpriv" #define DTD_ATTR_BOOTARGS (const xmlChar *) "bootargs" #define DTD_ATTR_SCHED (const xmlChar *) "scheduling-class" +#define DTD_ATTR_MAC (const xmlChar *) "mac-addr" #define DTD_ATTR_MATCH (const xmlChar *) "match" #define DTD_ATTR_NAME (const xmlChar *) "name" #define DTD_ATTR_PHYSICAL (const xmlChar *) "physical" @@ -116,6 +122,7 @@ #define DTD_ATTR_SPECIAL (const xmlChar *) "special" #define DTD_ATTR_TYPE (const xmlChar *) "type" #define DTD_ATTR_VALUE (const xmlChar *) "value" +#define DTD_ATTR_VLANID (const xmlChar *) "vlan-id" #define DTD_ATTR_ZONEPATH (const xmlChar *) "zonepath" #define DTD_ATTR_NCPU_MIN (const xmlChar *) "ncpu_min" #define DTD_ATTR_NCPU_MAX (const xmlChar *) "ncpu_max" @@ -128,6 +135,7 @@ #define DTD_ATTR_MODE (const xmlChar *) "mode" #define DTD_ATTR_ACL (const xmlChar *) "acl" #define DTD_ATTR_BRAND (const xmlChar *) "brand" +#define DTD_ATTR_DID (const xmlChar *) "debugid" #define DTD_ATTR_HOSTID (const xmlChar *) "hostid" #define DTD_ATTR_USER (const xmlChar *) "user" #define DTD_ATTR_AUTHS (const xmlChar *) "auths" @@ -174,9 +182,12 @@ static struct alias { {ALIAS_MAXSEMIDS, "zone.max-sem-ids", "privileged", "deny", 0}, {ALIAS_MAXLOCKEDMEM, "zone.max-locked-memory", "privileged", "deny", 0}, {ALIAS_MAXSWAP, "zone.max-swap", "privileged", "deny", 0}, + {ALIAS_MAXPHYSMEM, "zone.max-physical-memory", "privileged", "deny", + 1048576}, {ALIAS_SHARES, "zone.cpu-shares", "privileged", "none", 0}, {ALIAS_CPUCAP, "zone.cpu-cap", "privileged", "deny", 0}, {ALIAS_MAXPROCS, "zone.max-processes", "privileged", "deny", 100}, + {ALIAS_ZFSPRI, "zone.zfs-io-priority", "privileged", "none", 1}, {NULL, NULL, NULL, NULL, 0} }; @@ -2064,6 +2075,32 @@ zonecfg_ifname_exists(sa_family_t af, char *ifname) } /* + * Turn an addr that looks like f:2:0:44:5:6C into 0f:02:00:44:05:6c + * We're expecting a dst of at least MAXMACADDRLEN size here. + */ +static void +normalize_mac_addr(char *dst, const char *src, int len) +{ + char *p, *e, *sep = ""; + long n; + char buf[MAXMACADDRLEN], tmp[4]; + + *dst = '\0'; + (void) strlcpy(buf, src, sizeof (buf)); + p = strtok(buf, ":"); + while (p != NULL) { + n = strtol(p, &e, 16); + if (*e != NULL || n > 0xff) + return; + (void) snprintf(tmp, sizeof (tmp), "%s%02x", sep, n); + (void) strlcat(dst, tmp, len); + + sep = ":"; + p = strtok(NULL, ":"); + } +} + +/* * Determines whether there is a net resource with the physical interface, IP * address, and default router specified by 'tabptr' in the zone configuration * to which 'handle' refers. 'tabptr' must have an interface, an address, a @@ -2082,13 +2119,18 @@ zonecfg_ifname_exists(sa_family_t af, char *ifname) int zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { - xmlNodePtr cur; + xmlNodePtr cur, val; xmlNodePtr firstmatch; int err; char address[INET6_ADDRSTRLEN]; char physical[LIFNAMSIZ]; + char mac[MAXMACADDRLEN]; + char norm_mac[MAXMACADDRLEN]; + char gnic[LIFNAMSIZ]; size_t addrspec; /* nonzero if tabptr has IP addr */ size_t physspec; /* nonzero if tabptr has interface */ + size_t macspec; /* nonzero if tabptr has mac addr */ + size_t gnicspec; /* nonzero if tabptr has gnic */ size_t defrouterspec; /* nonzero if tabptr has def. router */ size_t allowed_addrspec; zone_iptype_t iptype; @@ -2100,17 +2142,20 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) * Determine the fields that will be searched. There must be at least * one. * - * zone_nwif_address, zone_nwif_physical, and zone_nwif_defrouter are + * zone_nwif_address, zone_nwif_physical, zone_nwif_defrouter, + * zone_nwif_mac, zone_nwif_vlan_id and zone_nwif_gnic are * arrays, so no NULL checks are necessary. */ addrspec = strlen(tabptr->zone_nwif_address); physspec = strlen(tabptr->zone_nwif_physical); + macspec = strlen(tabptr->zone_nwif_mac); + gnicspec = strlen(tabptr->zone_nwif_gnic); defrouterspec = strlen(tabptr->zone_nwif_defrouter); allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address); if (addrspec != 0 && allowed_addrspec != 0) return (Z_INVAL); /* can't specify both */ if (addrspec == 0 && physspec == 0 && defrouterspec == 0 && - allowed_addrspec == 0) + allowed_addrspec == 0 && macspec == 0 && gnicspec == 0) return (Z_INSUFFICIENT_SPEC); if ((err = operation_prep(handle)) != Z_OK) @@ -2137,6 +2182,19 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) physical, sizeof (physical)) != Z_OK || strcmp(tabptr->zone_nwif_physical, physical) != 0)) continue; + if (iptype == ZS_EXCLUSIVE && macspec != 0) { + if (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) != + Z_OK) + continue; + normalize_mac_addr(norm_mac, mac, sizeof (norm_mac)); + if (strcmp(tabptr->zone_nwif_mac, norm_mac) != 0) + continue; + } + if (iptype == ZS_EXCLUSIVE && gnicspec != 0 && + (fetchprop(cur, DTD_ATTR_GNIC, gnic, + sizeof (gnic)) != Z_OK || + strcmp(tabptr->zone_nwif_gnic, gnic) != 0)) + continue; if (iptype == ZS_SHARED && addrspec != 0 && (fetchprop(cur, DTD_ATTR_ADDRESS, address, sizeof (address)) != Z_OK || @@ -2179,6 +2237,21 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) return (err); if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && (err = fetchprop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address, sizeof (tabptr->zone_nwif_allowed_address))) != Z_OK) @@ -2189,13 +2262,40 @@ zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) return (err); + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { - xmlNodePtr newnode, cur = handle->zone_dh_cur; + xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; + struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); @@ -2211,13 +2311,40 @@ zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) tabptr->zone_nwif_physical)) != Z_OK) return (err); /* - * Do not add this property when it is not set, for backwards - * compatibility and because it is optional. + * Do not add these properties when they are not set, for backwards + * compatibility and because they are optional. */ if ((strlen(tabptr->zone_nwif_defrouter) > 0) && ((err = newprop(newnode, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter)) != Z_OK)) return (err); + if (strlen(tabptr->zone_nwif_mac) > 0 && + (err = newprop(newnode, DTD_ATTR_MAC, + tabptr->zone_nwif_mac)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_vlan_id) > 0 && + (err = newprop(newnode, DTD_ATTR_VLANID, + tabptr->zone_nwif_vlan_id)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_gnic) > 0 && + (err = newprop(newnode, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic)) != Z_OK) + return (err); + + for (valptr = tabptr->zone_nwif_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + return (Z_OK); } @@ -2242,7 +2369,8 @@ static int zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { xmlNodePtr cur = handle->zone_dh_cur; - boolean_t addr_match, phys_match, allowed_addr_match; + boolean_t addr_match, phys_match, allowed_addr_match, mac_match, + gnic_match; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_NET)) @@ -2254,8 +2382,13 @@ zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) tabptr->zone_nwif_allowed_address); phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical); + mac_match = match_prop(cur, DTD_ATTR_MAC, + tabptr->zone_nwif_mac); + gnic_match = match_prop(cur, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic); - if ((addr_match || allowed_addr_match) && phys_match) { + if ((addr_match || allowed_addr_match || mac_match || + gnic_match) && phys_match) { xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); @@ -2304,6 +2437,58 @@ zonecfg_modify_nwif( return (Z_OK); } +void +zonecfg_free_res_attr_list(struct zone_res_attrtab *valtab) +{ + if (valtab == NULL) + return; + zonecfg_free_res_attr_list(valtab->zone_res_attr_next); + free(valtab); +} + +int +zonecfg_add_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) +{ + struct zone_res_attrtab *last, *old, *new; + + last = *headptr; + for (old = last; old != NULL; old = old->zone_res_attr_next) + last = old; /* walk to the end of the list */ + new = valtabptr; /* alloc'd by caller */ + new->zone_res_attr_next = NULL; + if (last == NULL) + *headptr = new; + else + last->zone_res_attr_next = new; + return (Z_OK); +} + +int +zonecfg_remove_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) +{ + struct zone_res_attrtab *last, *this, *next; + + last = *headptr; + for (this = last; this != NULL; this = this->zone_res_attr_next) { + if (strcmp(this->zone_res_attr_name, + valtabptr->zone_res_attr_name) == 0 && + strcmp(this->zone_res_attr_value, + valtabptr->zone_res_attr_value) == 0) { + next = this->zone_res_attr_next; + if (this == *headptr) + *headptr = next; + else + last->zone_res_attr_next = next; + free(this); + return (Z_OK); + } else + last = this; + } + return (Z_NO_PROPERTY_ID); +} + /* * Must be a comma-separated list of alpha-numeric file system names. */ @@ -2453,7 +2638,7 @@ zonecfg_set_hostid(zone_dochandle_t handle, const char *hostidp) int zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) { - xmlNodePtr cur, firstmatch; + xmlNodePtr cur, val, firstmatch; int err; char match[MAXPATHLEN]; @@ -2498,13 +2683,40 @@ zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) sizeof (tabptr->zone_dev_match))) != Z_OK) return (err); + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { - xmlNodePtr newnode, cur = handle->zone_dh_cur; + xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; + struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); @@ -2513,6 +2725,21 @@ zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) tabptr->zone_dev_match)) != Z_OK) return (err); + for (valptr = tabptr->zone_dev_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + + return (Z_OK); } @@ -4572,7 +4799,7 @@ get_pool_sched_class(char *poolname, char *class, int clsize) pool_conf_t *poolconf; pool_t *pool; pool_elem_t *pe; - pool_value_t *pv = pool_value_alloc(); + pool_value_t *pv; const char *sched_str; if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED) @@ -4593,15 +4820,23 @@ get_pool_sched_class(char *poolname, char *class, int clsize) return (Z_NO_POOL); } + if ((pv = pool_value_alloc()) == NULL) { + (void) pool_conf_close(poolconf); + pool_conf_free(poolconf); + return (Z_NO_POOL); + } + pe = pool_to_elem(poolconf, pool); if (pool_get_property(poolconf, pe, "pool.scheduler", pv) != POC_STRING) { (void) pool_conf_close(poolconf); + pool_value_free(pv); pool_conf_free(poolconf); return (Z_NO_ENTRY); } (void) pool_value_get_string(pv, &sched_str); (void) pool_conf_close(poolconf); + pool_value_free(pv); pool_conf_free(poolconf); if (strlcpy(class, sched_str, clsize) >= clsize) return (Z_TOO_BIG); @@ -4710,7 +4945,8 @@ zonecfg_setnwifent(zone_dochandle_t handle) int zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { - xmlNodePtr cur; + xmlNodePtr cur, val; + struct zone_res_attrtab *valptr; int err; if (handle == NULL) @@ -4746,6 +4982,24 @@ zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) return (err); } + if ((err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) { @@ -4753,6 +5007,29 @@ zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) return (err); } + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if (fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK) + break; + if (fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } @@ -4772,7 +5049,7 @@ zonecfg_setdevent(zone_dochandle_t handle) int zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) { - xmlNodePtr cur; + xmlNodePtr cur, val; int err; if (handle == NULL) @@ -4795,6 +5072,31 @@ zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) return (err); } + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } @@ -5523,6 +5825,164 @@ zone_get_brand(char *zone_name, char *brandname, size_t rp_sz) } /* + * Atomically get a new zone_did value. The currently allocated value + * is stored in /etc/zones/did.txt. Lock the file, read the current value, + * increment, save the new value and unlock the file. Return the new value + * or -1 if there was an error. The ID namespace is large enough that we + * don't worry about recycling an ID when a zone is deleted. + */ +static zoneid_t +new_zone_did() +{ + int fd; + int len; + int val; + struct flock lck; + char buf[80]; + + if ((fd = open(DEBUGID_FILE, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + perror("new_zone_did open failed"); + return (-1); + } + + /* Initialize the lock. */ + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = 0; + + /* Wait until we acquire an exclusive lock on the file. */ + lck.l_type = F_WRLCK; + if (fcntl(fd, F_SETLKW, &lck) == -1) { + perror("new_zone_did lock failed"); + (void) close(fd); + return (-1); + } + + /* Get currently allocated value */ + len = read(fd, buf, sizeof (buf)); + if (len == -1) { + perror("new_zone_did read failed"); + val = -1; + } else { + if (lseek(fd, 0L, SEEK_SET) == -1) { + perror("new_zone_did seek failed"); + val = -1; + } else { + if (len == 0) { + /* Just created the file, initialize at 1 */ + val = 1; + } else { + val = atoi(buf); + val++; + } + + (void) snprintf(buf, sizeof (buf), "%d\n", val); + len = strlen(buf); + + /* Save newly allocated value */ + if (write(fd, buf, len) == -1) { + perror("new_zone_did write failed"); + val = -1; + } + } + } + + /* Release the file lock. */ + lck.l_type = F_UNLCK; + if (fcntl(fd, F_SETLK, &lck) == -1) { + perror("new_zone_did unlock failed"); + val = -1; + } + + if (close(fd) != 0) + perror("new_zone_did close failed"); + + return (val); +} + +/* + * Called by zoneadmd to get the zone's debug ID. + * If the zone doesn't already have an ID, a new one is generated and + * persistently saved onto the zone. Normally either zoneadm or zonecfg + * will assign a new ID for the zone, so zoneadmd should never have to + * generate one, but we also handle that here just to be paranoid. + */ +zoneid_t +zone_get_did(char *zone_name) +{ + int res; + zoneid_t new_did; + zone_dochandle_t handle; + char did_str[80]; + + if ((handle = zonecfg_init_handle()) == NULL) + return (getpid()); + + if (zonecfg_get_handle((char *)zone_name, handle) != Z_OK) + return (getpid()); + + res = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + + /* If the zone already has an assigned debug ID, return it. */ + if (res == Z_OK && did_str[0] != '\0') { + zonecfg_fini_handle(handle); + return (atoi(did_str)); + } + + /* + * The zone doesn't have an assigned debug ID yet, generate one and + * save it as part of the zone definition. + */ + if ((new_did = new_zone_did()) == -1) { + /* + * We should really never hit this block of code. + * Generating a new ID failed for some reason. Use the current + * pid as a temporary ID so that the zone can continue to boot + * but we don't persistently save this temporary ID on the zone. + */ + zonecfg_fini_handle(handle); + return (getpid()); + } + + /* Now persistently save this new ID onto the zone. */ + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); + (void) zonecfg_save(handle); + + zonecfg_fini_handle(handle); + return (new_did); +} + +zoneid_t +zonecfg_get_did(zone_dochandle_t handle) +{ + char did_str[80]; + int err; + zoneid_t did; + + err = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + if (err == Z_OK && did_str[0] != '\0') + did = atoi(did_str); + else + did = -1; + + return (did); +} + +void +zonecfg_set_did(zone_dochandle_t handle) +{ + zoneid_t new_did; + char did_str[80]; + + if ((new_did = new_zone_did()) == -1) + return; + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); +} + +/* * Return the appropriate root for the active /dev. * For normal zone, the path is $ZONEPATH/root; * for scratch zone, the dev path is $ZONEPATH/lu. @@ -5805,6 +6265,30 @@ zonecfg_get_uuid(const char *zonename, uuid_t uuid) } /* + * Changes a zone's UUID to the given value. Returns an error if the UUID is + * malformed or if the zone cannot be located. + */ +int +zonecfg_set_uuid(const char *zonename, const char *zonepath, + const char *uuid) +{ + int err; + struct zoneent ze; + + bzero(&ze, sizeof (ze)); + ze.zone_state = -1; /* Preserve existing state in index */ + (void) strlcpy(ze.zone_name, zonename, sizeof (ze.zone_name)); + (void) strlcpy(ze.zone_path, zonepath, sizeof (ze.zone_path)); + if (uuid_parse((char *)uuid, ze.zone_uuid) == -1) + return (Z_INVALID_PROPERTY); + + if ((err = putzoneent(&ze, PZE_MODIFY)) != Z_OK) + return (err); + + return (Z_OK); +} + +/* * File-system convenience functions. */ boolean_t @@ -6838,131 +7322,49 @@ zonecfg_getpsetent(zone_dochandle_t handle, struct zone_psettab *tabptr) return (err); } -static int -add_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) -{ - xmlNodePtr newnode, cur = handle->zone_dh_cur; - int err; - - newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_MCAP, NULL); - if ((err = newprop(newnode, DTD_ATTR_PHYSCAP, tabptr->zone_physmem_cap)) - != Z_OK) - return (err); - - return (Z_OK); -} - -int -zonecfg_delete_mcap(zone_dochandle_t handle) -{ - int err; - xmlNodePtr cur = handle->zone_dh_cur; - - if ((err = operation_prep(handle)) != Z_OK) - return (err); - - for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { - if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0) - continue; - - xmlUnlinkNode(cur); - xmlFreeNode(cur); - return (Z_OK); - } - return (Z_NO_RESOURCE_ID); -} - -int -zonecfg_modify_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) -{ - int err; - - if (tabptr == NULL) - return (Z_INVAL); - - err = zonecfg_delete_mcap(handle); - /* it is ok if there is no mcap entry */ - if (err != Z_OK && err != Z_NO_RESOURCE_ID) - return (err); - - if ((err = add_mcap(handle, tabptr)) != Z_OK) - return (err); - - return (Z_OK); -} - +/* + * Cleanup obsolete constructs in the configuration. + * Return true of the config has been updated and must be commited. + */ int -zonecfg_lookup_mcap(zone_dochandle_t handle, struct zone_mcaptab *tabptr) +zonecfg_fix_obsolete(zone_dochandle_t handle) { + int res = 0; + int add_physmem_rctl = 0; xmlNodePtr cur; - int err; - - if (tabptr == NULL) - return (Z_INVAL); + char zone_physmem_cap[MAXNAMELEN]; - if ((err = operation_prep(handle)) != Z_OK) - return (err); + if (operation_prep(handle) != Z_OK) + return (res); + /* + * If an obsolete mcap entry exists, convert it to the rctl. + */ cur = handle->zone_dh_cur; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) != 0) continue; - if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP, - tabptr->zone_physmem_cap, - sizeof (tabptr->zone_physmem_cap))) != Z_OK) { - handle->zone_dh_cur = handle->zone_dh_top; - return (err); + + if (fetchprop(cur, DTD_ATTR_PHYSCAP, + zone_physmem_cap, sizeof (zone_physmem_cap)) == Z_OK) { + res = 1; + add_physmem_rctl = 1; } - return (Z_OK); + xmlUnlinkNode(cur); + xmlFreeNode(cur); + break; } - return (Z_NO_ENTRY); -} - -static int -getmcapent_core(zone_dochandle_t handle, struct zone_mcaptab *tabptr) -{ - xmlNodePtr cur; - int err; - - if (handle == NULL) - return (Z_INVAL); - - if ((cur = handle->zone_dh_cur) == NULL) - return (Z_NO_ENTRY); - - for (; cur != NULL; cur = cur->next) - if (xmlStrcmp(cur->name, DTD_ELEM_MCAP) == 0) - break; - if (cur == NULL) { - handle->zone_dh_cur = handle->zone_dh_top; - return (Z_NO_ENTRY); - } + if (add_physmem_rctl) { + uint64_t cap; + char *endp; - if ((err = fetchprop(cur, DTD_ATTR_PHYSCAP, tabptr->zone_physmem_cap, - sizeof (tabptr->zone_physmem_cap))) != Z_OK) { - handle->zone_dh_cur = handle->zone_dh_top; - return (err); + cap = strtoull(zone_physmem_cap, &endp, 10); + (void) zonecfg_set_aliased_rctl(handle, ALIAS_MAXPHYSMEM, cap); } - handle->zone_dh_cur = cur->next; - return (Z_OK); -} - -int -zonecfg_getmcapent(zone_dochandle_t handle, struct zone_mcaptab *tabptr) -{ - int err; - - if ((err = zonecfg_setent(handle)) != Z_OK) - return (err); - - err = getmcapent_core(handle, tabptr); - - (void) zonecfg_endent(handle); - - return (err); + return (res); } /* diff --git a/usr/src/lib/libzonecfg/common/mapfile-vers b/usr/src/lib/libzonecfg/common/mapfile-vers index b908a28174..7265b06a1f 100644 --- a/usr/src/lib/libzonecfg/common/mapfile-vers +++ b/usr/src/lib/libzonecfg/common/mapfile-vers @@ -20,6 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, Joyent Inc. All rights reserved. # # @@ -53,6 +54,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_add_fs_option; zonecfg_add_admin; zonecfg_add_nwif; + zonecfg_add_res_attr; zonecfg_add_pkg; zonecfg_add_pset; zonecfg_add_rctl; @@ -79,7 +81,6 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_delete_dev; zonecfg_delete_ds; zonecfg_delete_filesystem; - zonecfg_delete_mcap; zonecfg_delete_nwif; zonecfg_delete_pset; zonecfg_delete_rctl; @@ -104,7 +105,9 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_find_mounts; zonecfg_find_scratch; zonecfg_fini_handle; + zonecfg_fix_obsolete; zonecfg_free_fs_option_list; + zonecfg_free_res_attr_list; zonecfg_free_rctl_value_list; zonecfg_get_aliased_rctl; zonecfg_get_attach_handle; @@ -118,6 +121,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_get_bootargs; zonecfg_get_brand; zonecfg_get_dflt_sched_class; + zonecfg_get_did; zonecfg_getdevent; zonecfg_getdevperment; zonecfg_getdsent; @@ -127,7 +131,6 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_get_hostid; zonecfg_get_iptype; zonecfg_get_limitpriv; - zonecfg_getmcapent; zonecfg_get_name; zonecfg_get_name_by_uuid; zonecfg_getnwifent; @@ -160,7 +163,6 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_lookup_dev; zonecfg_lookup_ds; zonecfg_lookup_filesystem; - zonecfg_lookup_mcap; zonecfg_lookup_nwif; zonecfg_lookup_pset; zonecfg_lookup_rctl; @@ -169,7 +171,6 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_modify_dev; zonecfg_modify_ds; zonecfg_modify_filesystem; - zonecfg_modify_mcap; zonecfg_modify_nwif; zonecfg_modify_pset; zonecfg_modify_rctl; @@ -183,6 +184,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_ping_zoneadmd; zonecfg_release_lock_file; zonecfg_remove_fs_option; + zonecfg_remove_res_attr; zonecfg_remove_rctl_value; zonecfg_remove_userauths; zonecfg_reverse_scratch; @@ -196,6 +198,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_set_autoboot; zonecfg_set_bootargs; zonecfg_set_brand; + zonecfg_set_did; zonecfg_setdevent; zonecfg_setdevperment; zonecfg_setdsent; @@ -211,6 +214,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_set_root; zonecfg_set_sched; zonecfg_set_swinv; + zonecfg_set_uuid; zonecfg_set_zonepath; zonecfg_strerror; zonecfg_str_to_bytes; @@ -229,6 +233,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { zonecfg_verify_save; zonecfg_warn_poold; zone_get_brand; + zone_get_did; zone_get_devroot; zone_get_id; zone_get_rootpath; diff --git a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 index d94bb09c5f..3c7198efef 100644 --- a/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 +++ b/usr/src/lib/libzonecfg/dtd/zonecfg.dtd.1 @@ -21,6 +21,7 @@ CDDL HEADER END Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, Joyent Inc. All rights reserved. --> @@ -46,14 +47,21 @@ <!ATTLIST inherited-pkg-dir directory CDATA #REQUIRED> -<!ELEMENT network EMPTY> +<!ELEMENT net-attr EMPTY> +<!ATTLIST net-attr name CDATA #REQUIRED + value CDATA #REQUIRED> + +<!ELEMENT network (net-attr)*> <!ATTLIST network address CDATA "" allowed-address CDATA "" defrouter CDATA "" - physical CDATA #REQUIRED> + global-nic CDATA "" + mac-addr CDATA "" + physical CDATA #REQUIRED + vlan-id CDATA ""> -<!ELEMENT device EMPTY> +<!ELEMENT device (net-attr)*> <!ATTLIST device match CDATA #REQUIRED> @@ -156,6 +164,7 @@ limitpriv CDATA "" bootargs CDATA "" brand CDATA "" + debugid CDATA "" scheduling-class CDATA "" fs-allowed CDATA "" version NMTOKEN #FIXED '1'> diff --git a/usr/src/lib/lvm/libsvm/Makefile.com b/usr/src/lib/lvm/libsvm/Makefile.com index 7df4a4b39f..2457a10b69 100644 --- a/usr/src/lib/lvm/libsvm/Makefile.com +++ b/usr/src/lib/lvm/libsvm/Makefile.com @@ -46,7 +46,7 @@ LDLIBS += -lmeta -ldevid -lc # XXX There isn't a lint library for libspmicommon. For now, we work # around this by only using the library when we build (as opposed to lint). # -all debug install := LDLIBS += -L/usr/snadm/lib -lspmicommon +all debug install := LDLIBS += -L$(ADJUNCT_PROTO)/usr/snadm/lib -lspmicommon DYNFLAGS += -R/usr/snadm/lib CPPFLAGS += -D_FILE_OFFSET_BITS=64 diff --git a/usr/src/lib/pkcs11/pkcs11_tpm/Makefile.com b/usr/src/lib/pkcs11/pkcs11_tpm/Makefile.com index 22082a1fb8..323f311dec 100644 --- a/usr/src/lib/pkcs11/pkcs11_tpm/Makefile.com +++ b/usr/src/lib/pkcs11/pkcs11_tpm/Makefile.com @@ -66,14 +66,14 @@ ROOTLIBDIR64=$(ROOT)/usr/lib/security/$(MACH64) LIBS=$(DYNLIB) $(DYNLIB64) -TSSROOT= +TSSROOT=$(ADJUNCT_PROTO) TSPILIBDIR=$(TSSROOT)/usr/lib TSPIINCDIR=$(TSSROOT)/usr/include TSSLIB=-L$(TSPILIBDIR) TSSLIB64=-L$(TSPILIBDIR)/$(MACH64) TSSINC=-I$(TSPIINCDIR) -LDLIBS += $(TSSLIB) -L/lib -lc -luuid -lmd -ltspi -lcrypto +LDLIBS += $(TSSLIB) -L$(ADJUNCT_PROTO)/lib -lc -luuid -lmd -ltspi -lcrypto CPPFLAGS += -xCC -D_POSIX_PTHREAD_SEMANTICS $(TSSINC) CPPFLAGS64 += $(CPPFLAGS) C99MODE= $(C99_ENABLE) diff --git a/usr/src/lib/policykit/Makefile.policykit b/usr/src/lib/policykit/Makefile.policykit index 8b8cff0fe1..eca0c0d026 100644 --- a/usr/src/lib/policykit/Makefile.policykit +++ b/usr/src/lib/policykit/Makefile.policykit @@ -29,8 +29,11 @@ POLICYKIT_VERSION = 0.2 -POLICYKIT_DBUS_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -POLICYKIT_GLIB_CPPFLAGS = -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include +POLICYKIT_DBUS_CPPFLAGS = -DDBUS_API_SUBJECT_TO_CHANGE \ + -I$(ADJUNCT_PROTO)/usr/include/dbus-1.0 \ + -I$(ADJUNCT_PROTO)/usr/lib/dbus-1.0/include +POLICYKIT_GLIB_CPPFLAGS = -I$(ADJUNCT_PROTO)/usr/include/glib-2.0 \ + -I$(ADJUNCT_PROTO)/usr/lib/glib-2.0/include POLICYKIT_DBUS_LDLIBS = -ldbus-1 POLICYKIT_GLIB_LDLIBS = -lglib-2.0 diff --git a/usr/src/lib/print/Makefile b/usr/src/lib/print/Makefile deleted file mode 100644 index fd931373e8..0000000000 --- a/usr/src/lib/print/Makefile +++ /dev/null @@ -1,94 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -SUBDIRS = \ - libprint \ - libpapi-common \ - libpapi-dynamic \ - libpapi-lpd \ - libipp-core \ - libhttp-core \ - libpapi-ipp \ - libipp-listener \ - mod_ipp - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -install_h := TARGET = install_h -lint := TARGET = lint - -include $(SRC)/Makefile.master - -TEXT_DOMAIN= SUNW_OST_OSLIB -POFILE= print-lib.po - -.KEEP_STATE: - -all: $(TXTS) $(SUBDIRS) - -# -# Each message catalog file is generated in each sub -# directory and copied to the usr/src/cmd/lp/ directory. -# Those message catalog files are consolidated into one -# message catalog file. The consolidated one will be copied -# into the $(ROOT)/catalog/SUNW_OST_OSCMD/ directory. -# - -_msg: $(MSGDOMAIN) - @$(RM) $(POFILE) - $(XGETTEXT) -s `/bin/find . -type d -name SCCS -prune -o -type f -name '*.c' -print` - @/bin/cat messages.po | sed '/domain/d' > $(POFILE) - @$(RM) messages.po - $(RM) $(MSGDOMAIN)/$(POFILE) - /bin/cp $(POFILE) $(MSGDOMAIN) - -install: $(ROOTDIRS) $(ROOTSYMLINKDIRS) $(SUBDIRS) - -install_h clean strip lint: $(SUBDIRS) - -clobber: $(SUBDIRS) local_clobber - -local_clobber: - $(RM) $(CLOBBERFILES) $(POFILE) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include $(SRC)/Makefile.msg.targ - -# Dependencies -libpapi-dynamic: libpapi-common -libpapi-lpd: libpapi-dynamic -libipp-core: libpapi-common -libpapi-ipp: libpapi-common libipp-core libhttp-core -libipp-listener: libpapi-dynamic libipp-core -mod_ipp: libipp-listener - diff --git a/usr/src/lib/print/libhttp-core/Makefile b/usr/src/lib/print/libhttp-core/Makefile deleted file mode 100644 index b92d620b10..0000000000 --- a/usr/src/lib/print/libhttp-core/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) - -install_h: # $(ROOTHDRS) - -check: # $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/libhttp-core/Makefile.com b/usr/src/lib/print/libhttp-core/Makefile.com deleted file mode 100644 index cfb8ae8730..0000000000 --- a/usr/src/lib/print/libhttp-core/Makefile.com +++ /dev/null @@ -1,63 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = libhttp-core.a -VERS = .1 -OBJECTS = http-addr.o http-support.o http.o - -ROOTLIBDIR = $(ROOT)/usr/lib/print - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib/print -ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common - -MAPFILES = $(SRCDIR)/mapfile - -LDLIBS += -lsocket -lnsl -lc - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -$(ROOTLIBDIR): - $(INS.dir) - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libhttp-core/common/LICENSE.txt b/usr/src/lib/print/libhttp-core/common/LICENSE.txt deleted file mode 100644 index 797ee5db95..0000000000 --- a/usr/src/lib/print/libhttp-core/common/LICENSE.txt +++ /dev/null @@ -1,964 +0,0 @@ - Common UNIX Printing System License Agreement - - Copyright 1997-2006 by Easy Software Products - 44141 AIRPORT VIEW DR STE 204 - HOLLYWOOD, MARYLAND 20636 USA - - Voice: +1.301.373.9600 - Email: cups-info@cups.org - WWW: http://www.cups.org - - -INTRODUCTION - -The Common UNIX Printing System(tm), ("CUPS(tm)"), is provided -under the GNU General Public License ("GPL") and GNU Library -General Public License ("LGPL"), Version 2, with exceptions for -Apple operating systems and the OpenSSL toolkit. A copy of the -exceptions and licenses follow this introduction. - -The GNU LGPL applies to the CUPS API library, located in the -"cups" subdirectory of the CUPS source distribution and in the -"cups" include directory and library files in the binary -distributions. The GNU GPL applies to the remainder of the CUPS -distribution, including the "pdftops" filter which is based upon -Xpdf and the CUPS imaging library. - -For those not familiar with the GNU GPL, the license basically -allows you to: - - - Use the CUPS software at no charge. - - Distribute verbatim copies of the software in source or - binary form. - - Sell verbatim copies of the software for a media fee, or - sell support for the software. - - Distribute or sell printer drivers and filters that use - CUPS so long as source code is made available under the - GPL. - -What this license *does not* allow you to do is make changes or -add features to CUPS and then sell a binary distribution without -source code. You must provide source for any new drivers, -changes, or additions to the software, and all code must be -provided under the GPL or LGPL as appropriate. The only -exceptions to this are the portions of the CUPS software covered -by the Apple operating system license exceptions outlined later -in this license agreement. - -The GNU LGPL relaxes the "link-to" restriction, allowing you to -develop applications that use the CUPS API library under other -licenses and/or conditions as appropriate for your application. - - -LICENSE EXCEPTIONS - -In addition, as the copyright holder of CUPS, Easy Software -Products grants the following special exceptions: - - 1. Apple Operating System Development License Exception; - - a. Software that is developed by any person or entity - for an Apple Operating System ("Apple OS-Developed - Software"), including but not limited to Apple and - third party printer drivers, filters, and backends - for an Apple Operating System, that is linked to the - CUPS imaging library or based on any sample filters - or backends provided with CUPS shall not be - considered to be a derivative work or collective work - based on the CUPS program and is exempt from the - mandatory source code release clauses of the GNU GPL. - You may therefore distribute linked combinations of - the CUPS imaging library with Apple OS-Developed - Software without releasing the source code of the - Apple OS-Developed Software. You may also use sample - filters and backends provided with CUPS to develop - Apple OS-Developed Software without releasing the - source code of the Apple OS-Developed Software. - - b. An Apple Operating System means any operating system - software developed and/or marketed by Apple Computer, - Inc., including but not limited to all existing - releases and versions of Apple's Darwin, Mac OS X, - and Mac OS X Server products and all follow-on - releases and future versions thereof. - - c. This exception is only available for Apple - OS-Developed Software and does not apply to software - that is distributed for use on other operating - systems. - - d. All CUPS software that falls under this license - exception have the following text at the top of each - source file: - - This file is subject to the Apple OS-Developed - Software exception. - - 2. OpenSSL Toolkit License Exception; - - a. Easy Software Products explicitly allows the - compilation and distribution of the CUPS software - with the OpenSSL Toolkit. - -No developer is required to provide these exceptions in a -derived work. - - -TRADEMARKS - -Easy Software Products has trademarked the Common UNIX Printing -System, CUPS, and CUPS logo. You may use these names and logos -in any direct port or binary distribution of CUPS. Please -contact Easy Software Products for written permission to use -them in derivative products. Our intention is to protect the -value of these trademarks and ensure that any derivative product -meets the same high-quality standards as the original. - - -BINARY DISTRIBUTION RIGHTS - -Easy Software Products also sells rights to the CUPS source code -under a binary distribution license for vendors that are unable -to release source code for their drivers, additions, and -modifications to CUPS under the GNU GPL and LGPL. For -information please contact us at the address shown above. - -The Common UNIX Printing System provides a "pdftops" filter that -is based on the Xpdf software. For binary distribution licensing -of this software, please contact: - - Derek B. Noonburg - Email: derekn@glyphandcog.com - WWW: http://www.glyphandcog.com/ - - -SUPPORT - -Easy Software Products sells software support for CUPS as well -as a commercial printing product based on CUPS called ESP Print -Pro. You can find out more at our web site: - - http://www.easysw.com/ - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) 19yy <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - [This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/usr/src/lib/print/libhttp-core/common/LICENSE.txt.descrip b/usr/src/lib/print/libhttp-core/common/LICENSE.txt.descrip deleted file mode 100644 index 7c846a0987..0000000000 --- a/usr/src/lib/print/libhttp-core/common/LICENSE.txt.descrip +++ /dev/null @@ -1 +0,0 @@ -CUPS diff --git a/usr/src/lib/print/libhttp-core/common/debug.h b/usr/src/lib/print/libhttp-core/common/debug.h deleted file mode 100644 index aebc790017..0000000000 --- a/usr/src/lib/print/libhttp-core/common/debug.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $ - * - * Debugging macros for the Common UNIX Printing System (CUPS). - * - * Copyright 1997-2005 by Easy Software Products. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _CUPS_DEBUG_H_ -#define _CUPS_DEBUG_H_ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Include necessary headers... - */ - -# include <stdio.h> - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * The debug macros are used if you compile with DEBUG defined. - * - * Usage: - * - * DEBUG_puts("string") - * DEBUG_printf(("format string", arg, arg, ...)); - * - * Note the extra parenthesis around the DEBUG_printf macro... - */ - -# ifdef DEBUG -# define DEBUG_puts(x) puts(x) -# define DEBUG_printf(x) printf x -# else -# define DEBUG_puts(x) -# define DEBUG_printf(x) -# endif /* DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* !_CUPS_DEBUG_H_ */ - -/* - * End of "$Id: debug.h 148 2006-04-25 16:54:17Z njacobs $" - */ diff --git a/usr/src/lib/print/libhttp-core/common/http-addr.c b/usr/src/lib/print/libhttp-core/common/http-addr.c deleted file mode 100644 index a872d4d3fd..0000000000 --- a/usr/src/lib/print/libhttp-core/common/http-addr.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $" - * - * HTTP address routines for the Common UNIX Printing System (CUPS). - * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * Contents: - * - * httpAddrAny() - Check for the "any" address. - * httpAddrEqual() - Compare two addresses. - * httpAddrLoad() - Load a host entry address into an HTTP address. - * httpAddrLocalhost() - Check for the local loopback address. - * httpAddrLookup() - Lookup the hostname associated with the address. - * httpAddrString() - Convert an IP address to a dotted string. - * httpGetHostByName() - Lookup a hostname or IP address, and return - * address records for the specified name. - */ - -/* - * Include necessary headers... - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "http.h" -#include "debug.h" -#include "string.h" -#include <ctype.h> - - -/* - * 'httpAddrAny()' - Check for the "any" address. - */ - -int /* O - 1 if "any", 0 otherwise */ -httpAddrAny(const http_addr_t *addr) /* I - Address to check */ -{ -#ifdef AF_INET6 - if (addr->addr.sa_family == AF_INET6 && - IN6_IS_ADDR_UNSPECIFIED(&(addr->ipv6.sin6_addr))) - return (1); -#endif /* AF_INET6 */ - - if (addr->addr.sa_family == AF_INET && - ntohl(addr->ipv4.sin_addr.s_addr) == 0x00000000) - return (1); - - return (0); -} - - -/* - * 'httpAddrEqual()' - Compare two addresses. - */ - -int /* O - 1 if equal, 0 if != */ -httpAddrEqual(const http_addr_t *addr1, /* I - First address */ - const http_addr_t *addr2) /* I - Second address */ -{ - if (addr1->addr.sa_family != addr2->addr.sa_family) - return (0); - -#ifdef AF_INET6 - if (addr1->addr.sa_family == AF_INET6) - return (memcmp(&(addr1->ipv6.sin6_addr), &(addr2->ipv6.sin6_addr), 16) == 0); -#endif /* AF_INET6 */ - - return (addr1->ipv4.sin_addr.s_addr == addr2->ipv4.sin_addr.s_addr); -} - - -/* - * 'httpAddrLoad()' - Load a host entry address into an HTTP address. - */ - -void -httpAddrLoad(const struct hostent *host, /* I - Host entry */ - int port, /* I - Port number */ - int n, /* I - Index into host entry */ - http_addr_t *addr) /* O - Address to load */ -{ -#ifdef AF_INET6 - if (host->h_addrtype == AF_INET6) - { -# ifdef WIN32 - addr->ipv6.sin6_port = htons((u_short)port); -# else - addr->ipv6.sin6_port = htons(port); -# endif /* WIN32 */ - - memcpy((char *)&(addr->ipv6.sin6_addr), host->h_addr_list[n], - host->h_length); - addr->ipv6.sin6_family = AF_INET6; - } - else -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - if (host->h_addrtype == AF_LOCAL) - { - addr->un.sun_family = AF_LOCAL; - strlcpy(addr->un.sun_path, host->h_addr_list[n], sizeof(addr->un.sun_path)); - } - else -#endif /* AF_LOCAL */ - if (host->h_addrtype == AF_INET) - { -# ifdef WIN32 - addr->ipv4.sin_port = htons((u_short)port); -# else - addr->ipv4.sin_port = htons(port); -# endif /* WIN32 */ - - memcpy((char *)&(addr->ipv4.sin_addr), host->h_addr_list[n], - host->h_length); - addr->ipv4.sin_family = AF_INET; - } -} - - -/* - * 'httpAddrLocalhost()' - Check for the local loopback address. - */ - -int /* O - 1 if local host, 0 otherwise */ -httpAddrLocalhost(const http_addr_t *addr) - /* I - Address to check */ -{ -#ifdef AF_INET6 - if (addr->addr.sa_family == AF_INET6 && - IN6_IS_ADDR_LOOPBACK(&(addr->ipv6.sin6_addr))) - return (1); -#endif /* AF_INET6 */ - -#ifdef AF_LOCAL - if (addr->addr.sa_family == AF_LOCAL) - return (1); -#endif /* AF_LOCAL */ - - if (addr->addr.sa_family == AF_INET && - ntohl(addr->ipv4.sin_addr.s_addr) == 0x7f000001) - return (1); - - return (0); -} - - -#ifdef __sgi -# define ADDR_CAST (struct sockaddr *) -#else -# define ADDR_CAST (char *) -#endif /* __sgi */ - - -/* - * 'httpAddrLookup()' - Lookup the hostname associated with the address. - */ - -char * /* O - Host name */ -httpAddrLookup(const http_addr_t *addr, /* I - Address to lookup */ - char *name, /* I - Host name buffer */ - int namelen) /* I - Size of name buffer */ -{ - struct hostent *host; /* Host from name service */ - - - DEBUG_printf(("httpAddrLookup(addr=%p, name=%p, namelen=%d)\n", - addr, name, namelen)); - -#ifdef AF_INET6 - if (addr->addr.sa_family == AF_INET6) - host = gethostbyaddr(ADDR_CAST &(addr->ipv6.sin6_addr), - sizeof(struct in6_addr), AF_INET6); - else -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - if (addr->addr.sa_family == AF_LOCAL) - { - strlcpy(name, addr->un.sun_path, namelen); - return (name); - } - else -#endif /* AF_LOCAL */ - if (addr->addr.sa_family == AF_INET) - host = gethostbyaddr(ADDR_CAST &(addr->ipv4.sin_addr), - sizeof(struct in_addr), AF_INET); - else - host = NULL; - - if (host == NULL) - { - httpAddrString(addr, name, namelen); - return (NULL); - } - - strlcpy(name, host->h_name, namelen); - - return (name); -} - - -/* - * 'httpAddrString()' - Convert an IP address to a dotted string. - */ - -char * /* O - IP string */ -httpAddrString(const http_addr_t *addr, /* I - Address to convert */ - char *s, /* I - String buffer */ - int slen) /* I - Length of string */ -{ - DEBUG_printf(("httpAddrString(addr=%p, s=%p, slen=%d)\n", - addr, s, slen)); - -#ifdef AF_INET6 - if (addr->addr.sa_family == AF_INET6) - snprintf(s, slen, "%u.%u.%u.%u", - ntohl(addr->ipv6.sin6_addr.s6_addr32[0]), - ntohl(addr->ipv6.sin6_addr.s6_addr32[1]), - ntohl(addr->ipv6.sin6_addr.s6_addr32[2]), - ntohl(addr->ipv6.sin6_addr.s6_addr32[3])); - else -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - if (addr->addr.sa_family == AF_LOCAL) - strlcpy(s, addr->un.sun_path, slen); - else -#endif /* AF_LOCAL */ - if (addr->addr.sa_family == AF_INET) - { - unsigned temp; /* Temporary address */ - - - temp = ntohl(addr->ipv4.sin_addr.s_addr); - - snprintf(s, slen, "%d.%d.%d.%d", (temp >> 24) & 255, - (temp >> 16) & 255, (temp >> 8) & 255, temp & 255); - } - else - strlcpy(s, "UNKNOWN", slen); - - DEBUG_printf(("httpAddrString: returning \"%s\"...\n", s)); - - return (s); -} - - -/* - * 'httpGetHostByName()' - Lookup a hostname or IP address, and return - * address records for the specified name. - */ - -struct hostent * /* O - Host entry */ -httpGetHostByName(const char *name) /* I - Hostname or IP address */ -{ - const char *nameptr; /* Pointer into name */ - unsigned ip[4]; /* IP address components */ - static unsigned packed_ip; /* Packed IPv4 address */ - static char *packed_ptr[2]; /* Pointer to packed address */ - static struct hostent host_ip; /* Host entry for IP/domain address */ - - - DEBUG_printf(("httpGetHostByName(name=\"%s\")\n", name)); - -#if defined(__APPLE__) - /* OS X hack to avoid it's ocassional long delay in lookupd */ - static const char sLoopback[] = "127.0.0.1"; - if (strcmp(name, "localhost") == 0) - name = sLoopback; -#endif /* __APPLE__ */ - - /* - * This function is needed because some operating systems have a - * buggy implementation of gethostbyname() that does not support - * IP addresses. If the first character of the name string is a - * number, then sscanf() is used to extract the IP components. - * We then pack the components into an IPv4 address manually, - * since the inet_aton() function is deprecated. We use the - * htonl() macro to get the right byte order for the address. - * - * We also support domain sockets when supported by the underlying - * OS... - */ - -#ifdef AF_LOCAL - if (name[0] == '/') - { - /* - * A domain socket address, so make an AF_LOCAL entry and return it... - */ - - host_ip.h_name = (char *)name; - host_ip.h_aliases = NULL; - host_ip.h_addrtype = AF_LOCAL; - host_ip.h_length = strlen(name) + 1; - host_ip.h_addr_list = packed_ptr; - packed_ptr[0] = (char *)name; - packed_ptr[1] = NULL; - - DEBUG_puts("httpGetHostByName: returning domain socket address..."); - - return (&host_ip); - } -#endif /* AF_LOCAL */ - - for (nameptr = name; isdigit(*nameptr & 255) || *nameptr == '.'; nameptr ++); - - if (!*nameptr) - { - /* - * We have an IP address; break it up and provide the host entry - * to the caller. Currently only supports IPv4 addresses, although - * it should be trivial to support IPv6 in CUPS 1.2. - */ - - if (sscanf(name, "%u.%u.%u.%u", ip, ip + 1, ip + 2, ip + 3) != 4) - return (NULL); /* Must have 4 numbers */ - - if (ip[0] > 255 || ip[1] > 255 || ip[2] > 255 || ip[3] > 255) - return (NULL); /* Invalid byte ranges! */ - - packed_ip = htonl(((((((ip[0] << 8) | ip[1]) << 8) | ip[2]) << 8) | ip[3])); - - /* - * Fill in the host entry and return it... - */ - - host_ip.h_name = (char *)name; - host_ip.h_aliases = NULL; - host_ip.h_addrtype = AF_INET; - host_ip.h_length = 4; - host_ip.h_addr_list = packed_ptr; - packed_ptr[0] = (char *)(&packed_ip); - packed_ptr[1] = NULL; - - DEBUG_puts("httpGetHostByName: returning IPv4 address..."); - - return (&host_ip); - } - else - { - /* - * Use the gethostbyname() function to get the IP address for - * the name... - */ - - DEBUG_puts("httpGetHostByName: returning domain lookup address(es)..."); - - return (gethostbyname(name)); - } -} - - -/* - * End of "$Id: http-addr.c 148 2006-04-25 16:54:17Z njacobs $". - */ diff --git a/usr/src/lib/print/libhttp-core/common/http-private.h b/usr/src/lib/print/libhttp-core/common/http-private.h deleted file mode 100644 index a11b8bbb5e..0000000000 --- a/usr/src/lib/print/libhttp-core/common/http-private.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $" - * - * Private HTTP definitions for the Common UNIX Printing System (CUPS). - * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _CUPS_HTTP_PRIVATE_H_ -#define _CUPS_HTTP_PRIVATE_H_ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Include necessary headers... - */ -#ifdef __cplusplus -extern "C" { -#endif - - -# include "config.h" - - -# ifdef __sun -/* - * Define FD_SETSIZE to CUPS_MAX_FDS on Solaris to get the correct version of - * select() for large numbers of file descriptors. - */ - -#define CUPS_MAX_FDS 1024 - -# define FD_SETSIZE CUPS_MAX_FDS -# include <sys/select.h> -# endif /* __sun */ - -# include "http.h" - -# if defined HAVE_LIBSSL -/* - * The OpenSSL library provides its own SSL/TLS context structure for its - * IO and protocol management... - */ - -# include <openssl/err.h> -# include <openssl/rand.h> -# include <openssl/ssl.h> - -typedef SSL http_tls_t; - -# elif defined HAVE_GNUTLS -/* - * The GNU TLS library is more of a "bare metal" SSL/TLS library... - */ -# include <gnutls/gnutls.h> - -typedef struct -{ - gnutls_session session; /* GNU TLS session object */ - void *credentials; /* GNU TLS credentials object */ -} http_tls_t; - -# elif defined(HAVE_CDSASSL) -/* - * Darwin's Security framework provides its own SSL/TLS context structure - * for its IO and protocol management... - */ - -# include <Security/SecureTransport.h> - -typedef SSLConnectionRef http_tls_t; - -# endif /* HAVE_LIBSSL */ - -/* - * Some OS's don't have hstrerror(), most notably Solaris... - */ - -# ifndef HAVE_HSTRERROR -extern const char *cups_hstrerror(int error); -# define hstrerror cups_hstrerror -# elif defined(_AIX) || defined(__osf__) -/* - * AIX and Tru64 UNIX don't provide a prototype but do provide the function... - */ -extern const char *hstrerror(int error); -# endif /* !HAVE_HSTRERROR */ - -#ifdef __cplusplus -} -#endif - -#endif /* !_CUPS_HTTP_PRIVATE_H_ */ - -/* - * End of "$Id: http-private.h 148 2006-04-25 16:54:17Z njacobs $" - */ diff --git a/usr/src/lib/print/libhttp-core/common/http-support.c b/usr/src/lib/print/libhttp-core/common/http-support.c deleted file mode 100644 index 2ef3911058..0000000000 --- a/usr/src/lib/print/libhttp-core/common/http-support.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $" - * - * HTTP support routines for the Common UNIX Printing System (CUPS) scheduler. - * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * httpSeparate() - Separate a Universal Resource Identifier into its - * components. - * httpSeparate2() - Separate a Universal Resource Identifier into its - * components. - * httpStatus() - Return a short string describing a HTTP status code. - * cups_hstrerror() - hstrerror() emulation function for Solaris and others... - * http_copy_decode() - Copy and decode a URI. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Include necessary headers... - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include "string.h" - -#include "http.h" - - -/* - * Local functions... - */ - -static const char *http_copy_decode(char *dst, const char *src, - int dstsize, const char *term); - - -/* - * 'httpSeparate()' - Separate a Universal Resource Identifier into its - * components. - */ - -void -httpSeparate(const char *uri, /* I - Universal Resource Identifier */ - char *method, /* O - Method [32] (http, https, etc.) */ - char *username, /* O - Username [1024] */ - char *host, /* O - Hostname [1024] */ - int *port, /* O - Port number to use */ - char *resource) /* O - Resource/filename [1024] */ -{ - httpSeparate2(uri, method, 32, username, HTTP_MAX_URI, host, HTTP_MAX_URI, - port, resource, HTTP_MAX_URI); -} - - -/* - * 'httpSeparate2()' - Separate a Universal Resource Identifier into its - * components. - */ - -void -httpSeparate2(const char *uri, /* I - Universal Resource Identifier */ - char *method, /* O - Method (http, https, etc.) */ - int methodlen, /* I - Size of method buffer */ - char *username, /* O - Username */ - int usernamelen, /* I - Size of username buffer */ - char *host, /* O - Hostname */ - int hostlen, /* I - Size of hostname buffer */ - int *port, /* O - Port number to use */ - char *resource, /* O - Resource/filename */ - int resourcelen) /* I - Size of resource buffer */ -{ - char *ptr; /* Pointer into string... */ - const char *atsign, /* @ sign */ - *slash; /* Separator */ - - - /* - * Range check input... - */ - - if (uri == NULL || method == NULL || username == NULL || host == NULL || - port == NULL || resource == NULL) - return; - - /* - * Grab the method portion of the URI... - */ - - if (strncmp(uri, "//", 2) == 0) - { - /* - * Workaround for HP IPP client bug... - */ - - strlcpy(method, "ipp", methodlen); - } - else - { - /* - * Standard URI with method... - */ - - uri = http_copy_decode(host, uri, hostlen, ":"); - - if (*uri == ':') - uri ++; - - /* - * If the method contains a period or slash, then it's probably - * hostname/filename... - */ - - if (strchr(host, '.') != NULL || strchr(host, '/') != NULL || *uri == '\0') - { - if ((ptr = strchr(host, '/')) != NULL) - { - strlcpy(resource, ptr, resourcelen); - *ptr = '\0'; - } - else - resource[0] = '\0'; - - if (isdigit(*uri & 255)) - { - /* - * OK, we have "hostname:port[/resource]"... - */ - - *port = strtol(uri, (char **)&uri, 10); - - if (*uri == '/') - strlcpy(resource, uri, resourcelen); - } - else - *port = 631; - - strlcpy(method, "http", methodlen); - username[0] = '\0'; - return; - } - else - strlcpy(method, host, methodlen); - } - - /* - * If the method starts with less than 2 slashes then it is a local resource... - */ - - if (strncmp(uri, "//", 2) != 0) - { - strlcpy(resource, uri, resourcelen); - - username[0] = '\0'; - host[0] = '\0'; - *port = 0; - return; - } - - /* - * Grab the username, if any... - */ - - uri += 2; - - if ((slash = strchr(uri, '/')) == NULL) - slash = uri + strlen(uri); - - if ((atsign = strchr(uri, '@')) != NULL && atsign < slash) - { - /* - * Got a username:password combo... - */ - - uri = http_copy_decode(username, uri, usernamelen, "@") + 1; - } - else - username[0] = '\0'; - - /* - * Grab the hostname... - */ - - uri = http_copy_decode(host, uri, hostlen, ":/"); - - if (*uri != ':') - { - if (strcasecmp(method, "http") == 0) - *port = 80; - else if (strcasecmp(method, "https") == 0) - *port = 443; - else if (strcasecmp(method, "ipp") == 0) - *port = 631; - else if (strcasecmp(method, "lpd") == 0) - *port = 515; - else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */ - *port = 9100; - else - *port = 0; - } - else - { - /* - * Parse port number... - */ - - *port = strtol(uri + 1, (char **)&uri, 10); - } - - if (*uri == '\0') - { - /* - * Hostname but no port or path... - */ - - resource[0] = '/'; - resource[1] = '\0'; - return; - } - - /* - * The remaining portion is the resource string... - */ - - http_copy_decode(resource, uri, resourcelen, ""); -} - - -/* - * 'httpStatus()' - Return a short string describing a HTTP status code. - */ - -const char * /* O - String or NULL */ -httpStatus(http_status_t status) /* I - HTTP status code */ -{ - switch (status) - { - case HTTP_CONTINUE : - return ("Continue"); - case HTTP_SWITCHING_PROTOCOLS : - return ("Switching Protocols"); - case HTTP_OK : - return ("OK"); - case HTTP_CREATED : - return ("Created"); - case HTTP_ACCEPTED : - return ("Accepted"); - case HTTP_NO_CONTENT : - return ("No Content"); - case HTTP_NOT_MODIFIED : - return ("Not Modified"); - case HTTP_BAD_REQUEST : - return ("Bad Request"); - case HTTP_UNAUTHORIZED : - return ("Unauthorized"); - case HTTP_FORBIDDEN : - return ("Forbidden"); - case HTTP_NOT_FOUND : - return ("Not Found"); - case HTTP_REQUEST_TOO_LARGE : - return ("Request Entity Too Large"); - case HTTP_URI_TOO_LONG : - return ("URI Too Long"); - case HTTP_UPGRADE_REQUIRED : - return ("Upgrade Required"); - case HTTP_NOT_IMPLEMENTED : - return ("Not Implemented"); - case HTTP_NOT_SUPPORTED : - return ("Not Supported"); - default : - return ("Unknown"); - } -} - - -#ifndef HAVE_HSTRERROR -/* - * 'cups_hstrerror()' - hstrerror() emulation function for Solaris and others... - */ - -const char * /* O - Error string */ -cups_hstrerror(int error) /* I - Error number */ -{ - static const char * const errors[] = /* Error strings */ - { - "OK", - "Host not found.", - "Try again.", - "Unrecoverable lookup error.", - "No data associated with name." - }; - - - if (error < 0 || error > 4) - return ("Unknown hostname lookup error."); - else - return (errors[error]); -} -#endif /* !HAVE_HSTRERROR */ - - -/* - * 'http_copy_decode()' - Copy and decode a URI. - */ - -static const char * /* O - New source pointer */ -http_copy_decode(char *dst, /* O - Destination buffer */ - const char *src, /* I - Source pointer */ - int dstsize, /* I - Destination size */ - const char *term) /* I - Terminating characters */ -{ - char *ptr, /* Pointer into buffer */ - *end; /* End of buffer */ - int quoted; /* Quoted character */ - - - /* - * Copy the src to the destination until we hit a terminating character - * or the end of the string. - */ - - for (ptr = dst, end = dst + dstsize - 1; *src && !strchr(term, *src); src ++) - if (ptr < end) - { - if (*src == '%' && isxdigit(src[1] & 255) && isxdigit(src[2] & 255)) - { - /* - * Grab a hex-encoded character... - */ - - src ++; - if (isalpha(*src)) - quoted = (tolower(*src) - 'a' + 10) << 4; - else - quoted = (*src - '0') << 4; - - src ++; - if (isalpha(*src)) - quoted |= tolower(*src) - 'a' + 10; - else - quoted |= *src - '0'; - - *ptr++ = quoted; - } - else - *ptr++ = *src; - } - - *ptr = '\0'; - - return (src); -} - - -/* - * End of "$Id: http-support.c 148 2006-04-25 16:54:17Z njacobs $" - */ diff --git a/usr/src/lib/print/libhttp-core/common/http.c b/usr/src/lib/print/libhttp-core/common/http.c deleted file mode 100644 index b32b1eb3bc..0000000000 --- a/usr/src/lib/print/libhttp-core/common/http.c +++ /dev/null @@ -1,2569 +0,0 @@ -/* - * "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $" - * - * HTTP routines for the Common UNIX Printing System (CUPS). - * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * This file is subject to the Apple OS-Developed Software exception. - * - * Contents: - * - * httpInitialize() - Initialize the HTTP interface library and set the - * default HTTP proxy (if any). - * httpCheck() - Check to see if there is a pending response from - * the server. - * httpClearCookie() - Clear the cookie value(s). - * httpClose() - Close an HTTP connection... - * httpConnect() - Connect to a HTTP server. - * httpConnectEncrypt() - Connect to a HTTP server using encryption. - * httpEncryption() - Set the required encryption on the link. - * httpReconnect() - Reconnect to a HTTP server... - * httpGetSubField() - Get a sub-field value. - * httpSetField() - Set the value of an HTTP header. - * httpDelete() - Send a DELETE request to the server. - * httpGet() - Send a GET request to the server. - * httpHead() - Send a HEAD request to the server. - * httpOptions() - Send an OPTIONS request to the server. - * httpPost() - Send a POST request to the server. - * httpPut() - Send a PUT request to the server. - * httpTrace() - Send an TRACE request to the server. - * httpFlush() - Flush data from a HTTP connection. - * httpRead() - Read data from a HTTP connection. - * httpSetCookie() - Set the cookie value(s)... - * httpWait() - Wait for data available on a connection. - * httpWrite() - Write data to a HTTP connection. - * httpGets() - Get a line of text from a HTTP connection. - * httpPrintf() - Print a formatted string to a HTTP connection. - * httpGetDateString() - Get a formatted date/time string from a time value. - * httpGetDateTime() - Get a time value from a formatted date/time string. - * httpUpdate() - Update the current HTTP state for incoming data. - * httpDecode64() - Base64-decode a string. - * httpDecode64_2() - Base64-decode a string. - * httpEncode64() - Base64-encode a string. - * httpEncode64_2() - Base64-encode a string. - * httpGetLength() - Get the amount of data remaining from the - * content-length or transfer-encoding fields. - * http_field() - Return the field index for a field name. - * http_send() - Send a request with all fields and the trailing - * blank line. - * http_wait() - Wait for data available on a connection. - * http_upgrade() - Force upgrade to TLS encryption. - * http_setup_ssl() - Set up SSL/TLS on a connection. - * http_shutdown_ssl() - Shut down SSL/TLS on a connection. - * http_read_ssl() - Read from a SSL/TLS connection. - * http_write_ssl() - Write to a SSL/TLS connection. - * CDSAReadFunc() - Read function for CDSA decryption code. - * CDSAWriteFunc() - Write function for CDSA encryption code. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Include necessary headers... - */ - -#include "http-private.h" - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include "string.h" -#include <fcntl.h> -#include <errno.h> - -#include "http.h" -#include "debug.h" - -#ifndef WIN32 -# include <signal.h> -# include <sys/time.h> -# include <sys/resource.h> -#endif /* !WIN32 */ - - -/* - * Some operating systems have done away with the Fxxxx constants for - * the fcntl() call; this works around that "feature"... - */ - -#ifndef FNONBLK -# define FNONBLK O_NONBLOCK -#endif /* !FNONBLK */ - - -/* - * Local functions... - */ - -static http_field_t http_field(const char *name); -static int http_send(http_t *http, http_state_t request, - const char *uri); -static int http_wait(http_t *http, int msec); -#ifdef HAVE_SSL -static int http_upgrade(http_t *http); -static int http_setup_ssl(http_t *http); -static void http_shutdown_ssl(http_t *http); -static int http_read_ssl(http_t *http, char *buf, int len); -static int http_write_ssl(http_t *http, const char *buf, int len); -# ifdef HAVE_CDSASSL -static OSStatus CDSAReadFunc(SSLConnectionRef connection, void *data, size_t *dataLength); -static OSStatus CDSAWriteFunc(SSLConnectionRef connection, const void *data, size_t *dataLength); -# endif /* HAVE_CDSASSL */ -#endif /* HAVE_SSL */ - - -/* - * Local globals... - */ - -static const char * const http_fields[] = - { - "Accept-Language", - "Accept-Ranges", - "Authorization", - "Connection", - "Content-Encoding", - "Content-Language", - "Content-Length", - "Content-Location", - "Content-MD5", - "Content-Range", - "Content-Type", - "Content-Version", - "Date", - "Host", - "If-Modified-Since", - "If-Unmodified-since", - "Keep-Alive", - "Last-Modified", - "Link", - "Location", - "Range", - "Referer", - "Retry-After", - "Transfer-Encoding", - "Upgrade", - "User-Agent", - "WWW-Authenticate" - }; -static const char * const days[7] = - { - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat" - }; -static const char * const months[12] = - { - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - }; - -void -httpDumpData(FILE *fp, const char *tag, const char *buffer, int bytes) -{ - int i, j, ch; - - fprintf(fp, "%s %d(0x%x) bytes...\n", tag, bytes, bytes); - for (i = 0; i < bytes; i += 16) { - fprintf(fp, "%s ", (tag ? tag : "")); - - for (j = 0; j < 16 && (i + j) < bytes; j ++) - fprintf(fp, " %02X", buffer[i + j] & 255); - - while (j < 16) { - fprintf(fp, " "); - j++; - } - - fprintf(fp, " "); - for (j = 0; j < 16 && (i + j) < bytes; j ++) { - ch = buffer[i + j] & 255; - if (ch < ' ' || ch == 127) - ch = '.'; - putc(ch, fp); - } - putc('\n', fp); - } -} - - -/* - * 'httpInitialize()' - Initialize the HTTP interface library and set the - * default HTTP proxy (if any). - */ - -void -httpInitialize(void) -{ -#ifdef HAVE_LIBSSL -# ifndef WIN32 - struct timeval curtime; /* Current time in microseconds */ -# endif /* !WIN32 */ - int i; /* Looping var */ - unsigned char data[1024]; /* Seed data */ -#endif /* HAVE_LIBSSL */ - -#ifdef WIN32 - WSADATA winsockdata; /* WinSock data */ - static int initialized = 0; /* Has WinSock been initialized? */ - - - if (!initialized) - WSAStartup(MAKEWORD(1,1), &winsockdata); -#elif defined(HAVE_SIGSET) - sigset(SIGPIPE, SIG_IGN); -#elif defined(HAVE_SIGACTION) - struct sigaction action; /* POSIX sigaction data */ - - - /* - * Ignore SIGPIPE signals... - */ - - memset(&action, 0, sizeof(action)); - action.sa_handler = SIG_IGN; - sigaction(SIGPIPE, &action, NULL); -#else - signal(SIGPIPE, SIG_IGN); -#endif /* WIN32 */ - -#ifdef HAVE_GNUTLS - gnutls_global_init(); -#endif /* HAVE_GNUTLS */ - -#ifdef HAVE_LIBSSL - SSL_load_error_strings(); - SSL_library_init(); - - /* - * Using the current time is a dubious random seed, but on some systems - * it is the best we can do (on others, this seed isn't even used...) - */ - -#ifdef WIN32 -#else - gettimeofday(&curtime, NULL); - srand(curtime.tv_sec + curtime.tv_usec); -#endif /* WIN32 */ - - for (i = 0; i < sizeof(data); i ++) - data[i] = rand(); /* Yes, this is a poor source of random data... */ - - RAND_seed(&data, sizeof(data)); -#endif /* HAVE_LIBSSL */ -} - - -/* - * 'httpCheck()' - Check to see if there is a pending response from the server. - */ - -int /* O - 0 = no data, 1 = data available */ -httpCheck(http_t *http) /* I - HTTP connection */ -{ - return (httpWait(http, 0)); -} - - -/* - * 'httpClearCookie()' - Clear the cookie value(s). - */ - -void -httpClearCookie(http_t *http) /* I - Connection */ -{ - if (!http) - return; - - if (http->cookie) - { - free(http->cookie); - http->cookie = NULL; - } -} - - -/* - * 'httpClose()' - Close an HTTP connection... - */ - -void -httpClose(http_t *http) /* I - Connection to close */ -{ - DEBUG_printf(("httpClose(http=%p)\n", http)); - - if (!http) - return; - - if (http->input_set) - free(http->input_set); - - if (http->cookie) - free(http->cookie); - -#ifdef HAVE_SSL - if (http->tls) - http_shutdown_ssl(http); -#endif /* HAVE_SSL */ - -#ifdef WIN32 - closesocket(http->fd); -#else - close(http->fd); -#endif /* WIN32 */ - - free(http); -} - - -/* - * 'httpConnect()' - Connect to a HTTP server. - */ - -http_t * /* O - New HTTP connection */ -httpConnect(const char *host, /* I - Host to connect to */ - int port) /* I - Port number */ -{ - http_encryption_t encrypt; /* Type of encryption to use */ - - - /* - * Set the default encryption status... - */ - - if (port == 443) - encrypt = HTTP_ENCRYPT_ALWAYS; - else - encrypt = HTTP_ENCRYPT_IF_REQUESTED; - - return (httpConnectEncrypt(host, port, encrypt)); -} - - -/* - * 'httpConnectEncrypt()' - Connect to a HTTP server using encryption. - */ - -http_t * /* O - New HTTP connection */ -httpConnectEncrypt(const char *host, /* I - Host to connect to */ - int port, /* I - Port number */ - http_encryption_t encrypt) - /* I - Type of encryption to use */ -{ - int i; /* Looping var */ - http_t *http; /* New HTTP connection */ - struct hostent *hostaddr; /* Host address data */ - - - DEBUG_printf(("httpConnectEncrypt(host=\"%s\", port=%d, encrypt=%d)\n", - host ? host : "(null)", port, encrypt)); - - if (!host) - return (NULL); - - httpInitialize(); - - /* - * Lookup the host... - */ - - if ((hostaddr = httpGetHostByName(host)) == NULL) - { - /* - * This hack to make users that don't have a localhost entry in - * their hosts file or DNS happy... - */ - - if (strcasecmp(host, "localhost") != 0) - return (NULL); - else if ((hostaddr = httpGetHostByName("127.0.0.1")) == NULL) - return (NULL); - } - - /* - * Verify that it is an IPv4, IPv6, or domain address... - */ - - if ((hostaddr->h_addrtype != AF_INET || hostaddr->h_length != 4) -#ifdef AF_INET6 - && (hostaddr->h_addrtype != AF_INET6 || hostaddr->h_length != 16) -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - && (hostaddr->h_addrtype != AF_LOCAL) -#endif /* AF_LOCAL */ - ) - return (NULL); - - /* - * Allocate memory for the structure... - */ - - http = calloc(sizeof(http_t), 1); - if (http == NULL) - return (NULL); - - http->version = HTTP_1_1; - http->blocking = 1; - http->activity = time(NULL); - http->fd = -1; - - /* - * Set the encryption status... - */ - - if (port == 443) /* Always use encryption for https */ - http->encryption = HTTP_ENCRYPT_ALWAYS; - else - http->encryption = encrypt; - - /* - * Loop through the addresses we have until one of them connects... - */ - - strlcpy(http->hostname, host, sizeof(http->hostname)); - - for (i = 0; hostaddr->h_addr_list[i]; i ++) - { - /* - * Load the address... - */ - - httpAddrLoad(hostaddr, port, i, &(http->hostaddr)); - - /* - * Connect to the remote system... - */ - - if (!httpReconnect(http)) - return (http); - } - - /* - * Could not connect to any known address - bail out! - */ - - free(http); - return (NULL); -} - - -/* - * 'httpEncryption()' - Set the required encryption on the link. - */ - -int /* O - -1 on error, 0 on success */ -httpEncryption(http_t *http, /* I - HTTP data */ - http_encryption_t e) /* I - New encryption preference */ -{ - DEBUG_printf(("httpEncryption(http=%p, e=%d)\n", http, e)); - -#ifdef HAVE_SSL - if (!http) - return (0); - - http->encryption = e; - - if ((http->encryption == HTTP_ENCRYPT_ALWAYS && !http->tls) || - (http->encryption == HTTP_ENCRYPT_NEVER && http->tls)) - return (httpReconnect(http)); - else if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls) - return (http_upgrade(http)); - else - return (0); -#else - if (e == HTTP_ENCRYPT_ALWAYS || e == HTTP_ENCRYPT_REQUIRED) - return (-1); - else - return (0); -#endif /* HAVE_SSL */ -} - - -/* - * 'httpReconnect()' - Reconnect to a HTTP server... - */ - -int /* O - 0 on success, non-zero on failure */ -httpReconnect(http_t *http) /* I - HTTP data */ -{ - int val; /* Socket option value */ - int status; /* Connect status */ - - - DEBUG_printf(("httpReconnect(http=%p)\n", http)); - - if (!http) - return (-1); - -#ifdef HAVE_SSL - if (http->tls) - http_shutdown_ssl(http); -#endif /* HAVE_SSL */ - - /* - * Close any previously open socket... - */ - - if (http->fd >= 0) -#ifdef WIN32 - closesocket(http->fd); -#else - close(http->fd); -#endif /* WIN32 */ - - /* - * Create the socket and set options to allow reuse. - */ - - if ((http->fd = socket(http->hostaddr.addr.sa_family, SOCK_STREAM, 0)) < 0) - { -#ifdef WIN32 - http->error = WSAGetLastError(); -#else - http->error = errno; -#endif /* WIN32 */ - http->status = HTTP_ERROR; - return (-1); - } - -#ifdef FD_CLOEXEC - fcntl(http->fd, F_SETFD, FD_CLOEXEC); /* Close this socket when starting * - * other processes... */ -#endif /* FD_CLOEXEC */ - - val = 1; - setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); - -#ifdef SO_REUSEPORT - val = 1; - setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); -#endif /* SO_REUSEPORT */ - - /* - * Using TCP_NODELAY improves responsiveness, especially on systems - * with a slow loopback interface... Since we write large buffers - * when sending print files and requests, there shouldn't be any - * performance penalty for this... - */ - - val = 1; -#ifdef WIN32 - setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); -#else - setsockopt(http->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); -#endif /* WIN32 */ - - /* - * Connect to the server... - */ - -#ifdef AF_INET6 - if (http->hostaddr.addr.sa_family == AF_INET6) - status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), - sizeof(http->hostaddr.ipv6)); - else -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - if (http->hostaddr.addr.sa_family == AF_LOCAL) - status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), - SUN_LEN(&(http->hostaddr.un))); - else -#endif /* AF_LOCAL */ - status = connect(http->fd, (struct sockaddr *)&(http->hostaddr), - sizeof(http->hostaddr.ipv4)); - - if (status < 0) - { -#ifdef WIN32 - http->error = WSAGetLastError(); -#else - http->error = errno; -#endif /* WIN32 */ - http->status = HTTP_ERROR; - -#ifdef WIN32 - closesocket(http->fd); -#else - close(http->fd); -#endif - - http->fd = -1; - - return (-1); - } - - http->error = 0; - http->status = HTTP_CONTINUE; - -#ifdef HAVE_SSL - if (http->encryption == HTTP_ENCRYPT_ALWAYS) - { - /* - * Always do encryption via SSL. - */ - - if (http_setup_ssl(http) != 0) - { -#ifdef WIN32 - closesocket(http->fd); -#else - close(http->fd); -#endif /* WIN32 */ - - return (-1); - } - } - else if (http->encryption == HTTP_ENCRYPT_REQUIRED) - return (http_upgrade(http)); -#endif /* HAVE_SSL */ - - return (0); -} - - -/* - * 'httpGetSubField()' - Get a sub-field value. - */ - -char * /* O - Value or NULL */ -httpGetSubField(http_t *http, /* I - HTTP data */ - http_field_t field, /* I - Field index */ - const char *name, /* I - Name of sub-field */ - char *value) /* O - Value string */ -{ - const char *fptr; /* Pointer into field */ - char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ - *ptr; /* Pointer into string buffer */ - - - DEBUG_printf(("httpGetSubField(http=%p, field=%d, name=\"%s\", value=%p)\n", - http, field, name, value)); - - if (http == NULL || - field < HTTP_FIELD_ACCEPT_LANGUAGE || - field > HTTP_FIELD_WWW_AUTHENTICATE || - name == NULL || value == NULL) - return (NULL); - - for (fptr = http->fields[field]; *fptr;) - { - /* - * Skip leading whitespace... - */ - - while (isspace(*fptr & 255)) - fptr ++; - - if (*fptr == ',') - { - fptr ++; - continue; - } - - /* - * Get the sub-field name... - */ - - for (ptr = temp; - *fptr && *fptr != '=' && !isspace(*fptr & 255) && ptr < (temp + sizeof(temp) - 1); - *ptr++ = *fptr++); - - *ptr = '\0'; - - DEBUG_printf(("httpGetSubField: name=\"%s\"\n", temp)); - - /* - * Skip trailing chars up to the '='... - */ - - while (isspace(*fptr & 255)) - fptr ++; - - if (!*fptr) - break; - - if (*fptr != '=') - continue; - - /* - * Skip = and leading whitespace... - */ - - fptr ++; - - while (isspace(*fptr & 255)) - fptr ++; - - if (*fptr == '\"') - { - /* - * Read quoted string... - */ - - for (ptr = value, fptr ++; - *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1); - *ptr++ = *fptr++); - - *ptr = '\0'; - - while (*fptr && *fptr != '\"') - fptr ++; - - if (*fptr) - fptr ++; - } - else - { - /* - * Read unquoted string... - */ - - for (ptr = value; - *fptr && !isspace(*fptr & 255) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1); - *ptr++ = *fptr++); - - *ptr = '\0'; - - while (*fptr && !isspace(*fptr & 255) && *fptr != ',') - fptr ++; - } - - DEBUG_printf(("httpGetSubField: value=\"%s\"\n", value)); - - /* - * See if this is the one... - */ - - if (strcmp(name, temp) == 0) - return (value); - } - - value[0] = '\0'; - - return (NULL); -} - - -/* - * 'httpSetField()' - Set the value of an HTTP header. - */ - -void -httpSetField(http_t *http, /* I - HTTP data */ - http_field_t field, /* I - Field index */ - const char *value) /* I - Value */ -{ - if (http == NULL || - field < HTTP_FIELD_ACCEPT_LANGUAGE || - field > HTTP_FIELD_WWW_AUTHENTICATE || - value == NULL) - return; - - strlcpy(http->fields[field], value, HTTP_MAX_VALUE); -} - - -/* - * 'httpDelete()' - Send a DELETE request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpDelete(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI to delete */ -{ - return (http_send(http, HTTP_DELETE, uri)); -} - - -/* - * 'httpGet()' - Send a GET request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpGet(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI to get */ -{ - return (http_send(http, HTTP_GET, uri)); -} - - -/* - * 'httpHead()' - Send a HEAD request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpHead(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI for head */ -{ - return (http_send(http, HTTP_HEAD, uri)); -} - - -/* - * 'httpOptions()' - Send an OPTIONS request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpOptions(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI for options */ -{ - return (http_send(http, HTTP_OPTIONS, uri)); -} - - -/* - * 'httpPost()' - Send a POST request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpPost(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI for post */ -{ - httpGetLength(http); - - return (http_send(http, HTTP_POST, uri)); -} - - -/* - * 'httpPut()' - Send a PUT request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpPut(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI to put */ -{ - httpGetLength(http); - - return (http_send(http, HTTP_PUT, uri)); -} - - -/* - * 'httpTrace()' - Send an TRACE request to the server. - */ - -int /* O - Status of call (0 = success) */ -httpTrace(http_t *http, /* I - HTTP data */ - const char *uri) /* I - URI for trace */ -{ - return (http_send(http, HTTP_TRACE, uri)); -} - - -/* - * 'httpFlush()' - Flush data from a HTTP connection. - */ - -void -httpFlush(http_t *http) /* I - HTTP data */ -{ - char buffer[8192]; /* Junk buffer */ - - - DEBUG_printf(("httpFlush(http=%p), state=%d\n", http, http->state)); - - while (httpRead(http, buffer, sizeof(buffer)) > 0); -} - - -/* - * 'httpRead()' - Read data from a HTTP connection. - */ - -int /* O - Number of bytes read */ -httpRead(http_t *http, /* I - HTTP data */ - char *buffer, /* I - Buffer for data */ - int length) /* I - Maximum number of bytes */ -{ - int bytes; /* Bytes read */ - char len[32]; /* Length string */ - - - DEBUG_printf(("httpRead(http=%p, buffer=%p, length=%d)\n", - http, buffer, length)); - - if (http == NULL || buffer == NULL) - return (-1); - - http->activity = time(NULL); - - if (length <= 0) - return (0); - - if (http->data_encoding == HTTP_ENCODE_CHUNKED && - http->data_remaining <= 0) - { - DEBUG_puts("httpRead: Getting chunk length..."); - - if (httpGets(len, sizeof(len), http) == NULL) - { - DEBUG_puts("httpRead: Could not get length!"); - return (0); - } - - http->data_remaining = strtol(len, NULL, 16); - if (http->data_remaining < 0) - { - DEBUG_puts("httpRead: Negative chunk length!"); - return (0); - } - } - - DEBUG_printf(("httpRead: data_remaining=%d\n", http->data_remaining)); - - if (http->data_remaining <= 0) - { - /* - * A zero-length chunk ends a transfer; unless we are reading POST - * data, go idle... - */ - - if (http->data_encoding == HTTP_ENCODE_CHUNKED) - httpGets(len, sizeof(len), http); - - if (http->state == HTTP_POST_RECV) - http->state ++; - else - http->state = HTTP_WAITING; - - /* - * Prevent future reads for this request... - */ - - http->data_encoding = HTTP_ENCODE_LENGTH; - - return (0); - } - else if (length > http->data_remaining) - length = http->data_remaining; - - if (http->used == 0 && length <= 256) - { - /* - * Buffer small reads for better performance... - */ - - if (!http->blocking && !httpWait(http, 1000)) - return (0); - - if (http->data_remaining > sizeof(http->buffer)) - bytes = sizeof(http->buffer); - else - bytes = http->data_remaining; - -#ifdef HAVE_SSL - if (http->tls) - bytes = http_read_ssl(http, http->buffer, bytes); - else -#endif /* HAVE_SSL */ - { - DEBUG_printf(("httpRead: reading %d bytes from socket into buffer...\n", - bytes)); - - bytes = recv(http->fd, http->buffer, bytes, 0); - - DEBUG_printf(("httpRead: read %d bytes from socket into buffer...\n", - bytes)); -#ifdef DEBUG_HTTP - httpDumpData(stdout, "httpRead:", http->buffer, bytes); -#endif - } - - if (bytes > 0) - http->used = bytes; - else if (bytes < 0) - { -#ifdef WIN32 - http->error = WSAGetLastError(); - return (-1); -#else - if (errno != EINTR) - { - http->error = errno; - return (-1); - } -#endif /* WIN32 */ - } - else - { - http->error = EPIPE; - return (0); - } - } - - if (http->used > 0) - { - if (length > http->used) - length = http->used; - - bytes = length; - - DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes)); - - memcpy(buffer, http->buffer, length); - http->used -= length; - - if (http->used > 0) - memmove(http->buffer, http->buffer + length, http->used); - } -#ifdef HAVE_SSL - else if (http->tls) - { - if (!http->blocking && !httpWait(http, 1000)) - return (0); - - bytes = http_read_ssl(http, buffer, length); - } -#endif /* HAVE_SSL */ - else - { - if (!http->blocking && !httpWait(http, 1000)) - return (0); - - DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length)); - - while ((bytes = recv(http->fd, buffer, length, 0)) < 0) - if (errno != EINTR) - break; - DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes)); - } -#ifdef DEBUG_HTTP - httpDumpData(stdout, "httpRead:", buffer, bytes); -#endif - - if (bytes > 0) - http->data_remaining -= bytes; - else if (bytes < 0) - { -#ifdef WIN32 - http->error = WSAGetLastError(); -#else - if (errno == EINTR) - bytes = 0; - else - http->error = errno; -#endif /* WIN32 */ - } - else - { - http->error = EPIPE; - return (0); - } - - if (http->data_remaining == 0) - { - if (http->data_encoding == HTTP_ENCODE_CHUNKED) - httpGets(len, sizeof(len), http); - - if (http->data_encoding != HTTP_ENCODE_CHUNKED) - { - if (http->state == HTTP_POST_RECV) - http->state ++; - else - http->state = HTTP_WAITING; - } - } - - return (bytes); -} - - -/* - * 'httpSetCookie()' - Set the cookie value(s)... - */ - -void -httpSetCookie(http_t *http, /* I - Connection */ - const char *cookie) /* I - Cookie string */ -{ - if (!http) - return; - - if (http->cookie) - free(http->cookie); - - if (cookie) - http->cookie = strdup(cookie); - else - http->cookie = NULL; -} - - -/* - * 'httpWait()' - Wait for data available on a connection. - */ - -int /* O - 1 if data is available, 0 otherwise */ -httpWait(http_t *http, /* I - HTTP data */ - int msec) /* I - Milliseconds to wait */ -{ - /* - * First see if there is data in the buffer... - */ - - if (http == NULL) - return (0); - - if (http->used) - return (1); - - /* - * If not, check the SSL/TLS buffers and do a select() on the connection... - */ - - return (http_wait(http, msec)); -} - - -/* - * 'httpWrite()' - Write data to a HTTP connection. - */ - -int /* O - Number of bytes written */ -httpWrite(http_t *http, /* I - HTTP data */ - const char *buffer, /* I - Buffer for data */ - int length) /* I - Number of bytes to write */ -{ - int tbytes, /* Total bytes sent */ - bytes; /* Bytes sent */ - - - if (http == NULL || buffer == NULL) - return (-1); - - http->activity = time(NULL); - - if (http->data_encoding == HTTP_ENCODE_CHUNKED) - { - if (httpPrintf(http, "%x\r\n", length) < 0) - return (-1); - - if (length == 0) - { - /* - * A zero-length chunk ends a transfer; unless we are sending POST - * or PUT data, go idle... - */ - - DEBUG_printf(("httpWrite: changing states from %d", http->state)); - - if (http->state == HTTP_POST_RECV) - http->state ++; - else if (http->state == HTTP_PUT_RECV) - http->state = HTTP_STATUS; - else - http->state = HTTP_WAITING; - DEBUG_printf((" to %d\n", http->state)); - - if (httpPrintf(http, "\r\n") < 0) - return (-1); - - return (0); - } - } - - tbytes = 0; - - while (length > 0) - { -#ifdef HAVE_SSL - if (http->tls) - bytes = http_write_ssl(http, buffer, length); - else -#endif /* HAVE_SSL */ - bytes = send(http->fd, buffer, length, 0); - -#ifdef DEBUG_HTTP - if (bytes >= 0) - httpDumpData(stdout, "httpWrite:", buffer, bytes); -#endif /* DEBUG */ - - - if (bytes < 0) - { -#ifdef WIN32 - if (WSAGetLastError() != http->error) - { - http->error = WSAGetLastError(); - continue; - } -#else - if (errno == EINTR) - continue; - else if (errno != http->error && errno != ECONNRESET) - { - http->error = errno; - continue; - } -#endif /* WIN32 */ - - DEBUG_puts("httpWrite: error writing data...\n"); - - return (-1); - } - - buffer += bytes; - tbytes += bytes; - length -= bytes; - if (http->data_encoding == HTTP_ENCODE_LENGTH) - http->data_remaining -= bytes; - } - - if (http->data_encoding == HTTP_ENCODE_CHUNKED) - if (httpPrintf(http, "\r\n") < 0) - return (-1); - - if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH) - { - /* - * Finished with the transfer; unless we are sending POST or PUT - * data, go idle... - */ - - DEBUG_printf(("httpWrite: changing states from %d", http->state)); - - if (http->state == HTTP_POST_RECV) - http->state ++; - else if (http->state == HTTP_PUT_RECV) - http->state = HTTP_STATUS; - else - http->state = HTTP_WAITING; - - DEBUG_printf((" to %d\n", http->state)); - } - - return (tbytes); -} - - -/* - * 'httpGets()' - Get a line of text from a HTTP connection. - */ - -char * /* O - Line or NULL */ -httpGets(char *line, /* I - Line to read into */ - int length, /* I - Max length of buffer */ - http_t *http) /* I - HTTP data */ -{ - char *lineptr, /* Pointer into line */ - *bufptr, /* Pointer into input buffer */ - *bufend; /* Pointer to end of buffer */ - int bytes; /* Number of bytes read */ - - - DEBUG_printf(("httpGets(line=%p, length=%d, http=%p)\n", line, length, http)); - - if (http == NULL || line == NULL) - return (NULL); - - /* - * Pre-scan the buffer and see if there is a newline in there... - */ - -#ifdef WIN32 - WSASetLastError(0); -#else - errno = 0; -#endif /* WIN32 */ - - do - { - bufptr = http->buffer; - bufend = http->buffer + http->used; - - while (bufptr < bufend) - if (*bufptr == 0x0a) - break; - else - bufptr ++; - - if (bufptr >= bufend && http->used < HTTP_MAX_BUFFER) - { - /* - * No newline; see if there is more data to be read... - */ - - if (!http->blocking && !http_wait(http, 1000)) - return (NULL); - -#ifdef HAVE_SSL - if (http->tls) - bytes = http_read_ssl(http, bufend, HTTP_MAX_BUFFER - http->used); - else -#endif /* HAVE_SSL */ - bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0); - - DEBUG_printf(("httpGets: read %d bytes...\n", bytes)); -#ifdef DEBUG_HTTP - httpDumpData(stdout, "httpGets:", bufend, bytes); -#endif - - if (bytes < 0) - { - /* - * Nope, can't get a line this time... - */ - -#ifdef WIN32 - if (WSAGetLastError() != http->error) - { - http->error = WSAGetLastError(); - continue; - } - - DEBUG_printf(("httpGets: recv() error %d!\n", WSAGetLastError())); -#else - DEBUG_printf(("httpGets: recv() error %d!\n", errno)); - - if (errno == EINTR) - continue; - else if (errno != http->error) - { - http->error = errno; - continue; - } -#endif /* WIN32 */ - - return (NULL); - } - else if (bytes == 0) - { - http->error = EPIPE; - - return (NULL); - } - - /* - * Yup, update the amount used and the end pointer... - */ - - http->used += bytes; - bufend += bytes; - bufptr = bufend; - } - } - while (bufptr >= bufend && http->used < HTTP_MAX_BUFFER); - - http->activity = time(NULL); - - /* - * Read a line from the buffer... - */ - - lineptr = line; - bufptr = http->buffer; - bytes = 0; - length --; - - while (bufptr < bufend && bytes < length) - { - bytes ++; - - if (*bufptr == 0x0a) - { - bufptr ++; - break; - } - else if (*bufptr == 0x0d) - bufptr ++; - else - *lineptr++ = *bufptr++; - } - - if (bytes > 0) - { - *lineptr = '\0'; - - http->used -= bytes; - if (http->used > 0) - memmove(http->buffer, bufptr, http->used); - - DEBUG_printf(("httpGets: Returning \"%s\"\n", line)); - return (line); - } - - DEBUG_puts("httpGets: No new line available!"); - - return (NULL); -} - - -/* - * 'httpPrintf()' - Print a formatted string to a HTTP connection. - */ - -int /* O - Number of bytes written */ -httpPrintf(http_t *http, /* I - HTTP data */ - const char *format, /* I - printf-style format string */ - ...) /* I - Additional args as needed */ -{ - int bytes, /* Number of bytes to write */ - nbytes, /* Number of bytes written */ - tbytes; /* Number of bytes all together */ - char buf[HTTP_MAX_BUFFER], /* Buffer for formatted string */ - *bufptr; /* Pointer into buffer */ - va_list ap; /* Variable argument pointer */ - - - DEBUG_printf(("httpPrintf: httpPrintf(http=%p, format=\"%s\", ...)\n", http, format)); - - va_start(ap, format); - bytes = vsnprintf(buf, sizeof(buf), format, ap); - va_end(ap); - - DEBUG_printf(("httpPrintf: %s", buf)); - - for (tbytes = 0, bufptr = buf; tbytes < bytes; tbytes += nbytes, bufptr += nbytes) - { -#ifdef HAVE_SSL - if (http->tls) - nbytes = http_write_ssl(http, bufptr, bytes - tbytes); - else -#endif /* HAVE_SSL */ - nbytes = send(http->fd, bufptr, bytes - tbytes, 0); - -#ifdef DEBUG_HTTP - if (nbytes >= 0) - httpDumpData(stdout, "httpPrintf:", bufptr, nbytes); -#endif - - if (nbytes < 0) - { - nbytes = 0; - -#ifdef WIN32 - if (WSAGetLastError() != http->error) - { - http->error = WSAGetLastError(); - continue; - } -#else - if (errno == EINTR) - continue; - else if (errno != http->error) - { - http->error = errno; - continue; - } -#endif /* WIN32 */ - - return (-1); - } - } - - return (bytes); -} - - -/* - * 'httpGetDateString()' - Get a formatted date/time string from a time value. - */ - -const char * /* O - Date/time string */ -httpGetDateString(time_t t) /* I - UNIX time */ -{ - struct tm *tdate; - static char datetime[256]; - - - tdate = gmtime(&t); - snprintf(datetime, sizeof(datetime), "%s, %02d %s %d %02d:%02d:%02d GMT", - days[tdate->tm_wday], tdate->tm_mday, months[tdate->tm_mon], - tdate->tm_year + 1900, tdate->tm_hour, tdate->tm_min, tdate->tm_sec); - - return (datetime); -} - - -/* - * 'httpGetDateTime()' - Get a time value from a formatted date/time string. - */ - -time_t /* O - UNIX time */ -httpGetDateTime(const char *s) /* I - Date/time string */ -{ - int i; /* Looping var */ - struct tm tdate; /* Time/date structure */ - char mon[16]; /* Abbreviated month name */ - int day, year; /* Day of month and year */ - int hour, min, sec; /* Time */ - - - if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6) - return (0); - - for (i = 0; i < 12; i ++) - if (strcasecmp(mon, months[i]) == 0) - break; - - if (i >= 12) - return (0); - - tdate.tm_mon = i; - tdate.tm_mday = day; - tdate.tm_year = year - 1900; - tdate.tm_hour = hour; - tdate.tm_min = min; - tdate.tm_sec = sec; - tdate.tm_isdst = 0; - - return (mktime(&tdate)); -} - - -/* - * 'httpUpdate()' - Update the current HTTP state for incoming data. - */ - -http_status_t /* O - HTTP status */ -httpUpdate(http_t *http) /* I - HTTP data */ -{ - char line[1024], /* Line from connection... */ - *value; /* Pointer to value on line */ - http_field_t field; /* Field index */ - int major, minor, /* HTTP version numbers */ - status; /* Request status */ - - - DEBUG_printf(("httpUpdate(http=%p), state=%d\n", http, http->state)); - - /* - * If we haven't issued any commands, then there is nothing to "update"... - */ - - if (http->state == HTTP_WAITING) - return (HTTP_CONTINUE); - - /* - * Grab all of the lines we can from the connection... - */ - - line[0] = '\0'; - while (httpGets(line, sizeof(line), http) != NULL) - { - DEBUG_printf(("httpUpdate: Got \"%s\"\n", line)); - - if (line[0] == '\0') - { - /* - * Blank line means the start of the data section (if any). Return - * the result code, too... - * - * If we get status 100 (HTTP_CONTINUE), then we *don't* change states. - * Instead, we just return HTTP_CONTINUE to the caller and keep on - * tryin'... - */ - - if (http->status == HTTP_CONTINUE) - return (http->status); - - if (http->status < HTTP_BAD_REQUEST) - http->digest_tries = 0; - -#ifdef HAVE_SSL - if (http->status == HTTP_SWITCHING_PROTOCOLS && !http->tls) - { - if (http_setup_ssl(http) != 0) - { -# ifdef WIN32 - closesocket(http->fd); -# else - close(http->fd); -# endif /* WIN32 */ - - return (HTTP_ERROR); - } - - return (HTTP_CONTINUE); - } -#endif /* HAVE_SSL */ - - httpGetLength(http); - - switch (http->state) - { - case HTTP_GET : - case HTTP_POST : - case HTTP_POST_RECV : - case HTTP_PUT : - http->state ++; - case HTTP_POST_SEND : - break; - - default : - http->state = HTTP_WAITING; - break; - } - - return (http->status); - } - else if (strncmp(line, "HTTP/", 5) == 0) - { - /* - * Got the beginning of a response... - */ - - if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, &status) != 3) - return (HTTP_ERROR); - - http->version = (http_version_t)(major * 100 + minor); - http->status = (http_status_t)status; - } - else if ((value = strchr(line, ':')) != NULL) - { - /* - * Got a value... - */ - - *value++ = '\0'; - while (isspace(*value & 255)) - value ++; - - /* - * Be tolerants of servers that send unknown attribute fields... - */ - - if (!strcasecmp(line, "expect")) - { - /* - * "Expect: 100-continue" or similar... - */ - - http->expect = (http_status_t)atoi(value); - } - else if (!strcasecmp(line, "cookie")) - { - /* - * "Cookie: name=value[; name=value ...]" - replaces previous cookies... - */ - - httpSetCookie(http, value); - } - else if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN) - { - DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line)); - continue; - } - else - httpSetField(http, field, value); - } - else - { - http->status = HTTP_ERROR; - return (HTTP_ERROR); - } - } - - /* - * See if there was an error... - */ - - if (http->error == EPIPE && http->status > HTTP_CONTINUE) - return (http->status); - - if (http->error) - { - DEBUG_printf(("httpUpdate: socket error %d - %s\n", http->error, - strerror(http->error))); - http->status = HTTP_ERROR; - return (HTTP_ERROR); - } - - /* - * If we haven't already returned, then there is nothing new... - */ - - return (HTTP_CONTINUE); -} - - -/* - * 'httpDecode64()' - Base64-decode a string. - */ - -char * /* O - Decoded string */ -httpDecode64(char *out, /* I - String to write to */ - const char *in) /* I - String to read from */ -{ - int outlen; /* Output buffer length */ - - - /* - * Use the old maximum buffer size for binary compatibility... - */ - - outlen = 512; - - return (httpDecode64_2(out, &outlen, in)); -} - - -/* - * 'httpDecode64_2()' - Base64-decode a string. - */ - -char * /* O - Decoded string */ -httpDecode64_2(char *out, /* I - String to write to */ - int *outlen, /* IO - Size of output string */ - const char *in) /* I - String to read from */ -{ - int pos, /* Bit position */ - base64; /* Value of this character */ - char *outptr, /* Output pointer */ - *outend; /* End of output buffer */ - - - /* - * Range check input... - */ - - if (!out || !outlen || *outlen < 1 || !in || !*in) - return (NULL); - - /* - * Convert from base-64 to bytes... - */ - - for (outptr = out, outend = out + *outlen - 1, pos = 0; *in != '\0'; in ++) - { - /* - * Decode this character into a number from 0 to 63... - */ - - if (*in >= 'A' && *in <= 'Z') - base64 = *in - 'A'; - else if (*in >= 'a' && *in <= 'z') - base64 = *in - 'a' + 26; - else if (*in >= '0' && *in <= '9') - base64 = *in - '0' + 52; - else if (*in == '+') - base64 = 62; - else if (*in == '/') - base64 = 63; - else if (*in == '=') - break; - else - continue; - - /* - * Store the result in the appropriate chars... - */ - - switch (pos) - { - case 0 : - if (outptr < outend) - *outptr = base64 << 2; - pos ++; - break; - case 1 : - if (outptr < outend) - *outptr++ |= (base64 >> 4) & 3; - if (outptr < outend) - *outptr = (base64 << 4) & 255; - pos ++; - break; - case 2 : - if (outptr < outend) - *outptr++ |= (base64 >> 2) & 15; - if (outptr < outend) - *outptr = (base64 << 6) & 255; - pos ++; - break; - case 3 : - if (outptr < outend) - *outptr++ |= base64; - pos = 0; - break; - } - } - - *outptr = '\0'; - - /* - * Return the decoded string and size... - */ - - *outlen = (int)(outptr - out); - - return (out); -} - - -/* - * 'httpEncode64()' - Base64-encode a string. - */ - -char * /* O - Encoded string */ -httpEncode64(char *out, /* I - String to write to */ - const char *in) /* I - String to read from */ -{ - return (httpEncode64_2(out, 512, in, strlen(in))); -} - - -/* - * 'httpEncode64_2()' - Base64-encode a string. - */ - -char * /* O - Encoded string */ -httpEncode64_2(char *out, /* I - String to write to */ - int outlen, /* I - Size of output string */ - const char *in, /* I - String to read from */ - int inlen) /* I - Size of input string */ -{ - char *outptr, /* Output pointer */ - *outend; /* End of output buffer */ - static const char base64[] = /* Base64 characters... */ - { - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789" - "+/" - }; - - - /* - * Range check input... - */ - - if (!out || outlen < 1 || !in || inlen < 1) - return (NULL); - - /* - * Convert bytes to base-64... - */ - - for (outptr = out, outend = out + outlen - 1; inlen > 0; in ++, inlen --) - { - /* - * Encode the up to 3 characters as 4 Base64 numbers... - */ - - if (outptr < outend) - *outptr ++ = base64[(in[0] & 255) >> 2]; - if (outptr < outend) - *outptr ++ = base64[(((in[0] & 255) << 4) | ((in[1] & 255) >> 4)) & 63]; - - in ++; - inlen --; - if (inlen <= 0) - { - if (outptr < outend) - *outptr ++ = '='; - if (outptr < outend) - *outptr ++ = '='; - break; - } - - if (outptr < outend) - *outptr ++ = base64[(((in[0] & 255) << 2) | ((in[1] & 255) >> 6)) & 63]; - - in ++; - inlen --; - if (inlen <= 0) - { - if (outptr < outend) - *outptr ++ = '='; - break; - } - - if (outptr < outend) - *outptr ++ = base64[in[0] & 63]; - } - - *outptr = '\0'; - - /* - * Return the encoded string... - */ - - return (out); -} - - -/* - * 'httpGetLength()' - Get the amount of data remaining from the - * content-length or transfer-encoding fields. - */ - -int /* O - Content length */ -httpGetLength(http_t *http) /* I - HTTP data */ -{ - DEBUG_printf(("httpGetLength(http=%p), state=%d\n", http, http->state)); - - if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0) - { - DEBUG_puts("httpGetLength: chunked request!"); - - http->data_encoding = HTTP_ENCODE_CHUNKED; - http->data_remaining = 0; - } - else - { - http->data_encoding = HTTP_ENCODE_LENGTH; - - /* - * The following is a hack for HTTP servers that don't send a - * content-length or transfer-encoding field... - * - * If there is no content-length then the connection must close - * after the transfer is complete... - */ - - if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0') - http->data_remaining = 2147483647; - else - http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]); - - DEBUG_printf(("httpGetLength: content_length=%d\n", http->data_remaining)); - } - - return (http->data_remaining); -} - - -/* - * 'http_field()' - Return the field index for a field name. - */ - -static http_field_t /* O - Field index */ -http_field(const char *name) /* I - String name */ -{ - int i; /* Looping var */ - - - for (i = 0; i < HTTP_FIELD_MAX; i ++) - if (strcasecmp(name, http_fields[i]) == 0) - return ((http_field_t)i); - - return (HTTP_FIELD_UNKNOWN); -} - - -/* - * 'http_send()' - Send a request with all fields and the trailing blank line. - */ - -static int /* O - 0 on success, non-zero on error */ -http_send(http_t *http, /* I - HTTP data */ - http_state_t request, /* I - Request code */ - const char *uri) /* I - URI */ -{ - int i; /* Looping var */ - char *ptr, /* Pointer in buffer */ - buf[1024]; /* Encoded URI buffer */ - static const char * const codes[] = - { /* Request code strings */ - NULL, - "OPTIONS", - "GET", - NULL, - "HEAD", - "POST", - NULL, - NULL, - "PUT", - NULL, - "DELETE", - "TRACE", - "CLOSE" - }; - static const char hex[] = "0123456789ABCDEF"; - /* Hex digits */ - - - DEBUG_printf(("http_send(http=%p, request=HTTP_%s, uri=\"%s\")\n", - http, codes[request], uri)); - - if (http == NULL || uri == NULL) - return (-1); - - /* - * Encode the URI as needed... - */ - - for (ptr = buf; *uri != '\0' && ptr < (buf + sizeof(buf) - 1); uri ++) - if (*uri <= ' ' || *uri >= 127) - { - if (ptr < (buf + sizeof(buf) - 1)) - *ptr ++ = '%'; - if (ptr < (buf + sizeof(buf) - 1)) - *ptr ++ = hex[(*uri >> 4) & 15]; - if (ptr < (buf + sizeof(buf) - 1)) - *ptr ++ = hex[*uri & 15]; - } - else - *ptr ++ = *uri; - - *ptr = '\0'; - - /* - * See if we had an error the last time around; if so, reconnect... - */ - - if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST) - httpReconnect(http); - - /* - * Send the request header... - */ - - http->state = request; - if (request == HTTP_POST || request == HTTP_PUT) - http->state ++; - - http->status = HTTP_CONTINUE; - -#ifdef HAVE_SSL - if (http->encryption == HTTP_ENCRYPT_REQUIRED && !http->tls) - { - httpSetField(http, HTTP_FIELD_CONNECTION, "Upgrade"); - httpSetField(http, HTTP_FIELD_UPGRADE, "TLS/1.0,SSL/2.0,SSL/3.0"); - } -#endif /* HAVE_SSL */ - - if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1) - { - http->status = HTTP_ERROR; - return (-1); - } - - for (i = 0; i < HTTP_FIELD_MAX; i ++) - if (http->fields[i][0] != '\0') - { - DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i])); - - if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1) - { - http->status = HTTP_ERROR; - return (-1); - } - } - - if (httpPrintf(http, "\r\n") < 1) - { - http->status = HTTP_ERROR; - return (-1); - } - - httpClearFields(http); - - return (0); -} - - -/* - * 'http_wait()' - Wait for data available on a connection. - */ - -static int /* O - 1 if data is available, 0 otherwise */ -http_wait(http_t *http, /* I - HTTP data */ - int msec) /* I - Milliseconds to wait */ -{ -#ifndef WIN32 - struct rlimit limit; /* Runtime limit */ -#endif /* !WIN32 */ - struct timeval timeout; /* Timeout */ - int nfds; /* Result from select() */ - int set_size; /* Size of select set */ - - - DEBUG_printf(("http_wait(http=%p, msec=%d)\n", http, msec)); - - /* - * Check the SSL/TLS buffers for data first... - */ - -#ifdef HAVE_SSL - if (http->tls) - { -# ifdef HAVE_LIBSSL - if (SSL_pending((SSL *)(http->tls))) - return (1); -# elif defined(HAVE_GNUTLS) - if (gnutls_record_check_pending(((http_tls_t *)(http->tls))->session)) - return (1); -# elif defined(HAVE_CDSASSL) - size_t bytes; /* Bytes that are available */ - - if (!SSLGetBufferedReadSize((SSLContextRef)http->tls, &bytes) && bytes > 0) - return; -# endif /* HAVE_LIBSSL */ - } -#endif /* HAVE_SSL */ - - /* - * Then try doing a select() to poll the socket... - */ - - if (!http->input_set) - { -#ifdef WIN32 - /* - * Windows has a fixed-size select() structure, different (surprise, - * surprise!) from all UNIX implementations. Just allocate this - * fixed structure... - */ - - http->input_set = calloc(1, sizeof(fd_set)); -#else - /* - * Allocate the select() input set based upon the max number of file - * descriptors available for this process... - */ - - getrlimit(RLIMIT_NOFILE, &limit); - - set_size = (limit.rlim_cur + 31) / 8 + 4; - if (set_size < sizeof(fd_set)) - set_size = sizeof(fd_set); - - http->input_set = calloc(1, set_size); -#endif /* WIN32 */ - - if (!http->input_set) - return (0); - } - - do - { - FD_SET(http->fd, http->input_set); - - if (msec >= 0) - { - timeout.tv_sec = msec / 1000; - timeout.tv_usec = (msec % 1000) * 1000; - - nfds = select(http->fd + 1, http->input_set, NULL, NULL, &timeout); - } - else - nfds = select(http->fd + 1, http->input_set, NULL, NULL, NULL); - } -#ifdef WIN32 - while (nfds < 0 && WSAGetLastError() == WSAEINTR); -#else - while (nfds < 0 && errno == EINTR); -#endif /* WIN32 */ - - FD_CLR(http->fd, http->input_set); - - return (nfds > 0); -} - - -#ifdef HAVE_SSL -/* - * 'http_upgrade()' - Force upgrade to TLS encryption. - */ - -static int /* O - Status of connection */ -http_upgrade(http_t *http) /* I - HTTP data */ -{ - int ret; /* Return value */ - http_t myhttp; /* Local copy of HTTP data */ - - - DEBUG_printf(("http_upgrade(%p)\n", http)); - - /* - * Copy the HTTP data to a local variable so we can do the OPTIONS - * request without interfering with the existing request data... - */ - - memcpy(&myhttp, http, sizeof(myhttp)); - - /* - * Send an OPTIONS request to the server, requiring SSL or TLS - * encryption on the link... - */ - - httpClearFields(&myhttp); - httpSetField(&myhttp, HTTP_FIELD_CONNECTION, "upgrade"); - httpSetField(&myhttp, HTTP_FIELD_UPGRADE, "TLS/1.0, SSL/2.0, SSL/3.0"); - - if ((ret = httpOptions(&myhttp, "*")) == 0) - { - /* - * Wait for the secure connection... - */ - - while (httpUpdate(&myhttp) == HTTP_CONTINUE); - } - - httpFlush(&myhttp); - - /* - * Copy the HTTP data back over, if any... - */ - - http->fd = myhttp.fd; - http->error = myhttp.error; - http->activity = myhttp.activity; - http->status = myhttp.status; - http->version = myhttp.version; - http->keep_alive = myhttp.keep_alive; - http->used = myhttp.used; - - if (http->used) - memcpy(http->buffer, myhttp.buffer, http->used); - - http->auth_type = myhttp.auth_type; - http->nonce_count = myhttp.nonce_count; - - memcpy(http->nonce, myhttp.nonce, sizeof(http->nonce)); - - http->tls = myhttp.tls; - http->encryption = myhttp.encryption; - - /* - * See if we actually went secure... - */ - - if (!http->tls) - { - /* - * Server does not support HTTP upgrade... - */ - - DEBUG_puts("Server does not support HTTP upgrade!"); - -# ifdef WIN32 - closesocket(http->fd); -# else - close(http->fd); -# endif - - http->fd = -1; - - return (-1); - } - else - return (ret); -} - - -/* - * 'http_setup_ssl()' - Set up SSL/TLS support on a connection. - */ - -static int /* O - Status of connection */ -http_setup_ssl(http_t *http) /* I - HTTP data */ -{ -# ifdef HAVE_LIBSSL - SSL_CTX *context; /* Context for encryption */ - SSL *conn; /* Connection for encryption */ -# elif defined(HAVE_GNUTLS) - http_tls_t *conn; /* TLS session object */ - gnutls_certificate_client_credentials *credentials; - /* TLS credentials */ -# elif defined(HAVE_CDSASSL) - SSLContextRef conn; /* Context for encryption */ - OSStatus error; /* Error info */ -# endif /* HAVE_LIBSSL */ - - - DEBUG_printf(("http_setup_ssl(http=%p)\n", http)); - -# ifdef HAVE_LIBSSL - context = SSL_CTX_new(SSLv23_client_method()); - - SSL_CTX_set_options(context, SSL_OP_NO_SSLv2); /* Only use SSLv3 or TLS */ - - conn = SSL_new(context); - - SSL_set_fd(conn, http->fd); - if (SSL_connect(conn) != 1) - { -# ifdef DEBUG - unsigned long error; /* Error code */ - - while ((error = ERR_get_error()) != 0) - printf("http_setup_ssl: %s\n", ERR_error_string(error, NULL)); -# endif /* DEBUG */ - - SSL_CTX_free(context); - SSL_free(conn); - -# ifdef WIN32 - http->error = WSAGetLastError(); -# else - http->error = errno; -# endif /* WIN32 */ - http->status = HTTP_ERROR; - - return (HTTP_ERROR); - } - -# elif defined(HAVE_GNUTLS) - conn = (http_tls_t *)malloc(sizeof(http_tls_t)); - - if (conn == NULL) - { - http->error = errno; - http->status = HTTP_ERROR; - - return (-1); - } - - credentials = (gnutls_certificate_client_credentials *) - malloc(sizeof(gnutls_certificate_client_credentials)); - if (credentials == NULL) - { - free(conn); - - http->error = errno; - http->status = HTTP_ERROR; - - return (-1); - } - - gnutls_certificate_allocate_credentials(credentials); - - gnutls_init(&(conn->session), GNUTLS_CLIENT); - gnutls_set_default_priority(conn->session); - gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, *credentials); - gnutls_transport_set_ptr(conn->session, http->fd); - - if ((gnutls_handshake(conn->session)) != GNUTLS_E_SUCCESS) - { - http->error = errno; - http->status = HTTP_ERROR; - - return (-1); - } - - conn->credentials = credentials; - -# elif defined(HAVE_CDSASSL) - error = SSLNewContext(false, &conn); - - if (!error) - error = SSLSetIOFuncs(conn, CDSAReadFunc, CDSAWriteFunc); - - if (!error) - error = SSLSetConnection(conn, (SSLConnectionRef)http->fd); - - if (!error) - error = SSLSetAllowsExpiredCerts(conn, true); - - if (!error) - error = SSLSetAllowsAnyRoot(conn, true); - - if (!error) - error = SSLHandshake(conn); - - if (error != 0) - { - http->error = error; - http->status = HTTP_ERROR; - - SSLDisposeContext(conn); - - close(http->fd); - - return (-1); - } -# endif /* HAVE_CDSASSL */ - - http->tls = conn; - return (0); -} - - -/* - * 'http_shutdown_ssl()' - Shut down SSL/TLS on a connection. - */ - -static void -http_shutdown_ssl(http_t *http) /* I - HTTP data */ -{ -# ifdef HAVE_LIBSSL - SSL_CTX *context; /* Context for encryption */ - SSL *conn; /* Connection for encryption */ - - - conn = (SSL *)(http->tls); - context = SSL_get_SSL_CTX(conn); - - SSL_shutdown(conn); - SSL_CTX_free(context); - SSL_free(conn); - -# elif defined(HAVE_GNUTLS) - http_tls_t *conn; /* Encryption session */ - gnutls_certificate_client_credentials *credentials; - /* TLS credentials */ - - - conn = (http_tls_t *)(http->tls); - credentials = (gnutls_certificate_client_credentials *)(conn->credentials); - - gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); - gnutls_deinit(conn->session); - gnutls_certificate_free_credentials(*credentials); - free(credentials); - free(conn); - -# elif defined(HAVE_CDSASSL) - SSLClose((SSLContextRef)http->tls); - SSLDisposeContext((SSLContextRef)http->tls); -# endif /* HAVE_LIBSSL */ - - http->tls = NULL; -} - - -/* - * 'http_read_ssl()' - Read from a SSL/TLS connection. - */ - -static int /* O - Bytes read */ -http_read_ssl(http_t *http, /* I - HTTP data */ - char *buf, /* I - Buffer to store data */ - int len) /* I - Length of buffer */ -{ -# if defined(HAVE_LIBSSL) - return (SSL_read((SSL *)(http->tls), buf, len)); - -# elif defined(HAVE_GNUTLS) - return (gnutls_record_recv(((http_tls_t *)(http->tls))->session, buf, len)); - -# elif defined(HAVE_CDSASSL) - OSStatus error; /* Error info */ - size_t processed; /* Number of bytes processed */ - - - error = SSLRead((SSLContextRef)http->tls, buf, len, &processed); - - if (error == 0) - return (processed); - else - { - http->error = error; - - return (-1); - } -# endif /* HAVE_LIBSSL */ -} - - -/* - * 'http_write_ssl()' - Write to a SSL/TLS connection. - */ - -static int /* O - Bytes written */ -http_write_ssl(http_t *http, /* I - HTTP data */ - const char *buf, /* I - Buffer holding data */ - int len) /* I - Length of buffer */ -{ -# if defined(HAVE_LIBSSL) - return (SSL_write((SSL *)(http->tls), buf, len)); - -# elif defined(HAVE_GNUTLS) - return (gnutls_record_send(((http_tls_t *)(http->tls))->session, buf, len)); -# elif defined(HAVE_CDSASSL) - OSStatus error; /* Error info */ - size_t processed; /* Number of bytes processed */ - - - error = SSLWrite((SSLContextRef)http->tls, buf, len, &processed); - - if (error == 0) - return (processed); - else - { - http->error = error; - return (-1); - } -# endif /* HAVE_LIBSSL */ -} - - -# if defined(HAVE_CDSASSL) -/* - * 'CDSAReadFunc()' - Read function for CDSA decryption code. - */ - -static OSStatus /* O - -1 on error, 0 on success */ -CDSAReadFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */ - void *data, /* I - Data buffer */ - size_t *dataLength) /* IO - Number of bytes */ -{ - ssize_t bytes; /* Number of bytes read */ - -#ifdef DEBUG_HTTP - httpDumpData(stdout, "CDSAReadFunc:", data, *dataLength); -#endif - bytes = recv((int)connection, data, *dataLength, 0); - if (bytes >= 0) - { - *dataLength = bytes; - return (0); - } - else - return (-1); -} - - -/* - * 'CDSAWriteFunc()' - Write function for CDSA encryption code. - */ - -static OSStatus /* O - -1 on error, 0 on success */ -CDSAWriteFunc(SSLConnectionRef connection, /* I - SSL/TLS connection */ - const void *data, /* I - Data buffer */ - size_t *dataLength) /* IO - Number of bytes */ -{ - ssize_t bytes; - - - bytes = write((int)connection, data, *dataLength); - if (bytes >= 0) - { - *dataLength = bytes; - return (0); - } - else - return (-1); -} -# endif /* HAVE_CDSASSL */ -#endif /* HAVE_SSL */ - - -/* - * End of "$Id: http.c 148 2006-04-25 16:54:17Z njacobs $" - */ diff --git a/usr/src/lib/print/libhttp-core/common/http.h b/usr/src/lib/print/libhttp-core/common/http.h deleted file mode 100644 index 593b7b68f6..0000000000 --- a/usr/src/lib/print/libhttp-core/common/http.h +++ /dev/null @@ -1,439 +0,0 @@ -/* - * "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" - * - * Hyper-Text Transport Protocol definitions for the Common UNIX Printing - * System (CUPS). - * - * Copyright 1997-2005 by Easy Software Products, all rights reserved. - * - * These coded instructions, statements, and computer programs are the - * property of Easy Software Products and are protected by Federal - * copyright law. Distribution and use rights are outlined in the file - * "LICENSE.txt" which should have been included with this file. If this - * file is missing or damaged please contact Easy Software Products - * at: - * - * Attn: CUPS Licensing Information - * Easy Software Products - * 44141 Airport View Drive, Suite 204 - * Hollywood, Maryland 20636 USA - * - * Voice: (301) 373-9600 - * EMail: cups-info@cups.org - * WWW: http://www.cups.org - * - * This file is subject to the Apple OS-Developed Software exception. - */ - -#ifndef _CUPS_HTTP_H_ -#define _CUPS_HTTP_H_ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Include necessary headers... - */ - -# include <string.h> -# include <time.h> -# ifdef WIN32 -# include <winsock.h> -# else -# include <unistd.h> -# include <sys/time.h> -# include <sys/types.h> -# include <sys/socket.h> -# include <netdb.h> -# include <netinet/in.h> -# include <arpa/inet.h> -# include <netinet/in_systm.h> -# include <netinet/ip.h> -# if !defined(__APPLE__) || !defined(TCP_NODELAY) -# include <netinet/tcp.h> -# endif /* !__APPLE__ || !TCP_NODELAY */ -# ifdef AF_LOCAL -# include <sys/un.h> -# endif /* AF_LOCAL */ -# endif /* WIN32 */ - - -/* - * C++ magic... - */ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * Oh, the wonderful world of IPv6 compatibility. Apparently some - * implementations expose the (more logical) 32-bit address parts - * to everyone, while others only expose it to kernel code... To - * make supporting IPv6 even easier, each vendor chose different - * core structure and union names, so the same defines or code - * can't be used on all platforms. - * - * The following will likely need tweeking on new platforms that - * support IPv6 - the "s6_addr32" define maps to the 32-bit integer - * array in the in6_addr union, which is named differently on various - * platforms. - */ - -#if defined(AF_INET6) && !defined(s6_addr32) -# if defined(__sun) -# define s6_addr32 _S6_un._S6_u32 -# elif defined(__FreeBSD__) || defined(__APPLE__) -# define s6_addr32 __u6_addr.__u6_addr32 -# endif /* __sun */ -#endif /* AF_INET6 && !s6_addr32 */ - - -/* - * Limits... - */ - -# define HTTP_MAX_URI 1024 /* Max length of URI string */ -# define HTTP_MAX_HOST 256 /* Max length of hostname string */ -# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */ -# define HTTP_MAX_VALUE 256 /* Max header field value length */ - - -/* - * HTTP state values... - */ - -typedef enum /* States are server-oriented */ -{ - HTTP_WAITING, /* Waiting for command */ - HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */ - HTTP_GET, /* GET command, waiting for blank line */ - HTTP_GET_SEND, /* GET command, sending data */ - HTTP_HEAD, /* HEAD command, waiting for blank line */ - HTTP_POST, /* POST command, waiting for blank line */ - HTTP_POST_RECV, /* POST command, receiving data */ - HTTP_POST_SEND, /* POST command, sending data */ - HTTP_PUT, /* PUT command, waiting for blank line */ - HTTP_PUT_RECV, /* PUT command, receiving data */ - HTTP_DELETE, /* DELETE command, waiting for blank line */ - HTTP_TRACE, /* TRACE command, waiting for blank line */ - HTTP_CLOSE, /* CLOSE command, waiting for blank line */ - HTTP_STATUS /* Command complete, sending status */ -} http_state_t; - - -/* - * HTTP version numbers... - */ - -typedef enum -{ - HTTP_0_9 = 9, /* HTTP/0.9 */ - HTTP_1_0 = 100, /* HTTP/1.0 */ - HTTP_1_1 = 101 /* HTTP/1.1 */ -} http_version_t; - - -/* - * HTTP keep-alive values... - */ - -typedef enum -{ - HTTP_KEEPALIVE_OFF = 0, - HTTP_KEEPALIVE_ON -} http_keepalive_t; - - -/* - * HTTP transfer encoding values... - */ - -typedef enum -{ - HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ - HTTP_ENCODE_CHUNKED /* Data is chunked */ -} http_encoding_t; - - -/* - * HTTP encryption values... - */ - -typedef enum -{ - HTTP_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */ - HTTP_ENCRYPT_NEVER, /* Never encrypt */ - HTTP_ENCRYPT_REQUIRED, /* Encryption is required (TLS upgrade) */ - HTTP_ENCRYPT_ALWAYS /* Always encrypt (SSL) */ -} http_encryption_t; - - -/* - * HTTP authentication types... - */ - -typedef enum -{ - HTTP_AUTH_NONE, /* No authentication in use */ - HTTP_AUTH_BASIC, /* Basic authentication in use */ - HTTP_AUTH_MD5, /* Digest authentication in use */ - HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */ - HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */ - HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */ -} http_auth_t; - - -/* - * HTTP status codes... - */ - -typedef enum -{ - HTTP_ERROR = -1, /* An error response from httpXxxx() */ - - HTTP_CONTINUE = 100, /* Everything OK, keep going... */ - HTTP_SWITCHING_PROTOCOLS, /* HTTP upgrade to TLS/SSL */ - - HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */ - HTTP_CREATED, /* PUT command was successful */ - HTTP_ACCEPTED, /* DELETE command was successful */ - HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */ - HTTP_NO_CONTENT, /* Successful command, no new data */ - HTTP_RESET_CONTENT, /* Content was reset/recreated */ - HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */ - - HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */ - HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */ - HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */ - HTTP_SEE_OTHER, /* See this other link... */ - HTTP_NOT_MODIFIED, /* File not modified */ - HTTP_USE_PROXY, /* Must use a proxy to access this URI */ - - HTTP_BAD_REQUEST = 400, /* Bad request */ - HTTP_UNAUTHORIZED, /* Unauthorized to access host */ - HTTP_PAYMENT_REQUIRED, /* Payment required */ - HTTP_FORBIDDEN, /* Forbidden to access this URI */ - HTTP_NOT_FOUND, /* URI was not found */ - HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */ - HTTP_NOT_ACCEPTABLE, /* Not Acceptable */ - HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */ - HTTP_REQUEST_TIMEOUT, /* Request timed out */ - HTTP_CONFLICT, /* Request is self-conflicting */ - HTTP_GONE, /* Server has gone away */ - HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */ - HTTP_PRECONDITION, /* Precondition failed */ - HTTP_REQUEST_TOO_LARGE, /* Request entity too large */ - HTTP_URI_TOO_LONG, /* URI too long */ - HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */ - HTTP_UPGRADE_REQUIRED = 426, /* Upgrade to SSL/TLS required */ - - HTTP_SERVER_ERROR = 500, /* Internal server error */ - HTTP_NOT_IMPLEMENTED, /* Feature not implemented */ - HTTP_BAD_GATEWAY, /* Bad gateway */ - HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */ - HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */ - HTTP_NOT_SUPPORTED /* HTTP version not supported */ -} http_status_t; - - -/* - * HTTP field names... - */ - -typedef enum -{ - HTTP_FIELD_UNKNOWN = -1, - HTTP_FIELD_ACCEPT_LANGUAGE, - HTTP_FIELD_ACCEPT_RANGES, - HTTP_FIELD_AUTHORIZATION, - HTTP_FIELD_CONNECTION, - HTTP_FIELD_CONTENT_ENCODING, - HTTP_FIELD_CONTENT_LANGUAGE, - HTTP_FIELD_CONTENT_LENGTH, - HTTP_FIELD_CONTENT_LOCATION, - HTTP_FIELD_CONTENT_MD5, - HTTP_FIELD_CONTENT_RANGE, - HTTP_FIELD_CONTENT_TYPE, - HTTP_FIELD_CONTENT_VERSION, - HTTP_FIELD_DATE, - HTTP_FIELD_HOST, - HTTP_FIELD_IF_MODIFIED_SINCE, - HTTP_FIELD_IF_UNMODIFIED_SINCE, - HTTP_FIELD_KEEP_ALIVE, - HTTP_FIELD_LAST_MODIFIED, - HTTP_FIELD_LINK, - HTTP_FIELD_LOCATION, - HTTP_FIELD_RANGE, - HTTP_FIELD_REFERER, - HTTP_FIELD_RETRY_AFTER, - HTTP_FIELD_TRANSFER_ENCODING, - HTTP_FIELD_UPGRADE, - HTTP_FIELD_USER_AGENT, - HTTP_FIELD_WWW_AUTHENTICATE, - HTTP_FIELD_MAX -} http_field_t; - - -/* - * HTTP address structure (makes using IPv6 a little easier and more portable.) - */ - -typedef union -{ - struct sockaddr addr; /* Base structure for family value */ - struct sockaddr_in ipv4; /* IPv4 address */ -#ifdef AF_INET6 - struct sockaddr_in6 ipv6; /* IPv6 address */ -#endif /* AF_INET6 */ -#ifdef AF_LOCAL - struct sockaddr_un un; /* Domain socket file */ -#endif /* AF_LOCAL */ - char pad[128]; /* Pad to ensure binary compatibility */ -} http_addr_t; - -/* - * HTTP connection structure... - */ - -typedef struct -{ - int fd; /* File descriptor for this socket */ - int blocking; /* To block or not to block */ - int error; /* Last error on read */ - time_t activity; /* Time since last read/write */ - http_state_t state; /* State of client */ - http_status_t status; /* Status of last request */ - http_version_t version; /* Protocol version */ - http_keepalive_t keep_alive; /* Keep-alive supported? */ - struct sockaddr_in oldaddr; /* Address of connected host */ - char hostname[HTTP_MAX_HOST], - /* Name of connected host */ - fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE]; - /* Field values */ - char *data; /* Pointer to data buffer */ - http_encoding_t data_encoding; /* Chunked or not */ - int data_remaining; /* Number of bytes left */ - int used; /* Number of bytes used in buffer */ - char buffer[HTTP_MAX_BUFFER]; - /* Buffer for messages */ - int auth_type; /* Authentication in use */ - char nonce[HTTP_MAX_VALUE]; - /* Nonce value */ - int nonce_count; /* Nonce count */ - void *tls; /* TLS state information */ - http_encryption_t encryption; /* Encryption requirements */ - /**** New in CUPS 1.1.19 ****/ - fd_set *input_set; /* select() set for httpWait() */ - http_status_t expect; /* Expect: header */ - char *cookie; /* Cookie value(s) */ - /**** New in CUPS 1.1.20 ****/ - char authstring[HTTP_MAX_VALUE], - /* Current Authentication value */ - userpass[HTTP_MAX_VALUE]; - /* Username:password string */ - int digest_tries; /* Number of tries for digest auth */ - /**** New in CUPS 1.2 ****/ - http_addr_t hostaddr; /* Host address and port */ -} http_t; - - -/* - * Prototypes... - */ - -# define httpBlocking(http,b) (http)->blocking = (b) -extern int httpCheck(http_t *http); -# define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\ - httpSetField((http), HTTP_FIELD_HOST, (http)->hostname) -extern void httpClose(http_t *http); -extern http_t *httpConnect(const char *host, int port); -extern http_t *httpConnectEncrypt(const char *host, int port, - http_encryption_t encrypt); -extern int httpDelete(http_t *http, const char *uri); -extern int httpEncryption(http_t *http, http_encryption_t e); -# define httpError(http) ((http)->error) -extern void httpFlush(http_t *http); -extern int httpGet(http_t *http, const char *uri); -extern char *httpGets(char *line, int length, http_t *http); -extern const char *httpGetDateString(time_t t); -extern time_t httpGetDateTime(const char *s); -# define httpGetField(http,field) (http)->fields[field] -extern struct hostent *httpGetHostByName(const char *name); -extern char *httpGetSubField(http_t *http, http_field_t field, - const char *name, char *value); -extern int httpHead(http_t *http, const char *uri); -extern void httpInitialize(void); -extern int httpOptions(http_t *http, const char *uri); -extern int httpPost(http_t *http, const char *uri); -extern int httpPrintf(http_t *http, const char *format, ...) -# ifdef __GNUC__ -__attribute__ ((__format__ (__printf__, 2, 3))) -# endif /* __GNUC__ */ -; -extern int httpPut(http_t *http, const char *uri); -extern int httpRead(http_t *http, char *buffer, int length); -extern int httpReconnect(http_t *http); -extern void httpSeparate(const char *uri, char *method, - char *username, char *host, int *port, - char *resource); -extern void httpSetField(http_t *http, http_field_t field, - const char *value); -extern const char *httpStatus(http_status_t status); -extern int httpTrace(http_t *http, const char *uri); -extern http_status_t httpUpdate(http_t *http); -extern int httpWrite(http_t *http, const char *buffer, int length); -extern char *httpEncode64(char *out, const char *in); -extern char *httpDecode64(char *out, const char *in); -extern int httpGetLength(http_t *http); -extern char *httpMD5(const char *, const char *, const char *, - char [33]); -extern char *httpMD5Final(const char *, const char *, const char *, - char [33]); -extern char *httpMD5String(const unsigned char *, char [33]); - -/**** New in CUPS 1.1.19 ****/ -extern void httpClearCookie(http_t *http); -#define httpGetCookie(http) ((http)->cookie) -extern void httpSetCookie(http_t *http, const char *cookie); -extern int httpWait(http_t *http, int msec); - -/**** New in CUPS 1.1.21 ****/ -extern char *httpDecode64_2(char *out, int *outlen, const char *in); -extern char *httpEncode64_2(char *out, int outlen, const char *in, - int inlen); -extern void httpSeparate2(const char *uri, - char *method, int methodlen, - char *username, int usernamelen, - char *host, int hostlen, int *port, - char *resource, int resourcelen); - -/**** New in CUPS 1.2 ****/ -extern int httpAddrAny(const http_addr_t *addr); -extern int httpAddrEqual(const http_addr_t *addr1, - const http_addr_t *addr2); -extern void httpAddrLoad(const struct hostent *host, int port, - int n, http_addr_t *addr); -extern int httpAddrLocalhost(const http_addr_t *addr); -extern char *httpAddrLookup(const http_addr_t *addr, - char *name, int namelen); -extern char *httpAddrString(const http_addr_t *addr, - char *s, int slen); - -#include <stdio.h> -extern void httpDumpData(FILE *, const char *, const char *, int); - - -/* - * C++ magic... - */ - -#ifdef __cplusplus -} -#endif - -#endif /* !_CUPS_HTTP_H_ */ - -/* - * End of "$Id: http.h 148 2006-04-25 16:54:17Z njacobs $" - */ diff --git a/usr/src/lib/print/libipp-core/Makefile b/usr/src/lib/print/libipp-core/Makefile deleted file mode 100644 index b92d620b10..0000000000 --- a/usr/src/lib/print/libipp-core/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) - -install_h: # $(ROOTHDRS) - -check: # $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/Makefile.com b/usr/src/lib/print/libipp-core/Makefile.com deleted file mode 100644 index 26f48c2dbb..0000000000 --- a/usr/src/lib/print/libipp-core/Makefile.com +++ /dev/null @@ -1,59 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = libipp-core.a -VERS = .0 -OBJECTS = ipp.o ipp_types.o read.o strings.o write.o - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common - -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-char-subscripts -CERRWARN += -_gcc=-Wno-switch - -MAPFILES = $(SRCDIR)/mapfile - -LDLIBS += -lpapi-common -lc - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libipp-core/common/ipp.c b/usr/src/lib/print/libipp-core/common/ipp.c deleted file mode 100644 index 133fb0ad13..0000000000 --- a/usr/src/lib/print/libipp-core/common/ipp.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: ipp.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdarg.h> -#include <papi.h> -#include "ipp.h" - -/* - * IPP requests/responses are represented as attribute lists. An IPP request - * attribute list will contain header information attributes: - * version-major (int) - * version-minor (int) - * request-id (int) - * operation-id (int) - * It will also contain 1 or more attribute groups (collections) - * operational-attribute-group - * ... - * this routine validates that the request falls within the guidelines of - * the protocol specification (or some other level of conformance if the - * restrictions have been specified at the top level of the request using - * a "conformance" attribute. - */ -papi_status_t -ipp_validate_request(papi_attribute_t **request, papi_attribute_t ***response) -{ - papi_attribute_t **attributes = NULL; - papi_status_t result = PAPI_OK; - char *s; - - if ((request == NULL) || (response == NULL) || (*response == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* validate the operational attributes group */ - result = papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &attributes); - if (result != PAPI_OK) { - ipp_set_status(response, result, - "operational attribute group: %s", - papiStatusString(result)); - return (result); - } - - result = papiAttributeListGetString(attributes, NULL, - "attributes-charset", &s); - if (result != PAPI_OK) { - ipp_set_status(response, result, "attributes-charset: %s", - papiStatusString(result)); - return (result); - } - - result = papiAttributeListGetString(attributes, NULL, - "attributes-natural-language", &s); - if (result != PAPI_OK) { - ipp_set_status(response, result, - "attributes-natural-language: %s", - papiStatusString(result)); - return (result); - } - - return (result); -} - -/* - * Add/Modify the statuse-code and status-message in an IPP response's - * operational attributes group. - */ -void -ipp_set_status(papi_attribute_t ***message, papi_status_t status, - char *format, ...) -{ - if (message == NULL) - return; - - if (format != NULL) { - papi_attribute_t **operational = NULL; - papi_attribute_t **saved; - char mesg[256]; /* status-message is type text(255) */ - va_list ap; - - (void) papiAttributeListGetCollection(*message, NULL, - "operational-attributes-group", - &operational); - saved = operational; - - va_start(ap, format); - (void) vsnprintf(mesg, sizeof (mesg), format, ap); - va_end(ap); - - (void) papiAttributeListAddString(&operational, - PAPI_ATTR_APPEND, "status-message", mesg); - - /* - * We need to check and see if adding the status-message caused - * the operational attributes group to be relocated in memory. - * If it has been, we will need to re-add the collection to - * the message. - */ - if (saved != operational) - (void) papiAttributeListAddCollection(message, - PAPI_ATTR_REPLACE, - "operational-attributes-group", - operational); - } - - (void) papiAttributeListAddInteger(message, PAPI_ATTR_APPEND, - "status-code", status); -} diff --git a/usr/src/lib/print/libipp-core/common/ipp.h b/usr/src/lib/print/libipp-core/common/ipp.h deleted file mode 100644 index c13728e334..0000000000 --- a/usr/src/lib/print/libipp-core/common/ipp.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _IPP_H -#define _IPP_H - -/* $Id: ipp.h 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdarg.h> -#include <sys/time.h> -#include <papi.h> -#include <inttypes.h> - - -typedef ssize_t (*ipp_reader_t)(void *fd, void *buffer, size_t buffer_size); -typedef ssize_t (*ipp_writer_t)(void *fd, void *buffer, size_t buffer_size); - -enum { - IPP_TYPE_UNKNOWN = 0, - IPP_TYPE_REQUEST = 1, - IPP_TYPE_RESPONSE = 2 -}; - -/* - * How closely do we conform to the spec when parsing? Do we - * a) Stop parsing only when we encounter an error that prevents us from - * continuing parsing (a server error or ridiculously malformed request)? - * b) Stop parsing when we know the server wouldn't be able to act on the - * response correctly, even if we can make sense of some of the data? - * c) Jawohl, Mein IPP Spec! - * The answer will usually be b, though a will be useful for debugging. - */ -enum { - IPP_PARSE_CONFORMANCE_RASH = 0, - IPP_PARSE_CONFORMANCE_LOOSE = 1, - IPP_PARSE_CONFORMANCE_STRICT = 2 -}; - - -/* Operation IDs */ -enum { - OPID_MIN = 0x0000, /* 0x0000 */ - OPID_RESERVED_0000 = 0x0000, /* 0x0000 */ - OPID_RESERVED_0001, /* 0x0001 */ - OPID_PRINT_JOB, /* 0x0002 */ - OPID_PRINT_URI, /* 0x0003 */ - OPID_VALIDATE_JOB, /* 0x0004 */ - OPID_CREATE_JOB, /* 0x0005 */ - OPID_SEND_DOCUMENT, /* 0x0006 */ - OPID_SEND_URI, /* 0x0007 */ - OPID_CANCEL_JOB, /* 0x0008 */ - OPID_GET_JOB_ATTRIBUTES, /* 0x0009 */ - OPID_GET_JOBS, /* 0x000a */ - OPID_GET_PRINTER_ATTRIBUTES, /* 0x000b */ - OPID_HOLD_JOB, /* 0x000c */ - OPID_RELEASE_JOB, /* 0x000d */ - OPID_RESTART_JOB, /* 0x000e */ - OPID_RESERVED_000F, /* 0x000f */ - OPID_PAUSE_PRINTER, /* 0x0010 */ - OPID_RESUME_PRINTER, /* 0x0011 */ - OPID_PURGE_JOBS, /* 0x0012 */ - OPID_SET_PRINTER_ATTRIBUTES, /* 0x0013 */ - OPID_SET_JOB_ATTRIBUTES, /* 0x0014 */ - OPID_GET_PRINTER_SUPPORTED_VALUES, /* 0x0015 */ - OPID_CREATE_PRINTER_SUBSCRIPTION, /* 0x0016 */ - OPID_CREATE_JOB_SUBSCRIPTION, /* 0x0017 */ - OPID_GET_SUBSCRIPTION_ATTRIBUTES, /* 0x0018 */ - OPID_GET_SUBSCRIPTIONS, /* 0x0019 */ - OPID_RENEW_SUBSCRIPTION, /* 0x001a */ - OPID_CANCEL_SUBSCRIPTION, /* 0x001b */ - OPID_GET_NOTIFICATIONS, /* 0x001c */ - OPID_SEND_NOTIFICATIONS, /* 0x001d */ - OPID_GET_RESOURCE_ATTRIBUTES, /* 0x001e */ - OPID_GET_RESOURCE_DATA, /* 0x001f */ - OPID_GET_RESOURCES, /* 0x0020 */ - OPID_GET_PRINT_SUPPORT_FILES, /* 0x0021 */ - OPID_ENABLE_PRINTER, /* 0x0022 */ - OPID_DISABLE_PRINTER, /* 0x0023 */ - OPID_PAUSE_PRINTER_AFTER_CURRENT_JOB, /* 0x0024 */ - OPID_HOLD_NEW_JOBS, /* 0x0025 */ - OPID_RELEASE_HELD_NEW_JOBS, /* 0x0026 */ - OPID_DEACTIVATE_PRINTER, /* 0x0027 */ - OPID_ACTIVATE_PRINTER, /* 0x0028 */ - OPID_RESTART_PRINTER, /* 0x0029 */ - OPID_SHUTDOWN_PRINTER, /* 0x002a */ - OPID_STARTUP_PRINTER, /* 0x002b */ - OPID_REPROCESS_JOB, /* 0x002c */ - OPID_CANCEL_CURRENT_JOB, /* 0x002d */ - OPID_SUSPEND_CURRENT_JOB, /* 0x002e */ - OPID_RESUME_JOB, /* 0x002f */ - OPID_PROMOTE_JOB, /* 0x0030 */ - OPID_SCHEDULE_JOB_AFTER, /* 0x0031 */ - OPID_RESERVED_MIN, /* 0x0032 */ - OPID_RESERVED_0032 = 0x0032, /* 0x0032 */ - /* ... */ - OPID_RESERVED_3FFF = 0x3fff, /* 0x3fff */ - OPID_RESERVED_MAX = 0x3fff, /* 0x3fff */ - OPID_RESERVED_VENDOR_MIN = 0x4000, /* 0x4000 */ - OPID_RESERVED_VENDOR_4000 = 0x4000, /* 0x4000 */ - /* ... */ - OPID_RESERVED_VENDOR_8FFF = 0x8fff, /* 0x8fff */ - OPID_RESERVED_VENDOR_MAX = 0x8fff, /* 0x8fff */ - OPID_MAX = 0x8fff /* 0x8fff */ -}; - -enum { - /* Delimiter Tags */ - DTAG_MIN = 0x00, /* 0x00 */ - DTAG_RESERVED_DELIMITER_00 = 0x00, /* 0x00 */ - DTAG_OPERATION_ATTRIBUTES, /* 0x01 */ - DTAG_JOB_ATTRIBUTES, /* 0x02 */ - DTAG_END_OF_ATTRIBUTES, /* 0x03 */ - DTAG_PRINTER_ATTRIBUTES, /* 0x04 */ - DTAG_UNSUPPORTED_ATTRIBUTES, /* 0x05 */ - DTAG_SUBSCRIPTION_ATTRIBUTES, /* 0x06 */ - DTAG_EVENT_NOTIFICATION_ATTRIBUTES, /* 0x07 */ - DTAG_RESERVED_DELIMITER_08, /* 0x08 */ - DTAG_RESERVED_DELIMITER_09, /* 0x09 */ - DTAG_RESERVED_DELIMITER_0A, /* 0x0a */ - DTAG_RESERVED_DELIMITER_0B, /* 0x0b */ - DTAG_RESERVED_DELIMITER_0C, /* 0x0c */ - DTAG_RESERVED_DELIMITER_0D, /* 0x0d */ - DTAG_RESERVED_DELIMITER_0E, /* 0x0e */ - DTAG_RESERVED_DELIMITER_0F, /* 0x0f */ - DTAG_MAX = 0x0f, /* 0x0f */ - - /* Value Tags */ - VTAG_MIN = 0x10, /* 0x10 */ - VTAG_UNSUPPORTED = 0x10, /* 0x10 */ - VTAG_RESERVED_DEFAULT, /* 0x11 */ - VTAG_UNKNOWN, /* 0x12 */ - VTAG_NOVALUE, /* 0x13 */ - VTAG_RESERVED_OOB_14, /* 0x14 */ - VTAG_NOT_SETTABLE, /* 0x15 */ - VTAG_DELETE_ATTRIBUTE, /* 0x16 */ - VTAG_ADMIN_DEFINE, /* 0x17 */ - VTAG_RESERVED_OOB_18, /* 0x18 */ - VTAG_RESERVED_OOB_19, /* 0x19 */ - VTAG_RESERVED_OOB_1A, /* 0x1a */ - VTAG_RESERVED_OOB_1B, /* 0x1b */ - VTAG_RESERVED_OOB_1C, /* 0x1c */ - VTAG_RESERVED_OOB_1D, /* 0x1d */ - VTAG_RESERVED_OOB_1E, /* 0x1e */ - VTAG_RESERVED_OOB_1F, /* 0x1f */ - VTAG_RESERVED_INT_GEN, /* 0x20 */ - VTAG_INTEGER, /* 0x21 */ - VTAG_BOOLEAN, /* 0x22 */ - VTAG_ENUM, /* 0x23 */ - VTAG_RESERVED_INT_24, /* 0x24 */ - VTAG_RESERVED_INT_25, /* 0x25 */ - VTAG_RESERVED_INT_26, /* 0x26 */ - VTAG_RESERVED_INT_27, /* 0x27 */ - VTAG_RESERVED_INT_28, /* 0x28 */ - VTAG_RESERVED_INT_29, /* 0x29 */ - VTAG_RESERVED_INT_2A, /* 0x2a */ - VTAG_RESERVED_INT_2B, /* 0x2b */ - VTAG_RESERVED_INT_2C, /* 0x2c */ - VTAG_RESERVED_INT_2D, /* 0x2d */ - VTAG_RESERVED_INT_2E, /* 0x2e */ - VTAG_RESERVED_INT_2F, /* 0x2f */ - VTAG_OCTET_STRING, /* 0x30 */ - VTAG_DATE_TIME, /* 0x31 */ - VTAG_RESOLUTION, /* 0x32 */ - VTAG_RANGE_OF_INTEGER, /* 0x33 */ - VTAG_BEGIN_COLLECTION, /* 0x34 */ - VTAG_TEXT_WITH_LANGUAGE, /* 0x35 */ - VTAG_NAME_WITH_LANGUAGE, /* 0x36 */ - VTAG_END_COLLECTION, /* 0x37 */ - VTAG_RESERVED_STRING_38, /* 0x38 */ - VTAG_RESERVED_STRING_39, /* 0x39 */ - VTAG_RESERVED_STRING_3A, /* 0x3a */ - VTAG_RESERVED_STRING_3B, /* 0x3b */ - VTAG_RESERVED_STRING_3C, /* 0x3c */ - VTAG_RESERVED_STRING_3D, /* 0x3d */ - VTAG_RESERVED_STRING_3E, /* 0x3e */ - VTAG_RESERVED_STRING_3F, /* 0x3f */ - VTAG_RESERVED_CHAR_GEN, /* 0x40 */ - VTAG_TEXT_WITHOUT_LANGUAGE, /* 0x41 */ - VTAG_NAME_WITHOUT_LANGUAGE, /* 0x42 */ - VTAG_RESERVED_43, /* 0x43 */ - VTAG_KEYWORD, /* 0x44 */ - VTAG_URI, /* 0x45 */ - VTAG_URI_SCHEME, /* 0x46 */ - VTAG_CHARSET, /* 0x47 */ - VTAG_NATURAL_LANGUAGE, /* 0x48 */ - VTAG_MIME_MEDIA_TYPE, /* 0x49 */ - VTAG_MEMBER_ATTR_NAME, /* 0x4a */ - VTAG_RESERVED_STRING_4B, /* 0x4b */ - VTAG_RESERVED_STRING_4C, /* 0x4c */ - VTAG_RESERVED_STRING_4D, /* 0x4d */ - VTAG_RESERVED_STRING_4E, /* 0x4e */ - VTAG_RESERVED_STRING_4F, /* 0x4f */ - VTAG_RESERVED_STRING_50, /* 0x50 */ - VTAG_RESERVED_STRING_51, /* 0x51 */ - VTAG_RESERVED_STRING_52, /* 0x52 */ - VTAG_RESERVED_STRING_53, /* 0x53 */ - VTAG_RESERVED_STRING_54, /* 0x54 */ - VTAG_RESERVED_STRING_55, /* 0x55 */ - VTAG_RESERVED_STRING_56, /* 0x56 */ - VTAG_RESERVED_STRING_57, /* 0x57 */ - VTAG_RESERVED_STRING_58, /* 0x58 */ - VTAG_RESERVED_STRING_59, /* 0x59 */ - VTAG_RESERVED_STRING_5A, /* 0x5a */ - VTAG_RESERVED_STRING_5B, /* 0x5b */ - VTAG_RESERVED_STRING_5C, /* 0x5c */ - VTAG_RESERVED_STRING_5D, /* 0x5d */ - VTAG_RESERVED_STRING_5E, /* 0x5e */ - VTAG_RESERVED_STRING_5F, /* 0x5f */ - VTAG_RESERVED_MAX = 0x5f, /* 0x5f */ - VTAG_MAX = 0x5f, /* 0x5f */ - VTAG_EXTEND = 0x7f /* 0x7f */ -}; - -/* Response codes */ -enum { - IPP_OK_MIN = 0x0000, - IPP_OK = 0x0000, /* 0x0000 */ - IPP_OK_IGNORED_ATTRIBUTES, /* 0x0001 */ - IPP_OK_CONFLICTING_ATTRIBUTES, /* 0x0002 */ - IPP_OK_IGNORED_SUBSCRIPTIONS, /* 0x0003 */ - IPP_OK_IGNORED_NOTIFICATIONS, /* 0x0004 */ - IPP_OK_TOO_MANY_EVENTS, /* 0x0005 */ - IPP_OK_BUT_CANCEL_SUBSCRIPTION, /* 0x0006 */ - IPP_OK_MAX = IPP_OK_BUT_CANCEL_SUBSCRIPTION, - - IPP_REDIR_MIN = 0x0300, - IPP_REDIR_OTHER_SIZE = 0x0300, /* 0x0300 */ - IPP_REDIR_MAX = 0x0300, - - IPP_CERR_MIN = 0x0400, - IPP_CERR_BAD_REQUEST = 0x0400, /* 0x0400 */ - IPP_CERR_FORBIDDEN, /* 0x0401 */ - IPP_CERR_NOT_AUTHENTICATED, /* 0x0402 */ - IPP_CERR_NOT_AUTHORIZED, /* 0x0403 */ - IPP_CERR_NOT_POSSIBLE, /* 0x0404 */ - IPP_CERR_TIMEOUT, /* 0x0405 */ - IPP_CERR_NOT_FOUND, /* 0x0406 */ - IPP_CERR_GONE, /* 0x0407 */ - IPP_CERR_REQUEST_ENTITY, /* 0x0408 */ - IPP_CERR_REQUEST_VALUE, /* 0x0409 */ - IPP_CERR_DOCUMENT_FORMAT, /* 0x040a */ - IPP_CERR_ATTRIBUTES, /* 0x040b */ - IPP_CERR_URI_SCHEME, /* 0x040c */ - IPP_CERR_CHARSET, /* 0x040d */ - IPP_CERR_CONFLICT, /* 0x040e */ - IPP_CERR_COMPRESSION_NOT_SUPPORTED, /* 0x040f */ - IPP_CERR_COMPRESSION_ERROR, /* 0x0410 */ - IPP_CERR_DOCUMENT_FORMAT_ERROR, /* 0x0411 */ - IPP_CERR_DOCUMENT_ACCESS_ERROR, /* 0x0412 */ - IPP_CERR_ATTRIBUTES_NOT_SETTABLE, /* 0x0413 */ - IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS, /* 0x0414 */ - IPP_CERR_TOO_MANY_SUBSCRIPTIONS, /* 0x0415 */ - IPP_CERR_IGNORED_ALL_NOTIFICATIONS, /* 0x0416 */ - IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, /* 0x0417 */ - IPP_CERR_MAX = IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND, - - IPP_SERR_MIN = 0x0500, - IPP_SERR_INTERNAL = 0x0500, /* 0x0500 */ - IPP_SERR_OPERATION_NOT_SUPPORTED, /* 0x0501 */ - IPP_SERR_SERVICE_UNAVAILABLE, /* 0x0502 */ - IPP_SERR_VERSION_NOT_SUPPORTED, /* 0x0503 */ - IPP_SERR_DEVICE_ERROR, /* 0x0504 */ - IPP_SERR_TEMPORARY_ERROR, /* 0x0505 */ - IPP_SERR_NOT_ACCEPTING, /* 0x0506 */ - IPP_SERR_BUSY, /* 0x0507 */ - IPP_SERR_CANCELLED, /* 0x0508 */ - IPP_SERR_MULTIPLE_DOCS_NOT_SUPPORTED, /* 0x0509 */ - IPP_SERR_PRINTER_IS_DEACTIVATED, /* 0x050a */ - IPP_SERR_MAX = IPP_SERR_PRINTER_IS_DEACTIVATED -}; - -/* Job state codes */ -enum { - IPP_JOB_STATE_PENDING = 3, - IPP_JOB_STATE_PENDING_HELD = 4, - IPP_JOB_STATE_PROCESSING = 5, - IPP_JOB_STATE_PROCESSING_STOPPED = 6, - IPP_JOB_STATE_CANCELED = 7, - IPP_JOB_STATE_ABORTED = 8, - IPP_JOB_STATE_COMPLETED = 9 -}; - -/* exported functions */ -extern papi_status_t ipp_read_message(ipp_reader_t iread, void *fd, - papi_attribute_t ***message, char type); - -extern papi_status_t ipp_write_message(ipp_writer_t iwrite, void *fd, - papi_attribute_t **message); - -/* internal functions shared between modules */ -extern void ipp_set_status(papi_attribute_t ***message, papi_status_t status, - char *format, ...); -extern papi_status_t ipp_validate_request(papi_attribute_t **request, - papi_attribute_t ***response); - -extern int ipp_severity(int16_t status); - -extern int16_t ipp_charset_supported(char *charset); - -extern void *string_to_ipp_attr_value(int8_t type, char *value); - -extern char *ipp_uri_to_printer(char *uri); -extern void *papi_attribute_to_ipp_attr(int8_t type, papi_attribute_t *attr); - -extern int8_t name_to_ipp_type(char *name); -extern char *job_template[]; -extern char *job_description[]; -extern char *printer_description[]; -extern char *ipp_tag_string(int8_t tag, char *buf, size_t bufsiz); -extern size_t min_val_len(int8_t type, char *name); -extern size_t max_val_len(int8_t type, char *name); -extern int is_keyword(char *value); - -#ifdef __cplusplus -} -#endif - -#endif /* _IPP_H */ diff --git a/usr/src/lib/print/libipp-core/common/ipp_types.c b/usr/src/lib/print/libipp-core/common/ipp_types.c deleted file mode 100644 index 47fc32c259..0000000000 --- a/usr/src/lib/print/libipp-core/common/ipp_types.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: ipp_types.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <ipp.h> -#include <errno.h> -#include <values.h> - -#ifndef MININT -#define MININT (-MAXINT - 1) -#endif - -typedef struct { - char *name; - int8_t ipp_type; - int min; - int max; -} attr_info_list_t; - -static attr_info_list_t attr_list[] = { - {"operation-attribute-group", DTAG_OPERATION_ATTRIBUTES, 0, 0}, - {"job-attribute-group", DTAG_JOB_ATTRIBUTES, 0, 0}, - {"printer-attribute-group", DTAG_PRINTER_ATTRIBUTES, 0, 0}, - {"unsupported-attribute-group", DTAG_UNSUPPORTED_ATTRIBUTES, 0, 0}, - {"subscription-attribute-group", DTAG_SUBSCRIPTION_ATTRIBUTES, 0, 0}, - {"even-notificaton-attribute-group", - DTAG_EVENT_NOTIFICATION_ATTRIBUTES, 0, 0}, - {"attributes-charset", VTAG_CHARSET, 0, 255}, - {"attributes-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, - {"charset-configured", VTAG_CHARSET, 0, 255}, - {"charset-supported", VTAG_CHARSET, 0, 255}, - {"color-supported", VTAG_BOOLEAN, 0, 1}, - {"compression", VTAG_KEYWORD, 1, 255}, - {"compression-supported", VTAG_KEYWORD, 1, 255}, - {"copies", VTAG_INTEGER, 1, MAXINT}, - {"copies-default", VTAG_INTEGER, 1, MAXINT}, - {"copies-supported", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, - {"date-at-completed", VTAG_DATE_TIME, 0, 0}, - {"date-at-creation", VTAG_DATE_TIME, 0, 0}, - {"date-at-processing", VTAG_DATE_TIME, 0, 0}, - {"detailed-status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"document-access-error", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"document-format", VTAG_MIME_MEDIA_TYPE, 0, 255}, - {"document-format-default", VTAG_MIME_MEDIA_TYPE, 0, 255}, - {"document-format-supported", VTAG_MIME_MEDIA_TYPE, 0, 255}, - {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"document-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"document-natural-language", VTAG_NATURAL_LANGUAGE, 0, 255}, - {"finishing", VTAG_ENUM, 3, 31}, - {"finishing-default", VTAG_ENUM, 3, 31}, - {"finishing-supported", VTAG_ENUM, 3, 31}, - {"generated-natural-language-supported", VTAG_NATURAL_LANGUAGE, 0, 255}, - {"ipp-attribute-fidelity", VTAG_BOOLEAN, 0, 1}, - {"ipp-versions-supported", VTAG_KEYWORD, 1, 255}, - {"job-detailed-status-messages", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"job-document-access-errors", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"job-hold-until", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-hold-until-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-hold-until-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-id", VTAG_INTEGER, 1, MAXINT}, - {"job-impressions", VTAG_INTEGER, 0, MAXINT}, - {"job-impressions-completed", VTAG_INTEGER, 0, MAXINT}, - {"job-impressions-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, - {"job-k-octets", VTAG_INTEGER, 0, MAXINT}, - {"job-k-octets-processed", VTAG_INTEGER, 0, MAXINT}, - {"job-k-octets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, - {"job-media-sheets", VTAG_INTEGER, 0, MAXINT}, - {"job-media-sheets-completed", VTAG_INTEGER, 0, MAXINT}, - {"job-media-sheets-supported", VTAG_RANGE_OF_INTEGER, 0, MAXINT}, - {"job-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"job-more-info", VTAG_URI, 0, 1023}, - {"job-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-originating-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-printer-up-time", VTAG_INTEGER, 1, MAXINT}, - {"job-printer-uri", VTAG_URI, 0, 1023}, - {"job-priority", VTAG_INTEGER, 1, 100}, - {"job-priority-default", VTAG_INTEGER, 1, 100}, - {"job-priority-supported", VTAG_INTEGER, 1, 100}, - {"job-sheets", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-sheets-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-sheets-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"job-state", VTAG_ENUM, 3, 9}, - {"job-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"job-state-reasons", VTAG_KEYWORD, 1, 255}, - {"job-uri", VTAG_URI, 0, 1023}, - {"last-document", VTAG_BOOLEAN, 0, 1}, - {"limit", VTAG_INTEGER, 1, MAXINT}, - {"media", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"media-default", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"media-supported", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"multiple-document-handling", VTAG_KEYWORD, 1, 255}, - {"multiple-document-handling-default", VTAG_KEYWORD, 1, 255}, - {"multiple-document-handling-supported", VTAG_KEYWORD, 1, 255}, - {"multiple-document-jobs-supported", VTAG_BOOLEAN, 0, 1}, - {"multiple-operation-time-out", VTAG_INTEGER, 1, MAXINT}, - {"my-jobs", VTAG_BOOLEAN, 0, 1}, - {"natural-language-configured", VTAG_NATURAL_LANGUAGE, 0, 255}, - {"number-of-documents", VTAG_INTEGER, 0, MAXINT}, - {"number-of-intervening-jobs", VTAG_INTEGER, 0, MAXINT}, - {"number-up", VTAG_INTEGER, 1, MAXINT}, - {"number-up-default", VTAG_INTEGER, 1, MAXINT}, - {"number-up-supported", VTAG_INTEGER, 1, MAXINT}, - {"operations-supported", VTAG_ENUM, 1, 0x8FFF}, - {"orientation-requested", VTAG_ENUM, 3, 6}, - {"orientation-requested-default", VTAG_ENUM, 3, 6}, - {"orientation-requested-supported", VTAG_ENUM, 3, 6}, - {"output-device-assigned", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, - {"page-ranges", VTAG_RANGE_OF_INTEGER, 1, MAXINT}, - {"page-ranges-supported", VTAG_BOOLEAN, 0, 1}, - {"pages-per-minute", VTAG_INTEGER, 0, MAXINT}, - {"pages-per-minute-color", VTAG_INTEGER, 0, MAXINT}, - {"pdl-override-supported", VTAG_KEYWORD, 1, 255}, - {"print-quality", VTAG_ENUM, 3, 5}, - {"print-quality-default", VTAG_ENUM, 3, 5}, - {"print-quality-supported", VTAG_ENUM, 3, 5}, - {"printer-current-time", VTAG_DATE_TIME, 0, 1}, - {"printer-driver-installer", VTAG_URI, 0, 1023}, - {"printer-id", VTAG_INTEGER, 1, MAXINT}, - {"printer-info", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"printer-is-accepting-jobs", VTAG_BOOLEAN, 0, 1}, - {"printer-location", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"printer-make-and-model", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"printer-message-from-operator", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 127}, - {"printer-more-info", VTAG_URI, 0, 1023}, - {"printer-more-info-manufacturer", VTAG_URI, 0, 1023}, - {"printer-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 127}, - {"printer-resolution", VTAG_RESOLUTION, 0, 0}, - {"printer-resolution-default", VTAG_RESOLUTION, 0, 0}, - {"printer-resolution-supported", VTAG_RESOLUTION, 0, 0}, - {"printer-state", VTAG_ENUM, 3, 5}, - {"printer-state-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 1023}, - {"printer-state-reasons", VTAG_KEYWORD, 1, 255}, - {"printer-up-time", VTAG_INTEGER, 1, MAXINT}, - {"printer-uri", VTAG_URI, 0, 1023}, - {"printer-uri-supported", VTAG_URI, 0, 1023}, - {"queued-job-count", VTAG_INTEGER, 0, MAXINT}, - {"reference-uri-schemes-supported", VTAG_URI_SCHEME, 0, 63}, - {"requested-attributes", VTAG_KEYWORD, 1, 255}, - {"requesting-user-name", VTAG_NAME_WITHOUT_LANGUAGE, 0, 255}, - {"sides", VTAG_KEYWORD, 1, 255}, - {"sides-default", VTAG_KEYWORD, 1, 255}, - {"sides-supported", VTAG_KEYWORD, 1, 255}, - {"status-code", VTAG_ENUM, 1, 0x7FFF}, - {"status-message", VTAG_TEXT_WITHOUT_LANGUAGE, 0, 255}, - {"time-at-completed", VTAG_INTEGER, MININT, MAXINT}, - {"time-at-creation", VTAG_INTEGER, MININT, MAXINT}, - {"time-at-processing", VTAG_INTEGER, MININT, MAXINT}, - {"uri-authentication-supported", VTAG_KEYWORD, 1, 255}, - {"uri-security-supported", VTAG_KEYWORD, 1, 255}, - {"which-jobs", VTAG_KEYWORD, 1, 255}, - {NULL, 0, 0, 0} -}; - - -static attr_info_list_t * -get_attr_info_by_name(char *name) -{ - if (name != NULL) { - int i; - - for (i = 0; attr_list[i].name != NULL; i++) - if (strcasecmp(attr_list[i].name, name) == 0) - return (&attr_list[i]); - } - - return (NULL); -} - -size_t -max_val_len(int8_t type, char *name) -{ - attr_info_list_t *t; - int result; - - switch (type) { - case VTAG_INTEGER: - case VTAG_RANGE_OF_INTEGER: - case VTAG_ENUM: - result = MAXINT; - break; - case VTAG_URI: - case VTAG_OCTET_STRING: - case VTAG_TEXT_WITHOUT_LANGUAGE: - result = 1023; - break; - case VTAG_NATURAL_LANGUAGE: - case VTAG_URI_SCHEME: - case VTAG_CHARSET: - result = 63; - break; - case VTAG_NAME_WITHOUT_LANGUAGE: - case VTAG_MIME_MEDIA_TYPE: - case VTAG_KEYWORD: - result = 255; - break; - default: - result = MAXINT; - } - -#define min(a, b) ((a < b) ? a : b) - if ((t = get_attr_info_by_name(name)) != NULL) - result = min(t->max, result); -#undef min - - return (result); -} - -size_t -min_val_len(int8_t type, char *name) -{ - attr_info_list_t *t; - int result; - - switch (type) { - case VTAG_INTEGER: - case VTAG_RANGE_OF_INTEGER: - result = MININT; - break; - case VTAG_ENUM: - result = 1; - break; - case VTAG_URI: - case VTAG_OCTET_STRING: - case VTAG_TEXT_WITHOUT_LANGUAGE: - case VTAG_MIME_MEDIA_TYPE: - case VTAG_NAME_WITHOUT_LANGUAGE: - case VTAG_URI_SCHEME: - case VTAG_CHARSET: - case VTAG_NATURAL_LANGUAGE: - result = 0; - break; - case VTAG_KEYWORD: - result = 1; - break; - default: - result = MININT; - } - -#define max(a, b) ((a > b) ? a : b) - if ((t = get_attr_info_by_name(name)) != NULL) - result = max(t->min, result); -#undef max - - return (result); -} - -int -is_keyword(char *k) -{ - /* [a-z][a-z0-9._-]* */ - if (*k < 'a' && *k > 'z') - return (0); - while (*(++k) != '\0') - if (*k < 'a' && *k > 'z' && *k < '0' && *k > '9' && - *k != '.' && *k != '_' && *k != '-') - return (0); - return (1); -} - -int8_t -name_to_ipp_type(char *name) -{ - int i; - - if (name != NULL) - for (i = 0; attr_list[i].name != NULL; i++) - if (strcasecmp(attr_list[i].name, name) == 0) - return (attr_list[i].ipp_type); - - return (0); -} diff --git a/usr/src/lib/print/libipp-core/common/read.c b/usr/src/lib/print/libipp-core/common/read.c deleted file mode 100644 index 6127958f66..0000000000 --- a/usr/src/lib/print/libipp-core/common/read.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: read.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <alloca.h> -#include <string.h> -#include <stdarg.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <inttypes.h> - -#include <papi.h> -#include <ipp.h> - - -#define _ipp_tag_string(id) ipp_tag_string((id), buf, sizeof (buf)) - -static papi_status_t -read_name_with_language(ipp_reader_t iread, void *fd, - papi_attribute_t ***message) -{ - char *string; - uint16_t size; - - /* read the language */ - if (iread(fd, &size, 2) != 2) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "read failed: lang len\n"); - return (PAPI_BAD_REQUEST); - } - size = (uint16_t)ntohs(size); - - if ((string = alloca(size + 1)) == NULL) { - ipp_set_status(message, PAPI_TEMPORARY_ERROR, - "Memory allocation failed"); - return (PAPI_TEMPORARY_ERROR); - } - if (iread(fd, string, size) != size) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "read failed: lang\n"); - return (PAPI_BAD_REQUEST); - } - - /* read the text */ - if (iread(fd, &size, 2) != 2) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "read failed: text len\n"); - return (PAPI_BAD_REQUEST); - } - size = (uint16_t)ntohs(size); - - if ((string = alloca(size + 1)) == NULL) { - ipp_set_status(message, PAPI_TEMPORARY_ERROR, - "Memory allocation failed"); - return (PAPI_TEMPORARY_ERROR); - } - if (iread(fd, string, size) != size) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "read failed: text\n"); - return (PAPI_BAD_REQUEST); - } - - return (PAPI_OK); -} - - -static struct { - int8_t ipp_type; - int8_t size; -} type_info[] = { - { VTAG_INTEGER, 4 }, - { VTAG_ENUM, 4 }, - { VTAG_BOOLEAN, 1 }, - { VTAG_RANGE_OF_INTEGER, 8 }, - { VTAG_RESOLUTION, 9 }, - { VTAG_DATE_TIME, 11 }, - { DTAG_MIN, 0 } -}; - -/* verify that the IPP type and size are compatible */ -static int -validate_length(int8_t type, int8_t size) -{ - int i; - - for (i = 0; type_info[i].ipp_type != DTAG_MIN; i++) - if (type_info[i].ipp_type == type) - return ((type_info[i].size == size) ? 0 : -1); - return (0); -} - -/* convert tyep IPP type to a type that is marginally compatible */ -static int8_t -base_type(int8_t i) -{ - switch (i) { - case VTAG_ENUM: - case VTAG_INTEGER: - return (VTAG_INTEGER); - case VTAG_URI: - case VTAG_OCTET_STRING: - case VTAG_TEXT_WITHOUT_LANGUAGE: - case VTAG_URI_SCHEME: - case VTAG_CHARSET: - case VTAG_NATURAL_LANGUAGE: - case VTAG_MIME_MEDIA_TYPE: - case VTAG_NAME_WITHOUT_LANGUAGE: - case VTAG_KEYWORD: - return (VTAG_TEXT_WITHOUT_LANGUAGE); - case VTAG_BOOLEAN: - case VTAG_RANGE_OF_INTEGER: - case VTAG_DATE_TIME: - case VTAG_RESOLUTION: - default: - return (i); - } -} - -/* verify that the IPP type is correct for the named attribute */ -static papi_status_t -validate_type(char *name, int8_t type) -{ - int8_t t = name_to_ipp_type(name); - - if (t == 0) /* The attribute is not defined in the RFC */ - return (PAPI_NOT_FOUND); - else if (t == type) /* The supplied type matched the RFC type */ - return (PAPI_OK); - else { /* The supplied type doesn't match the RFC */ - if (base_type(t) == base_type(type)) - return (PAPI_OK); - - return (PAPI_CONFLICT); - } -} - -/* verify that the IPP value is within specification for the named attribute */ -static int -validate_value(papi_attribute_t ***message, char *name, int8_t type, ...) -{ -#define within(a, b, c) ((b >= a) && (b <= c)) - va_list ap; - int rc = -1; - int min = min_val_len(type, name), - max = max_val_len(type, name); - char buf[64]; /* For _ipp_<...>_string() */ - - va_start(ap, type); - switch (type) { - case VTAG_ENUM: - case VTAG_INTEGER: { - int32_t i = (int32_t)va_arg(ap, int32_t); - - if (within(min, i, max)) - rc = 0; - else - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %d: out of range (%d - %d)", name, - _ipp_tag_string(type), i, min, max); - } - break; - case VTAG_BOOLEAN: { - int8_t v = (int8_t)va_arg(ap, int); - - if (within(0, v, 1)) - rc = 0; - else - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %d: out of range (0 - 1)", name, - _ipp_tag_string(type), v); - } - break; - case VTAG_RANGE_OF_INTEGER: { - int32_t lower = (int32_t)va_arg(ap, int32_t); - int32_t upper = (int32_t)va_arg(ap, int32_t); - - if (within(min, lower, max) && - within(min, upper, max)) - rc = 0; - else - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %d - %d: out of range (%d - %d)", name, - _ipp_tag_string(type), lower, upper, min, max); - } - break; - case VTAG_URI: - case VTAG_OCTET_STRING: - case VTAG_TEXT_WITHOUT_LANGUAGE: - case VTAG_URI_SCHEME: - case VTAG_CHARSET: - case VTAG_NATURAL_LANGUAGE: - case VTAG_MIME_MEDIA_TYPE: - case VTAG_NAME_WITHOUT_LANGUAGE: { - char *v = (char *)va_arg(ap, char *); - - if (strlen(v) < max) - rc = 0; - else - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %s: too long (max length: %d)", name, - _ipp_tag_string(type), v, max); - } - break; - case VTAG_KEYWORD: { - char *v = (char *)va_arg(ap, char *); - - if (strlen(v) >= max) - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %s: too long (max length: %d)", name, - _ipp_tag_string(type), v, max); - else if (is_keyword(v) == 0) - ipp_set_status(message, PAPI_BAD_ARGUMENT, - "%s(%s): %s: invalid keyword", name, - _ipp_tag_string(type), v); - else - rc = 0; - } - break; - case VTAG_DATE_TIME: - case VTAG_RESOLUTION: - default: - rc = 0; - } - va_end(ap); - - return (rc); -#undef within -} - -/* - * read_attr_group() reads in enough of the message data to parse an entire - * attribute group. Since to determine that the group is finished you have to - * read the character that determines the type of the next group, this function - * must return that character, in order that our caller knows how to call us for - * the next group. Thus type is used both as an input parameter (the type of - * attribute group to read in) and an output parameter (the type of the next - * attribute group). - */ - -static papi_status_t -ipp_read_attribute_group(ipp_reader_t iread, void *fd, int8_t *type, - papi_attribute_t ***message) -{ - int8_t value_tag; - uint16_t name_length, value_length; - papi_attribute_t **attributes = NULL; - char *name = NULL; - int i; - char buf[64]; /* For _ipp_<...>_string() */ - - /* - * RFC2910 3.3 says we need to handle `An expected but missing - * "begin-attribute-group-tag" field. How? - */ - if (*type > DTAG_MAX) { - /* Scream bloody murder, or assign a new type? */ - ipp_set_status(message, PAPI_BAD_REQUEST, - "Bad attribute group tag 0x%.2hx (%s)", - *type, _ipp_tag_string(*type)); - return (PAPI_BAD_REQUEST); - } - - /* This loops through *values* not *attributes*! */ - for (i = 0; ; i++) { - papi_status_t valid = PAPI_OK; - if (iread(fd, &value_tag, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: value tag\n"); - return (PAPI_BAD_REQUEST); - } - /* are we done with this group ? */ - if (value_tag <= DTAG_MAX) - break; - - if (iread(fd, &name_length, 2) != 2) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: name length\n"); - return (PAPI_BAD_REQUEST); - } - name_length = (uint16_t)ntohs(name_length); - - /* Not just another value for the previous attribute */ - if (name_length != 0) { - if ((name = alloca(name_length + 1)) == NULL) { - ipp_set_status(message, PAPI_TEMPORARY_ERROR, - "alloca(): failed\n"); - return (PAPI_TEMPORARY_ERROR); - } - (void) memset(name, 0, name_length + 1); - - if (iread(fd, name, name_length) != name_length) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: name\n"); - return (PAPI_BAD_REQUEST); - } - } - - valid = validate_type(name, value_tag); - if ((valid != PAPI_OK) && (valid != PAPI_NOT_FOUND)) - ipp_set_status(message, valid, "%s(%s): %s", name, - _ipp_tag_string(value_tag), - papiStatusString(valid)); - - if (iread(fd, &value_length, 2) != 2) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: value length\n"); - return (PAPI_BAD_REQUEST); - } - value_length = (uint16_t)ntohs(value_length); - - if (validate_length(value_tag, value_length) < 0) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "Bad value length (%d) for type %s", - value_length, _ipp_tag_string(value_tag)); - return (PAPI_BAD_REQUEST); - } - - switch (value_tag) { - case VTAG_INTEGER: - case VTAG_ENUM: { - int32_t v; - - if (iread(fd, &v, value_length) != value_length) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: int/enum\n"); - return (PAPI_BAD_REQUEST); - } - v = (int32_t)ntohl(v); - (void) validate_value(message, name, value_tag, v); - papiAttributeListAddInteger(&attributes, - PAPI_ATTR_APPEND, name, v); - - } - break; - case VTAG_BOOLEAN: { - int8_t v; - - if (iread(fd, &v, value_length) != value_length) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: boolean\n"); - return (PAPI_BAD_REQUEST); - } - (void) validate_value(message, name, value_tag, v); - papiAttributeListAddBoolean(&attributes, - PAPI_ATTR_APPEND, name, v); - } - break; - case VTAG_RANGE_OF_INTEGER: { - int32_t min, max; - - if (iread(fd, &min, 4) != 4) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: min\n"); - return (PAPI_BAD_REQUEST); - } - if (iread(fd, &max, 4) != 4) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: max\n"); - return (PAPI_BAD_REQUEST); - } - min = (int32_t)ntohl(min); - max = (int32_t)ntohl(max); - (void) validate_value(message, name, value_tag, - min, max); - papiAttributeListAddRange(&attributes, PAPI_ATTR_APPEND, - name, min, max); - } - break; - case VTAG_RESOLUTION: { - int32_t x, y; - int8_t units; - - if (iread(fd, &x, 4) != 4) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: x\n"); - return (PAPI_BAD_REQUEST); - } - if (iread(fd, &y, 4) != 4) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: y\n"); - return (PAPI_BAD_REQUEST); - } - if (iread(fd, &units, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: units\n"); - return (PAPI_BAD_REQUEST); - } - x = (int32_t)ntohl(x); - y = (int32_t)ntohl(y); - papiAttributeListAddResolution(&attributes, - PAPI_ATTR_APPEND, name, x, y, - (papi_resolution_unit_t)units); - } - break; - case VTAG_DATE_TIME: { - struct tm tm; - time_t v; - int8_t c; - uint16_t s; - - (void) memset(&tm, 0, sizeof (tm)); - if (iread(fd, &s, 2) != 2) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: year\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_year = (uint16_t)ntohs(s) - 1900; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: month\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_mon = c - 1; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: day\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_mday = c; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: hour\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_hour = c; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: minutes\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_min = c; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: seconds\n"); - return (PAPI_BAD_REQUEST); - } - tm.tm_sec = c; - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: decisec\n"); - return (PAPI_BAD_REQUEST); - } - /* tm.deciseconds = c; */ - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: utc_dir\n"); - return (PAPI_BAD_REQUEST); - } - /* tm.utc_dir = c; */ - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: utc_hour\n"); - return (PAPI_BAD_REQUEST); - } - /* tm.utc_hours = c; */ - if (iread(fd, &c, 1) != 1) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: utc_min\n"); - return (PAPI_BAD_REQUEST); - } - /* tm.utc_minutes = c; */ - - v = mktime(&tm); - - (void) validate_value(message, name, value_tag, v); - papiAttributeListAddDatetime(&attributes, - PAPI_ATTR_APPEND, name, v); - } - break; - case VTAG_NAME_WITH_LANGUAGE: - case VTAG_TEXT_WITH_LANGUAGE: - /* - * we are dropping this because we don't support - * name with language at this time. - */ - (void) read_name_with_language(iread, fd, message); - break; - case VTAG_NAME_WITHOUT_LANGUAGE: - case VTAG_TEXT_WITHOUT_LANGUAGE: - case VTAG_URI: - case VTAG_KEYWORD: - case VTAG_CHARSET: { - char *v; - - if ((v = calloc(1, value_length + 1)) == NULL) { - ipp_set_status(message, PAPI_TEMPORARY_ERROR, - "calloc(): failed\n"); - return (PAPI_TEMPORARY_ERROR); - } -#ifdef NOTDEF - if (iread(fd, v, value_length) != value_length) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: stringy\n"); - return (PAPI_BAD_REQUEST); - } -#else - { - int rc, i = value_length; - char *p = v; - - while ((rc = iread(fd, p, i)) != i) { - if (rc <= 0) { - ipp_set_status(message, - PAPI_BAD_REQUEST, - "bad read: stringy\n"); - return (PAPI_BAD_REQUEST); - } - i -= rc; - p += rc; - } - } -#endif - (void) validate_value(message, name, value_tag, v); - papiAttributeListAddString(&attributes, - PAPI_ATTR_APPEND, name, v); - } - break; - case VTAG_UNKNOWN: - case VTAG_NOVALUE: - case VTAG_UNSUPPORTED: - papiAttributeListAddValue(&attributes, PAPI_ATTR_EXCL, - name, PAPI_COLLECTION, NULL); - break; - default: { - char *v; - - if ((v = calloc(1, value_length + 1)) == NULL) { - ipp_set_status(message, PAPI_TEMPORARY_ERROR, - "calloc(): failed\n"); - return (PAPI_TEMPORARY_ERROR); - } - if (iread(fd, v, value_length) != value_length) { - ipp_set_status(message, PAPI_BAD_REQUEST, - "bad read: other\n"); - return (PAPI_BAD_REQUEST); - } - papiAttributeListAddString(&attributes, - PAPI_ATTR_APPEND, name, v); - } - break; - } - } - - if (attributes != NULL) { - char name[32]; - - (void) ipp_tag_string(*type, name, sizeof (name)); - papiAttributeListAddCollection(message, PAPI_ATTR_APPEND, name, - attributes); - } - - *type = value_tag; - - return (PAPI_OK); -} - - -static papi_status_t -ipp_read_header(ipp_reader_t iread, void *fd, papi_attribute_t ***message, - char type) -{ - char *attr_name = "status-code"; /* default to a response */ - char buf[8]; - int8_t c; - uint16_t s; - int32_t i; - - if ((iread == NULL) || (fd == NULL) || (message == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* - * Apache 1.X uses the buffer supplied to it's read call to read in - * the chunk size when chunking is used. This causes problems - * reading the header a piece at a time, because we don't have - * enough room to read in the chunk size prior to reading the - * chunk. - */ - - if (iread(fd, buf, 8) != 8) - return (PAPI_BAD_REQUEST); - - c = buf[0]; - (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, - "version-major", c); - - c = buf[1]; - (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, - "version-minor", c); - - memcpy(&s, &buf[2], 2); - s = (uint16_t)ntohs(s); - if (type == IPP_TYPE_REQUEST) - attr_name = "operation-id"; - (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, - attr_name, s); - - memcpy(&i, &buf[4], 4); - i = (uint32_t)ntohl(i); - (void) papiAttributeListAddInteger(message, PAPI_ATTR_REPLACE, - "request-id", i); - - return (PAPI_OK); -} - -static papi_status_t -ipp_read_attribute_groups(ipp_reader_t iread, void *fd, - papi_attribute_t ***message) -{ - papi_status_t result = PAPI_OK; - int8_t tag; - - /* start reading the attribute groups */ - if (iread(fd, &tag, 1) != 1) /* prime the pump */ - return (PAPI_BAD_REQUEST); - - while ((tag != DTAG_END_OF_ATTRIBUTES) && (result == PAPI_OK)) { - result = ipp_read_attribute_group(iread, fd, &tag, message); - } - - return (result); -} - -papi_status_t -ipp_read_message(ipp_reader_t iread, void *fd, papi_attribute_t ***message, - char type) -{ - papi_status_t result = PAPI_OK; - - if ((iread == NULL) || (fd == NULL) || (message == NULL)) - return (PAPI_BAD_ARGUMENT); - - result = ipp_read_header(iread, fd, message, type); - if (result == PAPI_OK) - result = ipp_read_attribute_groups(iread, fd, message); - - return (result); -} diff --git a/usr/src/lib/print/libipp-core/common/strings.c b/usr/src/lib/print/libipp-core/common/strings.c deleted file mode 100644 index b47449b8cc..0000000000 --- a/usr/src/lib/print/libipp-core/common/strings.c +++ /dev/null @@ -1,411 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: strings.c 151 2006-04-25 16:55:34Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "ipp.h" - -static char *tag_strings[] = { - /* delimiter tags */ - "reserved-delimiter-00", - "operational-attributes-group", - "job-attributes-group", - "end-of-attributes-group", - "printer-attributes-group", - "unsupported-attributes-group", - "subscription-attributes-group", - "event-notification-attributes-group", - "reserved-delimiter-08", - "reserved-delimiter-09", - "reserved-delimiter-0a", - "reserved-delimiter-0b", - "reserved-delimiter-0c", - "reserved-delimiter-0d", - "reserved-delimiter-0e", - "reserved-delimiter-0f", - /* value tags */ - "unsupported", - "reserved-default", - "unknown", - "no-value", - "reserved-out-of-band-14", - "not-settable", - "delete-attribute", - "admin-define", - "reserved-out-of-band-18", - "reserved-out-of-band-19", - "reserved-out-of-band-1a", - "reserved-out-of-band-1b", - "reserved-out-of-band-1c", - "reserved-out-of-band-1d", - "reserved-out-of-band-1e", - "reserved-out-of-band-1f", - "reserved", - "integer", - "boolean", - "enum", - "reserved-integer-type-24", - "reserved-integer-type-25", - "reserved-integer-type-26", - "reserved-integer-type-27", - "reserved-integer-type-28", - "reserved-integer-type-29", - "reserved-integer-type-2a", - "reserved-integer-type-2b", - "reserved-integer-type-2c", - "reserved-integer-type-2d", - "reserved-integer-type-2e", - "reserved-integer-type-2f", - "octetString", - "dateTime", - "resolution", - "rangeOfInteger", - "begCollection", - "textWithLanguage", - "nameWithLanguage", - "endCollection", - "reserved-octetString-38", - "reserved-octetString-39", - "reserved-octetString-3a", - "reserved-octetString-3b", - "reserved-octetString-3c", - "reserved-octetString-3d", - "reserved-octetString-3e", - "reserved-octetString-3f", - "reserved", - "textWithoutLanguage", - "nameWithoutLanguage", - "reserved", - "keyword", - "uri", - "uriScheme", - "charset", - "naturalLanguage", - "mimeMediaType", - "memberAttrName", - "reserved-charString-4b", - "reserved-charString-4c", - "reserved-charString-4d", - "reserved-charString-4e", - "reserved-charString-4f", - "reserved-charString-50", - "reserved-charString-51", - "reserved-charString-52", - "reserved-charString-53", - "reserved-charString-54", - "reserved-charString-55", - "reserved-charString-56", - "reserved-charString-57", - "reserved-charString-58", - "reserved-charString-59", - "reserved-charString-5a", - "reserved-charString-5b", - "reserved-charString-5c", - "reserved-charString-5d", - "reserved-charString-5e", - "reserved-charString-5f", -}; - -static char *opid_strings[] = { - "reserved-0x0000", - "reserved-0x0001", - "Print-Job", - "Print-URI", - "Validate-Job", - "Create-Job", - "Send-Document", - "Send-URI", - "Cancel-Job", - "Get-Job-Attributes", - "Get-Jobs", - "Get-Printer-Attributes", - "Hold-Job", - "Release-Job", - "Restart-Job", - "reserved-0x000f", - "Pause-Printer", - "Resume-Printer", - "Purge-Jobs", - "Set-Printer-Attributes", - "Set-Job-Attributes", - "Get-Printer-Supported-Values", - "Create-Printer-Subscription", - "Create-Job-Subscription", - "Get-Subscription-Attributes", - "Get-Subscriptions", - "Renew-Subscription", - "Cancel-Subscription", - "Get-Notifications", - "Send-Notifications", - "Get-Resource-Attributes-deleted", - "Get-Resource-Data-deleted", - "Get-Resources-deleted", - "Get-Print-Support-Files", - "Disable-Printer", - "Pause-Printer-After-Current-Job", - "Hold-New-Jobs", - "Release-Held-New-Jobs", - "Deactivate-Printer", - "Activate-Printer", - "Restart-Printer", - "Shutdown-Printer", - "Startup-Printer", - "Reprocess-Job", - "Cancel-Current-Job", - "Suspend-Current-Job", - "Resume-Job", - "Promote-Job", - "Schedule-Job-After", - NULL -}; - -static char *res_opid_strings[] = { - "Microsoft-0x4000", - "CUPS-Get-Default", - "CUPS-Get-Printers", - "CUPS-Add-Printer", - "CUPS-Delete-Printer", - "CUPS-Get-Classes", - "CUPS-Add-Class", - "CUPS-Delete-Class", - "CUPS-Accept-Jobs", - "CUPS-Reject-Jobs", - "CUPS-Set-Default", - "CUPS-Get-Devices", - "CUPS-Get-PPDs", - "CUPS-Move-Job", - "CUPS-0x400e", - "CUPS-0x400f", - "Peerless-0x4010", - NULL -}; -#define KNOWN_RESERVED_MIN 0x4000 -#define KNOWN_RESERVED_MAX 0x4010 - -static char *ok_status_strings[] = { - "successful-ok", - "successful-ok-ignored-or-substituted-attributes", - "successful-ok-conflicting-attributes", - "successful-ok-ignored-subscriptions", - "successful-ok-ignored-notifications", - "successful-ok-too-many-events", - "successful-ok-but-cancel-subscription" -}; - -static char *redir_status_strings[] = { - "redirection-other-site" -}; - -static char *client_error_status_strings[] = { - "client-error-bad-request", - "client-error-forbidden", - "client-error-not-authenticated", - "client-error-not-authorized", - "client-error-not-possible", - "client-error-timeout", - "client-error-not-found", - "client-error-gone", - "client-error-request-entity-too-large", - "client-error-request-value-too-long", - "client-error-document-format-not-supported", - "client-error-attributes-or-values-not-supported", - "client-error-uri-scheme-not-supported", - "client-error-charset-not-supported", - "client-error-conflicting-attributes", - "client-error-compression-not-supported", - "client-error-compression-error", - "client-error-document-format-error", - "client-error-document-access-error", - "client-error-attributes-not-settable", - "client-error-ignored-all-subscriptions", - "client-error-too-many-subscriptions", - "client-error-ignored-all-notifications", - "client-error-print-support-file-not-found" -}; - -static char *server_error_status_strings[] = { - "server-error-internal-error", - "server-error-operation-not-supported", - "server-error-service-unavailable", - "server-error-version-not-supported", - "server-error-device-error", - "server-error-temporary-error", - "server-error-not-accepting-jobs", - "server-error-busy", - "server-error-job-canceled", - "server-error-multiple-document-jobs-not-supported", - "server-error-printer-is-deactivated" -}; - -char * -ipp_tag_string(int8_t id, char *ret, size_t len) -{ - if (id < VTAG_MAX) - (void) strlcpy(ret, tag_strings[id], len); - else if (id == VTAG_EXTEND) - (void) strlcpy(ret, "extension", len); - else - (void) snprintf(ret, len, "bogus-0x%.2x", id); - - return (ret); -} - -char * -ipp_opid_string(int16_t id, char *ret, size_t len) -{ - if (id < OPID_RESERVED_MIN) - (void) strlcpy(ret, opid_strings[id], len); - else if (id < OPID_RESERVED_VENDOR_MIN) - (void) snprintf(ret, len, "reserved-0x%.4x", id); - else if (id <= KNOWN_RESERVED_MAX) - (void) strlcpy(ret, - res_opid_strings[id - KNOWN_RESERVED_MIN], len); - else /* if (id <= OPID_RESERVED_VENDOR_MAX) */ - (void) snprintf(ret, len, "reserved-vendor-0x%.4x", id); - - return (ret); -} - -int16_t -ipp_string_opid(char *string) -{ - int i; - - for (i = 0; opid_strings[i] != NULL; i++) - if (strcasecmp(opid_strings[i], string) == 0) - return (i); - - for (i = 0; res_opid_strings[i] != NULL; i++) - if (strcasecmp(res_opid_strings[i], string) == 0) - return (0x4000 + i); - - return (-1); -} - -char * -ipp_status_string(int16_t id, char *ret, size_t len) -{ - if (id <= IPP_OK_MAX) - (void) strlcpy(ret, ok_status_strings[id], len); - else if (id >= IPP_REDIR_MIN && id <= IPP_REDIR_MAX) - (void) strlcpy(ret, - redir_status_strings[id - IPP_REDIR_MIN], len); - else if (id >= IPP_CERR_MIN && id <= IPP_CERR_MAX) - (void) strlcpy(ret, - client_error_status_strings[id - IPP_CERR_MIN], len); - else if (id >= IPP_SERR_MIN && id <= IPP_SERR_MAX) - (void) strlcpy(ret, - server_error_status_strings[id - IPP_SERR_MIN], len); - else - (void) snprintf(ret, len, "bogus-0x%.4hx", id); - - return (ret); -} - - - -/* - * attribute template handling routines - */ -char *job_template[] = { - "copies", - "finishing", - "job-hold-until", - "job-priority", - "job-sheets", - "media", - "multiple-document-handling", - "number-up", - "page-ranges-supported", - "print-quality", - "printer-resoultion", - "sides", - NULL -}; - -char *job_description[] = { - "copies-default", "copies-supported", - "finishing-default", "finishing-supported", - "job-hold-until-default", "job-hold-until-supported", - "job-priority-default", "job-priority-supported", - "job-sheets-default", "job-sheets-supported", - "media-default", "media-supported", - "multiple-document-handling-default", - "multiple-document-handling-supported", - "number-up-default", "number-up-supported", - "page-ranges-supported", - "print-quality-default", "print-quality-supported", - "printer-resoultion-default", "printer-resoultion-supported", - "sides-default", "sides-supported", - NULL -}; - -char *printer_description[] = { - "printer-uri-supported", - "uri-security-supported", - "uri-authentication-supported", - "printer-name", - "printer-location", - "printer-info", - "printer-more-info", - "printer-driver-installer", - "printer-make-and-model", - "printer-more-info-manufacturer", - "printer-state", - "printer-state-reasons", - "printer-state-message", - "ipp-versions-supported", - "multiple-document-jobs-supported", - "charset-configured", - "charset-supported", - "natural-language-configured", - "generated-natural-language-supported", - "document-format-default", - "document-format-supported", - "printer-is-accepting-jobs", - "queued-job-count", - "printer-message-from-operator", - "color-supported", - "reference-uri-schemes-supported", - "pdl-override-supported", - "printer-up-time", - "printer-current-time", - "multiple-operation-time-out", - "compression-supported", - "job-k-octets-supported", - "job-impressions-supported", - "job-media-sheets-supported", - "pages-per-minute", - "pages-per-minute-color", - NULL -}; diff --git a/usr/src/lib/print/libipp-core/common/write.c b/usr/src/lib/print/libipp-core/common/write.c deleted file mode 100644 index aef693a365..0000000000 --- a/usr/src/lib/print/libipp-core/common/write.c +++ /dev/null @@ -1,415 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: write.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <inttypes.h> - -#include <papi.h> -#include <ipp.h> - -static int8_t -papi_attribute_to_ipp_type(papi_attribute_value_type_t type) -{ - switch (type) { - case PAPI_INTEGER: - return (VTAG_INTEGER); - case PAPI_BOOLEAN: - return (VTAG_BOOLEAN); - case PAPI_RANGE: - return (VTAG_RANGE_OF_INTEGER); - case PAPI_RESOLUTION: - return (VTAG_RESOLUTION); - case PAPI_DATETIME: - return (VTAG_DATE_TIME); - case PAPI_STRING: - return (VTAG_TEXT_WITHOUT_LANGUAGE); - } - - return (0); -} - -static papi_status_t -papi_ipp_type_match(papi_attribute_value_type_t papi, int8_t ipp) -{ - switch (papi) { - case PAPI_STRING: - switch (ipp) { - case VTAG_URI: - case VTAG_OCTET_STRING: - case VTAG_TEXT_WITHOUT_LANGUAGE: - case VTAG_URI_SCHEME: - case VTAG_CHARSET: - case VTAG_NATURAL_LANGUAGE: - case VTAG_MIME_MEDIA_TYPE: - case VTAG_NAME_WITHOUT_LANGUAGE: - case VTAG_KEYWORD: - break; - default: - return (PAPI_CONFLICT); - } - break; - case PAPI_INTEGER: - switch (ipp) { - case VTAG_ENUM: - case VTAG_INTEGER: - break; - default: - return (PAPI_CONFLICT); - } - break; - case PAPI_BOOLEAN: - if (ipp != VTAG_BOOLEAN) - return (PAPI_CONFLICT); - break; - case PAPI_RANGE: - if (ipp != VTAG_RANGE_OF_INTEGER) - return (PAPI_CONFLICT); - break; - case PAPI_RESOLUTION: - if (ipp != VTAG_RESOLUTION) - return (PAPI_CONFLICT); - break; - case PAPI_DATETIME: - if (ipp != VTAG_DATE_TIME) - return (PAPI_CONFLICT); - break; - case PAPI_COLLECTION: - /* don't need to match */ - break; - } - - return (PAPI_OK); -} - -static papi_status_t -ipp_write_attribute(ipp_writer_t iwrite, void *fd, papi_attribute_t *attribute) -{ - papi_status_t status; - papi_attribute_value_t **values; - int8_t type; - int i; - char *name; - - name = attribute->name; - values = attribute->values; - - if ((type = name_to_ipp_type(name)) == 0) - type = papi_attribute_to_ipp_type(attribute->type); - - /* The types don't match, so don't send the attribute */ - if ((status = papi_ipp_type_match(attribute->type, type)) != PAPI_OK) - return (status); - - if (values == NULL) { - uint16_t length; - - type = VTAG_UNSUPPORTED; - if (iwrite(fd, &type, 1) != 1) - return (PAPI_DEVICE_ERROR); - - if (name != NULL) { /* first value gets named */ - length = (uint16_t)htons(strlen(name)); - - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, name, strlen(name)) != strlen(name)) - return (PAPI_DEVICE_ERROR); - } - - length = (uint16_t)htons(0); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - - return (PAPI_OK); - } - - - - for (i = 0; values[i] != NULL; i++) { - papi_attribute_value_t *value = values[i]; - uint16_t length = 0; - - if (iwrite(fd, &type, 1) != 1) - return (PAPI_DEVICE_ERROR); - - if (name != NULL) { /* first value gets named */ - length = (uint16_t)htons(strlen(name)); - - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, name, strlen(name)) != strlen(name)) - return (PAPI_DEVICE_ERROR); - name = NULL; - } else { - length = (uint16_t)htons(0); - - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - } - - switch (attribute->type) { - case PAPI_STRING: { - char *v = (char *)value->string; - - if (v != NULL) { - size_t str_length = strlen(v); - - /* - * if the length is more than 16 bits can - * express, send what can be represented - * in 16 bits. IPP "strings" can only be - * that large. - */ - if (str_length > 0xFFFF) - str_length = 0xFFFF; - - length = (uint16_t)htons(str_length); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, v, str_length) != str_length) - return (PAPI_DEVICE_ERROR); - } else - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - } - break; - case PAPI_BOOLEAN: { - int8_t v = (int8_t)value->boolean; - - length = (uint16_t)htons(1); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &v, 1) != 1) - return (PAPI_DEVICE_ERROR); - } - break; - case PAPI_INTEGER: { - int32_t v = (int32_t)value->integer; - - length = (uint16_t)htons(4); - v = (int32_t)htonl(v); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &v, 4) != 4) - return (PAPI_DEVICE_ERROR); - } - break; - case PAPI_RANGE: { - int32_t min = (int32_t)htonl((int)(value->range).lower), - max = (int32_t)htonl((int)(value->range).upper); - - length = (uint16_t)htons(8); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &min, 4) != 4) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &max, 4) != 4) - return (PAPI_DEVICE_ERROR); - } - break; - case PAPI_RESOLUTION: { - int32_t x = (int)(value->resolution).xres, - y = (int)(value->resolution).yres; - int8_t units = (int8_t)(value->resolution).units; - - length = (uint16_t)htons(9); - x = (int32_t)htonl(x); - y = (int32_t)htonl(y); - - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &x, 4) != 4) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &y, 4) != 4) - return (PAPI_DEVICE_ERROR); - if (iwrite(fd, &units, 1) != 1) - return (PAPI_DEVICE_ERROR); - } - break; - case PAPI_DATETIME: { - struct tm *v = gmtime(&value->datetime); - int8_t c; - uint16_t s; - - length = (uint16_t)htons(11); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - s = (uint16_t)htons(v->tm_year + 1900); - if (iwrite(fd, &s, 2) != 2) - return (PAPI_DEVICE_ERROR); - c = v->tm_mon + 1; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = v->tm_mday; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = v->tm_hour; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = v->tm_min; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = v->tm_sec; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = /* v->deciseconds */ 0; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = /* v->utc_dir */ 0; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = /* v->utc_hours */ 0; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - c = /* v->utc_minutes */ 0; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - } - break; - default: { - /* - * If there is a value, it is not one of our - * types, so we couldn't use it anyway. We assume - * that it was an OOB type with no value - */ - length = (uint16_t)htons(0); - if (iwrite(fd, &length, 2) != 2) - return (PAPI_DEVICE_ERROR); - } - break; - } - } - - return (PAPI_OK); -} - -static papi_status_t -ipp_write_attribute_group(ipp_writer_t iwrite, void *fd, int8_t type, - papi_attribute_t **attributes) -{ - papi_status_t result = PAPI_OK; - int i; - - /* write group tag */ - if (iwrite(fd, &type, 1) != 1) - return (PAPI_DEVICE_ERROR); - - /* write values */ - for (i = 0; ((attributes[i] != NULL) && (result == PAPI_OK)); i++) - result = ipp_write_attribute(iwrite, fd, attributes[i]); - - return (result); -} - -static papi_status_t -ipp_write_attribute_groups(ipp_writer_t iwrite, void *fd, - papi_attribute_t **groups) -{ - papi_status_t result = PAPI_OK; - int8_t c; - - for (c = DTAG_MIN; c <= DTAG_MAX; c++) { - papi_status_t status; - papi_attribute_t **group = NULL; - void *iter = NULL; - char name[32]; - - (void) ipp_tag_string(c, name, sizeof (name)); - for (status = papiAttributeListGetCollection(groups, &iter, - name, &group); - ((status == PAPI_OK) && (result == PAPI_OK)); - status = papiAttributeListGetCollection(groups, &iter, - NULL, &group)) - result = ipp_write_attribute_group(iwrite, fd, - c, group); - } - - c = DTAG_END_OF_ATTRIBUTES; - if (iwrite(fd, &c, 1) != 1) - result = PAPI_DEVICE_ERROR; - - return (result); -} - -static papi_status_t -ipp_write_message_header(ipp_writer_t iwrite, void *fd, - papi_attribute_t **message) -{ - int tmp; - int8_t c; - uint16_t s; - int32_t i; - - /* write the version */ - papiAttributeListGetInteger(message, NULL, "version-major", &tmp); - c = tmp; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - - papiAttributeListGetInteger(message, NULL, "version-minor", &tmp); - c = tmp; - if (iwrite(fd, &c, 1) != 1) - return (PAPI_DEVICE_ERROR); - - /* write the request/status code */ - papiAttributeListGetInteger(message, NULL, "status-code", &tmp); - papiAttributeListGetInteger(message, NULL, "operation-id", &tmp); - s = (uint16_t)htons(tmp); - if (iwrite(fd, &s, 2) != 2) - return (PAPI_DEVICE_ERROR); - - /* write the request id */ - papiAttributeListGetInteger(message, NULL, "request-id", &tmp); - i = (uint32_t)htonl(tmp); - if (iwrite(fd, &i, 4) != 4) - return (PAPI_DEVICE_ERROR); - - return (PAPI_OK); -} - -papi_status_t -ipp_write_message(ipp_writer_t iwrite, void *fd, papi_attribute_t **message) -{ - papi_status_t result; - - if ((iwrite == NULL) || (fd == NULL) || (message == NULL)) - return (PAPI_BAD_ARGUMENT); - - result = ipp_write_message_header(iwrite, fd, message); - if (result == PAPI_OK) - result = ipp_write_attribute_groups(iwrite, fd, message); - - return (result); -} diff --git a/usr/src/lib/print/libipp-listener/Makefile.com b/usr/src/lib/print/libipp-listener/Makefile.com deleted file mode 100644 index 4db2966ceb..0000000000 --- a/usr/src/lib/print/libipp-listener/Makefile.com +++ /dev/null @@ -1,68 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# - -LIBRARY = libipp-listener.a -VERS = .0 -OBJECTS = \ - cancel-job.o common.o create-job.o cups-accept-jobs.o \ - cups-get-classes.o cups-get-default.o cups-get-printers.o \ - cups-move-job.o cups-reject-jobs.o disable-printer.o enable-printer.o \ - get-job-attributes.o get-jobs.o get-printer-attributes.o hold-job.o \ - ipp-listener.o pause-printer.o print-job.o purge-jobs.o release-job.o \ - restart-job.o resume-printer.o send-document.o set-job-attributes.o \ - set-printer-attributes.o validate-job.o - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -DSOLARIS_PRIVATE_POST_0_9 -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common -CPPFLAGS += -I../../libipp-core/common - -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-uninitialized - -MAPFILES = $(SRCDIR)/mapfile - -LDLIBS += -lipp-core -lpapi -lc -lsocket -lnsl - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libipp-listener/common/cancel-job.c b/usr/src/lib/print/libipp-listener/common/cancel-job.c deleted file mode 100644 index 49ad1980f8..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cancel-job.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cancel-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_cancel_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *message = NULL; - char *queue = NULL; - int id = -1; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group may contain: - * message - */ - (void) papiAttributeListGetString(operational, NULL, - "message", &message); - - status = papiJobCancel(svc, queue, id); - if (status != PAPI_OK) { - ipp_set_status(response, status, - "cancel failed: %s-%d: %s", - (queue ? queue : "(null)"), id, - ipp_svc_status_mesg(svc, status)); - } else if (message != NULL) { /* add unsupported attribute group */ - papi_attribute_t **unsupported = NULL; - - papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, - "message", PAPI_COLLECTION, NULL); - (void) papiAttributeListAddCollection(response, - PAPI_ATTR_REPLACE, "unsupported-attributes-group", - unsupported); - papiAttributeListFree(unsupported); - - status = PAPI_OK_SUBST; - ipp_set_status(response, status, - "unsupported attribute in request"); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/common.c b/usr/src/lib/print/libipp-listener/common/common.c deleted file mode 100644 index a8fbe45098..0000000000 --- a/usr/src/lib/print/libipp-listener/common/common.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: common.c 155 2006-04-26 02:34:54Z ktou $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <sys/types.h> -#include <unistd.h> -#include <papi.h> -#include <ipp-listener.h> - -char * -ipp_svc_status_mesg(papi_service_t svc, papi_status_t status) -{ - char *mesg = papiServiceGetStatusMessage(svc); - - if (mesg == NULL) - mesg = papiStatusString(status); - - return (mesg); -} - -char * -destination_from_printer_uri(char *uri) -{ - static char buf[64]; - char *result = NULL; - - if (uri != NULL) - result = strrchr(uri, '/'); - - if (result == NULL) - result = uri; - else - result++; - -#ifdef FORCE_LPSCHED_URI - snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", result); - result = buf; -#endif /* FORCE_LPSCHED_URI */ - - return (result); -} - -void -get_printer_id(papi_attribute_t **attributes, char **printer, int *id) -{ - papi_status_t result; - char *job = NULL; - char *fodder; - int junk; - - if (printer == NULL) - printer = &fodder; - if (id == NULL) - id = &junk; - - *printer = NULL; - *id = -1; - - result = papiAttributeListGetString(attributes, NULL, "job-uri", &job); - if (result != PAPI_OK) { - result = papiAttributeListGetString(attributes, NULL, - "printer-uri", printer); - if (result == PAPI_OK) - papiAttributeListGetInteger(attributes, NULL, - "job-id", id); - } else { - *printer = job; - if ((job = strrchr(*printer, '/')) != NULL) { - *job = '\0'; - *id = atoi(++job); - } - } -} - -void -get_string_list(papi_attribute_t **attributes, char *name, char ***values) -{ - papi_status_t result; - - void *iterator = NULL; - char *value = NULL; - - for (result = papiAttributeListGetString(attributes, &iterator, - name, &value); - result == PAPI_OK; - result = papiAttributeListGetString(attributes, &iterator, - NULL, &value)) - list_append(values, value); -} - -void -add_default_attributes(papi_attribute_t ***attributes) -{ - - (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND, - "ipp-versions-supported", "1.0"); - (void) papiAttributeListAddString(attributes, PAPI_ATTR_APPEND, - "ipp-versions-supported", "1.1"); - (void) papiAttributeListAddBoolean(attributes, PAPI_ATTR_EXCL, - "multiple-document-jobs-supported", 0); - /* - * Should be able to ask the web server if it supports SSL or TLS, but - * for now, we pick only "none" - */ - (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, - "uri-security-supported", "none"); - - /* - * For now, we only "none". As we support more authentication methods, - * we will need to add the associated uri for each. Valid values would - * be: - * "none", "requesting-user-name", "basic", "digest", "certificate" - * See RFC2911 page 127 for more information. - */ - (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, - "uri-authentication-supported", "requesting-user-name"); - (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, - "uri-security-supported", "none"); - /* printer-uri-supported is added in the service based attributes */ - - (void) papiAttributeListAddInteger(attributes, PAPI_ATTR_EXCL, - "multiple-operation-time-out", 60); - - /* I18N related */ - (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, - "charset-configured", "utf-8"); - (void) papiAttributeListAddString(attributes, PAPI_ATTR_EXCL, - "charset-supported", "utf-8"); - (void) papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, - "natural-language-configured", "en-us"); -} - -static void -massage_printer_attributes_group(papi_attribute_t **group, char *printer_uri) -{ - if (papiAttributeListFind(group, "printer-uri-supported") != NULL) - papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, - "printer-uri-supported", printer_uri); -} - -static void -massage_job_attributes_group(papi_attribute_t **group, char *printer_uri) -{ - if (papiAttributeListFind(group, "job-printer-uri") != NULL) - papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, - "job-printer-uri", printer_uri); - - if (papiAttributeListFind(group, "job-printer-uri") != NULL) { - char buf[BUFSIZ]; - int32_t id = -1; - - papiAttributeListGetInteger(group, NULL, "job-id", &id); - snprintf(buf, sizeof (buf), "%s/%d", printer_uri, id); - papiAttributeListAddString(&group, PAPI_ATTR_REPLACE, - "job-uri", buf); - } -} - -/* - * This function will replace the job/printer URIs with the requested - * uri because the print service may return a URI that isn't IPP based. - */ -void -massage_response(papi_attribute_t **request, papi_attribute_t **response) -{ - papi_status_t status; - papi_attribute_t **group = NULL; - void *iter = NULL; - char *host = "localhost"; - char *path = "/printers/"; - int port = 631; - char buf[BUFSIZ]; - - (void) papiAttributeListGetString(request, NULL, "uri-host", &host); - (void) papiAttributeListGetString(request, NULL, "uri-path", &path); - (void) papiAttributeListGetInteger(request, NULL, "uri-port", &port); - - if (port == 631) - snprintf(buf, sizeof (buf), "ipp://%s%s", host, path); - else - snprintf(buf, sizeof (buf), "http://%s:%d%s", host, port, path); - - for (status = papiAttributeListGetCollection(response, &iter, - "printer-attributes-group", &group); - status == PAPI_OK; - status = papiAttributeListGetCollection(NULL, &iter, - NULL, &group)) - massage_printer_attributes_group(group, buf); - - iter = NULL; - for (status = papiAttributeListGetCollection(response, &iter, - "job-attributes-group", &group); - status == PAPI_OK; - status = papiAttributeListGetCollection(NULL, &iter, - NULL, &group)) - massage_job_attributes_group(group, buf); -} - -/* - * This walks through the locale tab and returns the installed - * locales. There must be a better way. - */ -void -add_supported_locales(papi_attribute_t ***attributes) -{ - FILE *fp; - - papiAttributeListAddString(attributes, PAPI_ATTR_REPLACE, - "generated-natural-language-supported", "en-us"); - -#ifndef __linux__ /* this is Solaris specific */ - if ((fp = fopen("/usr/lib/locale/lcttab", "r")) != NULL) { - char buf[1024]; - - while (fgets(buf, sizeof (buf), fp) != NULL) { - char *name, *file; - int i, passed = 1; - - name = strtok(buf, " \t\n"); - - for (i = 0; ((passed == 1) && (name[i] != NULL)); i++) - if (isalpha(name[i]) != 0) - name[i] = tolower(name[i]); - else if ((name[i] == '_') || (name[i] == '-')) - name[i] = '-'; - else - passed = 0; - - if ((passed == 1) && - ((file = strtok(NULL, " \t\n")) != NULL)) { - char path[1024]; - - snprintf(path, sizeof (path), - "/usr/lib/locale/%s", file); - - if (access(path, F_OK) == 0) - papiAttributeListAddString(attributes, - PAPI_ATTR_APPEND, - "generated-natural-language-supported", - name); - } - } - } -#endif -} - -void -papi_to_ipp_printer_group(papi_attribute_t ***response, - papi_attribute_t **request, int flags, papi_printer_t p) -{ - papi_attribute_t **ipp_group = NULL; - - copy_attributes(&ipp_group, papiPrinterGetAttributeList(p)); - - /* Windows clients appear to have a problem with very large values */ - papiAttributeListDelete(&ipp_group, "lpsched-printer-ppd-contents"); - - add_default_attributes(&ipp_group); - ipp_operations_supported(&ipp_group, request); - - (void) papiAttributeListAddCollection(response, flags, - "printer-attributes-group", ipp_group); - papiAttributeListFree(ipp_group); -} - -void -papi_to_ipp_job_group(papi_attribute_t ***response, - papi_attribute_t **request, int flags, papi_job_t j) -{ - papi_attribute_t **ipp_group = NULL; - - copy_attributes(&ipp_group, papiJobGetAttributeList(j)); - - (void) papiAttributeListAddCollection(response, flags, - "job-attributes-group", ipp_group); - papiAttributeListFree(ipp_group); -} diff --git a/usr/src/lib/print/libipp-listener/common/create-job.c b/usr/src/lib/print/libipp-listener/common/create-job.c deleted file mode 100644 index 996b235cea..0000000000 --- a/usr/src/lib/print/libipp-listener/common/create-job.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: create-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_create_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - char *queue = NULL; - char *keys[] = { "attributes-natural-language", "attributes-charset", - "printer-uri", NULL }; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * job-name - * ipp-attribute-fidelity - * document-name - * compression - * document-format - * document-natural-language - * job-k-octets - * job-impressions - * job-media-sheets - * Simply copy the entire contents of the operational-attributes-group - * for the PAPI call's possible use. - */ - - /* copy the pointers only, not the elements */ - split_and_copy_attributes(keys, operational, NULL, &job_attributes); - - /* copy any job-attributes-group attributes for the PAPI call */ - if (papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &operational) == PAPI_OK) - copy_attributes(&job_attributes, operational); - - /* - * request job creation, using Sun extention to PAPI. The - * functionality in this extension is expected to make the - * next revision of the PAPI. - */ - status = papiJobCreate(svc, queue, job_attributes, NULL, &j); - papiAttributeListFree(job_attributes); - if (status != PAPI_OK) { - ipp_set_status(response, status, "job creation: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c deleted file mode 100644 index 01a91ba5fd..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-accept-jobs.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-accept-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -cups_accept_jobs(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) { - ipp_set_status(response, status, "accept failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-classes.c b/usr/src/lib/print/libipp-listener/common/cups-get-classes.c deleted file mode 100644 index a6aea61908..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-get-classes.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-get-classes.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -cups_get_classes(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_printer_t *p = NULL; - papi_attribute_t **operational = NULL; - papi_filter_t filt; - - char **req_attrs = NULL; - int limit = 0; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group may contain: - * limit - * printer-info - * printer-location - * printer-type - * printer-type-mask - * requested-attributes - */ - - papiAttributeListGetInteger(operational, NULL, "limit", &limit); - - get_string_list(operational, "requested-attributes", &req_attrs); - - /* only ask for the classes */ - filt.type = PAPI_FILTER_BITMASK; - filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS; - filt.filter.bitmask.value = PAPI_PRINTER_CLASS; - - status = papiPrintersList(svc, req_attrs, &filt, &p); - if (status != PAPI_OK) { - ipp_set_status(response, status, "query printers: %s", - ipp_svc_status_mesg(svc, status)); - papiPrinterFree(p); /* we shouldn't have a printer */ - return (status); - } - - if (p != NULL) { - int i; - - for (i = 0; p[i] != NULL; i++) - papi_to_ipp_printer_group(response, request, - PAPI_ATTR_APPEND, p[i]); - papiPrinterListFree(p); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-default.c b/usr/src/lib/print/libipp-listener/common/cups-get-default.c deleted file mode 100644 index 0bb084ac9e..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-get-default.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-get-default.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -#include <config-site.h> - -papi_status_t -cups_get_default(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_printer_t p = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **printer_attributes = NULL; - - char **req_attrs = NULL; - int limit = 0; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group may contain: - * requested-attributes - */ - get_string_list(operational, "requested-attributes", &req_attrs); - - status = papiPrinterQuery(svc, DEFAULT_DEST, req_attrs, NULL, &p); - if (status != PAPI_OK) { - ipp_set_status(response, status, "query default: %s", - ipp_svc_status_mesg(svc, status)); - papiPrinterFree(p); /* we shouldn't have a printer */ - return (status); - } - - /* - * add the printer attributes to the response in a - * printer-attributes-group - */ - printer_attributes = papiPrinterGetAttributeList(p); - add_default_attributes(&printer_attributes); - (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, - "printer-attributes-group", printer_attributes); - - papiPrinterFree(p); - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-get-printers.c b/usr/src/lib/print/libipp-listener/common/cups-get-printers.c deleted file mode 100644 index e883543381..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-get-printers.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-get-printers.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -cups_get_printers(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_printer_t *p = NULL; - papi_attribute_t **operational = NULL; - papi_filter_t filt; - - char **req_attrs = NULL; - int limit = 0; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group may contain: - * limit - * printer-info - * printer-location - * printer-type - * printer-type-mask - * requested-attributes - */ - - papiAttributeListGetInteger(operational, NULL, "limit", &limit); - - get_string_list(operational, "requested-attributes", &req_attrs); - - /* only ask for the classes */ - filt.type = PAPI_FILTER_BITMASK; - filt.filter.bitmask.mask = ~PAPI_PRINTER_CLASS; - filt.filter.bitmask.value = PAPI_PRINTER_LOCAL | PAPI_PRINTER_REMOTE; - - /* query the print service for printers information */ - status = papiPrintersList(svc, req_attrs, &filt, &p); - if (status != PAPI_OK) { - ipp_set_status(response, status, "query printers: %s", - ipp_svc_status_mesg(svc, status)); - papiPrinterListFree(p); /* we shouldn't have any printers */ - return (status); - } - - if (p != NULL) { - int i; - - for (i = 0; p[i] != NULL; i++) - papi_to_ipp_printer_group(response, request, - PAPI_ATTR_APPEND, p[i]); - papiPrinterListFree(p); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-move-job.c b/usr/src/lib/print/libipp-listener/common/cups-move-job.c deleted file mode 100644 index 137a507f93..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-move-job.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-move-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -cups_move_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL, **job = NULL; - - char *message = NULL; - char *job_printer_uri = NULL; - char *queue = NULL; - char *dest = NULL; - int id = -1; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * Get job attributes from the request - */ - status = papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &job); - if (status != PAPI_OK) { - ipp_set_status(response, status, - "job-attributes-group: %s", - papiStatusString(status)); - return (status); - } - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the job-attributes-group must contain: - * job-printer-uri - */ - job_printer_uri = NULL; - (void) papiAttributeListGetString(job, NULL, - "job-printer-uri", &job_printer_uri); - if (job_printer_uri == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-printer-uri"); - return (PAPI_BAD_REQUEST); - } else - dest = destination_from_printer_uri(job_printer_uri); - - if ((status = papiJobMove(svc, queue, id, dest)) != PAPI_OK) - ipp_set_status(response, status, - "move failed: %s-%d to %s: %s", - (queue ? queue : "(null)"), id, - (dest ? dest : "(null)"), - ipp_svc_status_mesg(svc, status)); - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c b/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c deleted file mode 100644 index 1a35acdf62..0000000000 --- a/usr/src/lib/print/libipp-listener/common/cups-reject-jobs.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: cups-reject-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -cups_reject_jobs(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) { - ipp_set_status(response, status, "pause failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/disable-printer.c b/usr/src/lib/print/libipp-listener/common/disable-printer.c deleted file mode 100644 index e1c2fd3b5c..0000000000 --- a/usr/src/lib/print/libipp-listener/common/disable-printer.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: disable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_disable_printer(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - char *message = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * printer-message-from-operator - */ - (void) papiAttributeListGetString(operational, NULL, - "printer-message-from-operator", &message); - - if ((status = papiPrinterDisable(svc, queue, message)) != PAPI_OK) { - ipp_set_status(response, status, "disable failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/enable-printer.c b/usr/src/lib/print/libipp-listener/common/enable-printer.c deleted file mode 100644 index 0d5419d51d..0000000000 --- a/usr/src/lib/print/libipp-listener/common/enable-printer.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: enable-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_enable_printer(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterEnable(svc, queue)) != PAPI_OK) { - ipp_set_status(response, status, "enable failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/get-job-attributes.c b/usr/src/lib/print/libipp-listener/common/get-job-attributes.c deleted file mode 100644 index 7f74054ebe..0000000000 --- a/usr/src/lib/print/libipp-listener/common/get-job-attributes.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: get-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_get_job_attributes(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - - char **req_attrs = NULL; - char *queue = NULL; - int id = -1; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group should contain: - * requested-attributes - */ - get_string_list(operational, "requested-attributes", &req_attrs); - - if ((status = papiJobQuery(svc, queue, id, req_attrs, &j)) != PAPI_OK) { - ipp_set_status(response, status, "query job: %s", - ipp_svc_status_mesg(svc, status)); - papiJobFree(j); /* we shouldn't have a job, but just in case */ - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/get-jobs.c b/usr/src/lib/print/libipp-listener/common/get-jobs.c deleted file mode 100644 index 0e5e56f44c..0000000000 --- a/usr/src/lib/print/libipp-listener/common/get-jobs.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: get-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_get_jobs(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_job_t *j = NULL; - papi_attribute_t **operational = NULL; - - char **req_attrs = NULL; - char *queue = NULL; - int limit = 0; - char my_jobs = PAPI_FALSE; - char *which; - int type = 0; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * limit - * requested-attributes - * which-jobs - * my-jobs - */ - (void) papiAttributeListGetString(operational, NULL, - "which-jobs", &which); - (void) papiAttributeListGetBoolean(operational, NULL, - "my-jobs", &my_jobs); - (void) papiAttributeListGetInteger(operational, NULL, "limit", &limit); - get_string_list(operational, "requested-attributes", &req_attrs); - - status = papiPrinterListJobs(svc, queue, req_attrs, type, limit, &j); - if (status != PAPI_OK) { - ipp_set_status(response, status, "query jobs: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* add any job's attributes to the response in job-attribute-groups */ - if (j != NULL) { - int i; - - for (i = 0; j[i] != NULL; i++) - papi_to_ipp_job_group(response, request, - PAPI_ATTR_APPEND, j[i]); - papiJobListFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c deleted file mode 100644 index 2f33d0039c..0000000000 --- a/usr/src/lib/print/libipp-listener/common/get-printer-attributes.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: get-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_get_printer_attributes(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_printer_t p = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **printer_attributes = NULL; - - char **req_attrs = NULL; - char *doc_fmt = NULL; - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * requested-attributes - * document-format - */ - get_string_list(operational, "requested-attributes", &req_attrs); - (void) papiAttributeListGetString(operational, NULL, - "document-format", &doc_fmt); - status = papiPrinterQuery(svc, queue, req_attrs, NULL, &p); - if (status != PAPI_OK) { - ipp_set_status(response, status, "query printer: %s", - ipp_svc_status_mesg(svc, status)); - papiPrinterFree(p); /* we shouldn't have a printer */ - return (status); - } - - /* - * add the printer attributes to the response in a - * printer-attributes-group - */ - if (p != NULL) { - papi_to_ipp_printer_group(response, request, - PAPI_ATTR_REPLACE, p); - papiPrinterFree(p); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/hold-job.c b/usr/src/lib/print/libipp-listener/common/hold-job.c deleted file mode 100644 index fcb1409df6..0000000000 --- a/usr/src/lib/print/libipp-listener/common/hold-job.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: hold-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_hold_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *message = NULL; - char *queue = NULL; - int id = -1; - - /* Get operational attributes from the request */ - papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group may contain: - * message - * job-hold-until (ingored) - */ - (void) papiAttributeListGetString(operational, NULL, - "message", &message); - - if ((status = papiJobHold(svc, queue, id)) != PAPI_OK) { - ipp_set_status(response, status, - "hold failed: %s-%d: %s", - (queue ? queue : "(null)"), id, - ipp_svc_status_mesg(svc, status)); - } else if (message != NULL) { /* add unsupported attribute group */ - papi_attribute_t **unsupported = NULL; - - papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, - "message", PAPI_COLLECTION, NULL); - (void) papiAttributeListAddCollection(response, - PAPI_ATTR_REPLACE, "unsupported-attributes-group", - unsupported); - papiAttributeListFree(unsupported); - - status = PAPI_OK_SUBST; - ipp_set_status(response, status, - "unsupported attribute in request"); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.c b/usr/src/lib/print/libipp-listener/common/ipp-listener.c deleted file mode 100644 index 42f23f85e7..0000000000 --- a/usr/src/lib/print/libipp-listener/common/ipp-listener.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: ipp-listener.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <netinet/in.h> -#include <assert.h> -#include <errno.h> -#include <syslog.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/systeminfo.h> - -#include <papi.h> -#include <ipp-listener.h> -#include <uri.h> - -typedef papi_status_t (ipp_handler_t)(papi_service_t svc, - papi_attribute_t **request, - papi_attribute_t ***response, - ipp_reader_t iread, void *fd); - -/* - * protocol request handlers are inserted below. The handler must be - * declared extern immediately below this comment and then an entry - * must be inserted in the "handlers" table a little further down. - */ -extern ipp_handler_t ipp_print_job; -extern ipp_handler_t ipp_validate_job; -extern ipp_handler_t ipp_create_job; -extern ipp_handler_t ipp_get_printer_attributes; -extern ipp_handler_t ipp_get_jobs; -extern ipp_handler_t ipp_pause_printer; -extern ipp_handler_t ipp_resume_printer; -extern ipp_handler_t ipp_disable_printer; -extern ipp_handler_t ipp_enable_printer; -extern ipp_handler_t ipp_purge_jobs; -extern ipp_handler_t ipp_send_document; -extern ipp_handler_t ipp_cancel_job; -extern ipp_handler_t ipp_get_job_attributes; -extern ipp_handler_t ipp_release_job; -extern ipp_handler_t ipp_hold_job; -extern ipp_handler_t ipp_restart_job; -extern ipp_handler_t ipp_set_job_attributes; -extern ipp_handler_t ipp_set_printer_attributes; -extern ipp_handler_t cups_get_default; -extern ipp_handler_t cups_get_printers; -extern ipp_handler_t cups_get_classes; -extern ipp_handler_t cups_accept_jobs; -extern ipp_handler_t cups_reject_jobs; -extern ipp_handler_t cups_move_job; - -/* ARGSUSED0 */ -static papi_status_t -default_handler(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - int result = (int)PAPI_INTERNAL_ERROR; - - if (response != NULL) - (void) papiAttributeListGetInteger(*response, NULL, - "status-code", &result); - - return ((papi_status_t)result); -} - -static struct { - int16_t id; - char *name; - ipp_handler_t *function; - enum { OP_REQUIRED, OP_OPTIONAL, OP_VENDOR } type; -} handlers[] = { - /* Printer Operations */ - { 0x0002, "print-job", ipp_print_job, OP_REQUIRED }, - { 0x0003, "print-uri", NULL, OP_OPTIONAL }, - { 0x0004, "validate-job", ipp_validate_job, - OP_REQUIRED }, - { 0x0005, "create-job", ipp_create_job, OP_OPTIONAL }, - { 0x000a, "get-jobs", ipp_get_jobs, OP_REQUIRED }, - { 0x000b, "get-printer-attributes", ipp_get_printer_attributes, - OP_REQUIRED }, - { 0x0010, "pause-printer", ipp_pause_printer, - OP_OPTIONAL }, - { 0x0011, "resume-printer", ipp_resume_printer, - OP_OPTIONAL }, - { 0x0012, "purge-jobs", ipp_purge_jobs, OP_OPTIONAL }, - { 0x0013, "set-printer-attributes", ipp_set_printer_attributes, - OP_OPTIONAL }, - { 0x0014, "set-job-attributes", ipp_set_job_attributes, - OP_OPTIONAL }, - { 0x0022, "enable-printer", ipp_enable_printer, - OP_OPTIONAL }, - { 0x0023, "disable-printer", ipp_disable_printer, - OP_OPTIONAL }, - /* Job Operations */ - { 0x0006, "send-document", ipp_send_document, - OP_OPTIONAL }, - { 0x0007, "send-uri", NULL, OP_OPTIONAL }, - { 0x0008, "cancel-job", ipp_cancel_job, OP_REQUIRED }, - { 0x0009, "get-job-attributes", ipp_get_job_attributes, - OP_REQUIRED }, - { 0x000c, "hold-job", ipp_hold_job, OP_OPTIONAL }, - { 0x000d, "release-job", ipp_release_job, - OP_OPTIONAL }, - { 0x000e, "restart-job", ipp_restart_job, - OP_OPTIONAL }, - /* Other Operations */ - { 0x4001, "cups-get-default", cups_get_default, - OP_VENDOR }, - { 0x4002, "cups-get-printers", cups_get_printers, - OP_VENDOR }, - { 0x4005, "cups-get-classes", cups_get_classes, - OP_VENDOR }, - { 0x4008, "cups-accept-jobs", cups_accept_jobs, - OP_VENDOR }, - { 0x4009, "cups-reject-jobs", cups_reject_jobs, - OP_VENDOR }, - { 0x400D, "cups-move-job", cups_move_job, OP_VENDOR }, - { 0, NULL, NULL, OP_VENDOR } -}; - -static int -ipp_operation_name_to_index(char *name) -{ - int i; - - for (i = 0; handlers[i].name != NULL; i++) - if (strcasecmp(name, handlers[i].name) == 0) - return (i); - - return (-1); -} - -static int -ipp_operation_id_to_index(int16_t id) -{ - int i; - - for (i = 0; handlers[i].name != NULL; i++) - if (id == handlers[i].id) - return (i); - - return (-1); -} - -static ipp_handler_t * -ipp_operation_handler(papi_attribute_t **request, papi_attribute_t ***response) -{ - int id = 0; - int index; - papi_attribute_t **ops = NULL; - papi_status_t status; - char configured = PAPI_FALSE; - - /* get the operation from the request */ - status = papiAttributeListGetInteger(request, NULL, - "operation-id", &id); - if (status != PAPI_OK) { - ipp_set_status(response, PAPI_BAD_ARGUMENT, - "no operation specified in request"); - return (default_handler); - } - - /* find the operation in the handler table */ - index = ipp_operation_id_to_index(id); -#ifdef DEBUG - if (index == -1) - fprintf(stderr, "Operation: 0x%4.4x\n", id); - else - fprintf(stderr, "Operation: 0x%4.4x(%s)\n", id, - handlers[index].name); - fflush(stderr); -#endif - - if ((index == -1) || (handlers[index].function == NULL)) { - ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED, - "operation (0x%4.4x) not implemented by server", - id); - return (default_handler); - } - - /* find the configured operations */ - status = papiAttributeListGetCollection(request, NULL, - "operations", &ops); - if (status != PAPI_OK) { /* this should not be possible */ - ipp_set_status(response, PAPI_INTERNAL_ERROR, - "sofware error, no operations configured"); - return (default_handler); - } - - /* check if the requested operation is configured */ - status = papiAttributeListGetBoolean(ops, NULL, - handlers[index].name, &configured); - if ((status != PAPI_OK) || (configured != PAPI_TRUE)) { - ipp_set_status(response, PAPI_OPERATION_NOT_SUPPORTED, - "operation (%s 0x%4.4x) not enabled on server", - handlers[index].name, id); - return (default_handler); - } - - return (handlers[index].function); -} - -static char -type_to_boolean(char *type) -{ - char result = PAPI_FALSE; - - if ((strcasecmp(type, "true") == 0) || - (strcasecmp(type, "yes") == 0) || - (strcasecmp(type, "on") == 0) || - (strcasecmp(type, "enable") == 0)) - result = PAPI_TRUE; - - return (result); -} - -static papi_status_t -ipp_configure_required_operations(papi_attribute_t ***list, char boolean) -{ - papi_status_t result = PAPI_OK; - int i; - - for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++) - if (handlers[i].type == OP_REQUIRED) - result = papiAttributeListAddBoolean(list, - PAPI_ATTR_REPLACE, handlers[i].name, - boolean); - - return (result); - -} - -static papi_status_t -ipp_configure_all_operations(papi_attribute_t ***list, char boolean) -{ - papi_status_t result = PAPI_OK; - int i; - - for (i = 0; ((result == PAPI_OK) && (handlers[i].name != NULL)); i++) - result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE, - handlers[i].name, boolean); - - return (result); -} - -papi_status_t -ipp_configure_operation(papi_attribute_t ***list, char *operation, char *type) -{ - papi_status_t result = PAPI_OPERATION_NOT_SUPPORTED; - char boolean = PAPI_FALSE; - - if ((list == NULL) || (operation == NULL) || (type == NULL)) - return (PAPI_BAD_ARGUMENT); - - boolean = type_to_boolean(type); - - if (strcasecmp(operation, "all") == 0) { - result = ipp_configure_all_operations(list, boolean); - } else if (strcasecmp(operation, "required") == 0) { - result = ipp_configure_required_operations(list, boolean); - } else if (ipp_operation_name_to_index(operation) != -1) { - result = papiAttributeListAddBoolean(list, PAPI_ATTR_REPLACE, - operation, boolean); - } - - return (result); -} - -void -ipp_operations_supported(papi_attribute_t ***list, papi_attribute_t **request) -{ - papi_attribute_t **group = NULL; - - (void) papiAttributeListGetCollection(request, NULL, - "operations", &group); - if (group != NULL) { - int i; - - for (i = 0; handlers[i].name != NULL; i++) { - char boolean = PAPI_FALSE; - (void) papiAttributeListGetBoolean(group, NULL, - handlers[i].name, &boolean); - - if (boolean == PAPI_TRUE) - (void) papiAttributeListAddInteger(list, - PAPI_ATTR_APPEND, - "operations-supported", - handlers[i].id); - } - } -} - -static papi_status_t -ipp_initialize_response(papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_attribute_t **operational = NULL; - int i; - - if ((request == NULL) || (response == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* If the response was initialized, start over */ - if (*response != NULL) { - papiAttributeListFree(*response); - *response = NULL; - } - - /* Add the basic ipp header information to the response */ - (void) papiAttributeListGetInteger(request, NULL, "version-major", &i); - (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, - "version-major", i); - (void) papiAttributeListGetInteger(request, NULL, "version-minor", &i); - (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, - "version-minor", i); - - (void) papiAttributeListGetInteger(request, NULL, "request-id", &i); - (void) papiAttributeListAddInteger(response, PAPI_ATTR_REPLACE, - "request-id", i); - - /* Add a default operational attributes group to the response */ - (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, - "attributes-charset", "utf-8"); - (void) papiAttributeListAddString(&operational, PAPI_ATTR_EXCL, - "attributes-natural-language", "en-us"); - - (void) papiAttributeListAddCollection(response, PAPI_ATTR_REPLACE, - "operational-attributes-group", operational); - papiAttributeListFree(operational); - - return (PAPI_OK); -} - -/* simplistic check for cyclical service references */ -static int -cyclical_service_check(char *svc_name, int port) -{ - papi_attribute_t **list; - char buf[BUFSIZ]; - uri_t *uri = NULL; - char *s = NULL; - - /* was there a service_uri? */ - if (svc_name == NULL) - return (0); - - if ((list = getprinterbyname(svc_name, NULL)) == NULL) - return (0); /* if it doesnt' resolve, we will fail later */ - - papiAttributeListGetString(list, NULL, "printer-uri-supported", &s); - if ((s == NULL) || (strcasecmp(svc_name, s) != 0)) - return (0); /* they don't match */ - - /* is it in uri form? */ - if (uri_from_string(s, &uri) < 0) - return (0); - - if ((uri == NULL) || (uri->scheme == NULL) || (uri->host == NULL)) { - uri_free(uri); - return (0); - } - - /* is it ipp form */ - if (strcasecmp(uri->scheme, "ipp") != 0) { - uri_free(uri); - return (0); - } - - /* does the host match up */ - if (is_localhost(uri->host) != 0) { - uri_free(uri); - return (0); - } - - /* does the port match our own */ - if (((uri->port == NULL) && (port != 631)) || - ((uri->port != NULL) && (atoi(uri->port) != port))) { - uri_free(uri); - return (0); - } - - uri_free(uri); - - return (1); -} - -static papi_status_t -print_service_connect(papi_service_t *svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - char *printer_uri = NULL; - char *svc_name = NULL; - char *user = NULL; - int port = 631; - - /* Get the operational attributes group from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* get the user name */ - (void) papiAttributeListGetString(request, NULL, "default-user", &user); - (void) papiAttributeListGetString(operational, NULL, - "requesting-user-name", &user); - - /* get the printer or service name */ - (void) papiAttributeListGetString(request, NULL, - "default-service", &svc_name); - get_printer_id(operational, &svc_name, NULL); - - /* get the port that we are listening on */ - (void) papiAttributeListGetInteger(request, NULL, "uri-port", &port); - - if (cyclical_service_check(svc_name, port) != 0) { - status = PAPI_NOT_POSSIBLE; - ipp_set_status(response, status, "printer-uri is cyclical"); - return (status); - } - - status = papiServiceCreate(svc, svc_name, user, NULL, NULL, - PAPI_ENCRYPT_NEVER, NULL); - if (status != PAPI_OK) { - ipp_set_status(response, status, "print service: %s", - papiStatusString(status)); - return (status); - } - - /* - * Trusted Solaris can't be trusting of intermediaries. Pass - * the socket connection to the print service to retrieve the - * sensativity label off of a multi-level port. - */ - { - int fd = -1; - - (void) papiAttributeListGetInteger(request, NULL, - "peer-socket", &fd); - if (fd != -1) - papiServiceSetPeer(*svc, fd); - } - - return (status); -} - -papi_status_t -ipp_process_request(papi_attribute_t **request, papi_attribute_t ***response, - ipp_reader_t iread, void *fd) -{ - papi_status_t result = PAPI_OK; - - ipp_initialize_response(request, response); - -#ifdef DEBUG - fprintf(stderr, "REQUEST:"); - papiAttributeListPrint(stderr, request, " %d ", getpid()); - fprintf(stderr, "\n"); -#endif - - /* verify that the request is "well-formed" */ - if ((result = ipp_validate_request(request, response)) == PAPI_OK) { - papi_service_t svc = NULL; - ipp_handler_t *handler; - - result = print_service_connect(&svc, request, response); - handler = ipp_operation_handler(request, response); - - /* process the request */ - if ((result == PAPI_OK) && (handler != NULL)) - result = (handler)(svc, request, response, iread, fd); -#ifdef DEBUG - fprintf(stderr, "RESULT: %s\n", papiStatusString(result)); -#endif - papiServiceDestroy(svc); - } - - (void) papiAttributeListAddInteger(response, PAPI_ATTR_EXCL, - "status-code", result); - massage_response(request, *response); - -#ifdef DEBUG - fprintf(stderr, "RESPONSE:"); - papiAttributeListPrint(stderr, *response, " %d ", getpid()); - fprintf(stderr, "\n"); -#endif - - return (result); -} diff --git a/usr/src/lib/print/libipp-listener/common/ipp-listener.h b/usr/src/lib/print/libipp-listener/common/ipp-listener.h deleted file mode 100644 index 5a8718477e..0000000000 --- a/usr/src/lib/print/libipp-listener/common/ipp-listener.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _IPP_LISTENER_H -#define _IPP_LISTENER_H - -/* $Id: ipp-listener.h 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include <ipp.h> - -/* exported functions */ -extern papi_status_t ipp_configure_operation(papi_attribute_t ***list, - char *operation, char *type); -extern papi_status_t ipp_process_request(papi_attribute_t **request, - papi_attribute_t ***response, - ipp_reader_t iread, void *fd); - -/* shared internal functions */ -extern char *ipp_svc_status_mesg(papi_service_t svc, papi_status_t status); -extern char *destination_from_printer_uri(char *); -extern void get_printer_id(papi_attribute_t **attributes, char **printer, - int *id); -extern void ipp_operations_supported(papi_attribute_t ***list, - papi_attribute_t **request); -extern void get_string_list(papi_attribute_t **attributes, char *name, - char ***values); -extern void add_default_attributes(papi_attribute_t ***attributes); -extern void papi_to_ipp_printer_group(papi_attribute_t ***response, - papi_attribute_t **request, int flags, - papi_printer_t p); -extern void papi_to_ipp_job_group(papi_attribute_t ***response, - papi_attribute_t **request, int flags, papi_job_t j); -extern void massage_response(papi_attribute_t **request, - papi_attribute_t **response); - -#ifdef __cplusplus -} -#endif - -#endif /* _IPP_LISTENER_H */ diff --git a/usr/src/lib/print/libipp-listener/common/pause-printer.c b/usr/src/lib/print/libipp-listener/common/pause-printer.c deleted file mode 100644 index 0afe4aadf0..0000000000 --- a/usr/src/lib/print/libipp-listener/common/pause-printer.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: pause-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_pause_printer(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterPause(svc, queue, NULL)) != PAPI_OK) { - ipp_set_status(response, status, "pause failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/print-job.c b/usr/src/lib/print/libipp-listener/common/print-job.c deleted file mode 100644 index 29d6b5c5be..0000000000 --- a/usr/src/lib/print/libipp-listener/common/print-job.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: print-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#include <stdio.h> -#include <stdlib.h> -#include <netdb.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_print_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - papi_status_t status; - papi_stream_t s = NULL; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - char *queue = NULL; - ssize_t rc; - char buf[BUFSIZ]; - char *host = NULL; - int fp = -1; - char *keys[] = { "attributes-natural-language", "attributes-charset", - "printer-uri", NULL }; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * job-name - * ipp-attribute-fidelity - * document-name - * compression - * document-format - * document-natural-language - * job-k-octets - * job-impressions - * job-media-sheets - * Simply copy the entire contents of the operational-attributes-group - * for the PAPI call's possible use. - */ - split_and_copy_attributes(keys, operational, NULL, &job_attributes); - - /* copy any job-attributes-group attributes for the PAPI call */ - if (papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &operational) == PAPI_OK) { - char *user = NULL; - - copy_attributes(&job_attributes, operational); - - if (papiAttributeListGetString(operational, NULL, - "requesting-user-name", &user) == PAPI_OK) { - papiAttributeListAddString(&job_attributes, - PAPI_ATTR_REPLACE, "requesting-user-name", user); - } - } - - /* Set "job-originating-host-name" in next block */ - (void) papiAttributeListGetInteger(request, NULL, - "peer-socket", &fp); - - if (fp != -1) { - struct sockaddr_in peer; - socklen_t peer_len = sizeof (peer); - - /* who is our peer ? */ - if (getpeername(fp, (struct sockaddr *)&peer, - &peer_len) == 0) { - struct hostent *he; - int error_num; - - /* - * get their name or return a string containing - * their address - */ - if ((he = getipnodebyaddr((const char *)&peer.sin_addr, - sizeof (peer.sin_addr), peer.sin_family, - &error_num)) == NULL) { - char tmp_buf[INET6_ADDRSTRLEN]; - papiAttributeListAddString( - &job_attributes, - PAPI_ATTR_REPLACE, - "job-originating-host-name", - (char *)inet_ntop(peer.sin_family, - &peer.sin_addr, tmp_buf, - sizeof (tmp_buf))); - - } else { - if (is_localhost(he->h_name) != 0) - papiAttributeListAddString( - &job_attributes, - PAPI_ATTR_REPLACE, - "job-originating-host-name", - "localhost"); - else if (he->h_name != NULL) - papiAttributeListAddString( - &job_attributes, - PAPI_ATTR_REPLACE, - "job-originating-host-name", - he->h_name); - } - } - } - - /* request job creation with a resulting stream that we can write to */ - status = papiJobStreamOpen(svc, queue, job_attributes, NULL, &s); - papiAttributeListFree(job_attributes); - if (status != PAPI_OK) { - ipp_set_status(response, status, "job submission: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* copy the document data from the IPP connection to the stream */ - while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) - status = papiJobStreamWrite(svc, s, buf, rc); - if (status != PAPI_OK) { - ipp_set_status(response, status, "write job data: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* close the stream, committing the job */ - status = papiJobStreamClose(svc, s, &j); - if (status != PAPI_OK) { - ipp_set_status(response, status, "close job stream: %s", - ipp_svc_status_mesg(svc, status)); - papiJobFree(j); /* we shouldn't have a job, but just in case */ - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/purge-jobs.c b/usr/src/lib/print/libipp-listener/common/purge-jobs.c deleted file mode 100644 index 7128595844..0000000000 --- a/usr/src/lib/print/libipp-listener/common/purge-jobs.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: purge-jobs.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_purge_jobs(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_job_t *jobs = NULL; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterPurgeJobs(svc, queue, &jobs)) != PAPI_OK) { - ipp_set_status(response, status, "purge failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - papiJobListFree(jobs); - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/release-job.c b/usr/src/lib/print/libipp-listener/common/release-job.c deleted file mode 100644 index 0ae16906a6..0000000000 --- a/usr/src/lib/print/libipp-listener/common/release-job.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: release-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_release_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *message = NULL; - char *queue = NULL; - int id = -1; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group may contain: - * message - */ - (void) papiAttributeListGetString(operational, NULL, - "message", &message); - - if ((status = papiJobRelease(svc, queue, id)) != PAPI_OK) { - ipp_set_status(response, status, - "release failed: %s-%d: %s", - (queue ? queue : "(null)"), id, - ipp_svc_status_mesg(svc, status)); - } else if (message != NULL) { /* add unsupported attribute group */ - papi_attribute_t **unsupported = NULL; - - papiAttributeListAddValue(&unsupported, PAPI_ATTR_EXCL, - "message", PAPI_COLLECTION, NULL); - (void) papiAttributeListAddCollection(response, - PAPI_ATTR_REPLACE, "unsupported-attributes-group", - unsupported); - papiAttributeListFree(unsupported); - - status = PAPI_OK_SUBST; - ipp_set_status(response, status, - "unsupported attribute in request"); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/restart-job.c b/usr/src/lib/print/libipp-listener/common/restart-job.c deleted file mode 100644 index d78967b0f2..0000000000 --- a/usr/src/lib/print/libipp-listener/common/restart-job.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: restart-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_restart_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *message = NULL; - char *hold_until = NULL; - char *queue = NULL; - int id = -1; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group may contain: - * message - * job-hold-until - */ - (void) papiAttributeListGetString(operational, NULL, - "job-hold-until", &hold_until); - (void) papiAttributeListGetString(operational, NULL, - "message", &message); - - if ((status = papiJobRestart(svc, queue, id)) != PAPI_OK) { - ipp_set_status(response, status, - "restart failed: %s-%d: %s", - (queue ? queue : "(null)"), id, - ipp_svc_status_mesg(svc, status)); - } else if ((message != NULL) || (hold_until != NULL)) { - /* add unsupported attribute group */ - papi_attribute_t **unsupported = NULL; - - if (message != NULL) - (void) papiAttributeListAddValue(&unsupported, - PAPI_ATTR_EXCL, "message", - PAPI_COLLECTION, NULL); - if (hold_until != NULL) - (void) papiAttributeListAddValue(&unsupported, - PAPI_ATTR_EXCL, "hold-until", - PAPI_COLLECTION, NULL); - (void) papiAttributeListAddCollection(response, - PAPI_ATTR_REPLACE, "unsupported-attributes-group", - unsupported); - papiAttributeListFree(unsupported); - - status = PAPI_OK_SUBST; - ipp_set_status(response, status, - "unsupported attribute in request"); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/resume-printer.c b/usr/src/lib/print/libipp-listener/common/resume-printer.c deleted file mode 100644 index 8d48ee9adb..0000000000 --- a/usr/src/lib/print/libipp-listener/common/resume-printer.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: resume-printer.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_resume_printer(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - papi_status_t status; - papi_attribute_t **operational = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - if ((status = papiPrinterResume(svc, queue)) != PAPI_OK) { - ipp_set_status(response, status, "resume failed: %s: %s", - (queue ? queue : "(null)"), - ipp_svc_status_mesg(svc, status)); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/send-document.c b/usr/src/lib/print/libipp-listener/common/send-document.c deleted file mode 100644 index 4a4d3a4314..0000000000 --- a/usr/src/lib/print/libipp-listener/common/send-document.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: send-document.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -/* - * When the PAPI supports papiJobCreate(), papiJobStreamAdd() and - * papiJobClose(), this will be much cleaner and more efficient, but in the - * meantime, we are using a private, non-standard interface to do this. - */ -papi_status_t -ipp_send_document(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - papi_status_t status; - papi_stream_t s = NULL; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - char *queue = NULL; - ssize_t rc; - int id = -1; - char buf[BUFSIZ]; - char last = PAPI_FALSE; - char *keys[] = { "attributes-natural-language", "attributes-charset", - "printer-uri", "job-id", "job-uri", "last-document", - NULL }; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * the operational-attributes-group must contain: - * job-uri (or printer-uri/job-id) - * last-document - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - status = papiAttributeListGetBoolean(operational, NULL, - "last-document", &last); - if (status != PAPI_OK) { - ipp_set_status(response, status, "last-document: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * the operational-attributes-group may contain: - * document-name - * compression - * document-format - * document-natural-language - * Simply copy the entire contents of the operational-attributes-group - * for the PAPI call's possible use. - */ - split_and_copy_attributes(keys, operational, NULL, &job_attributes); - - /* copy any job-attributes-group attributes for the PAPI call */ - if (papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &operational) == PAPI_OK) - copy_attributes(&job_attributes, operational); - - /* create a stream to write the document data on */ - status = papiJobStreamAdd(svc, queue, id, &s); - papiAttributeListFree(job_attributes); - if (status != PAPI_OK) { - ipp_set_status(response, status, "job submission: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* copy the document data from the IPP connection to the stream */ - while ((status == PAPI_OK) && ((rc = iread(fd, buf, sizeof (buf))) > 0)) - status = papiJobStreamWrite(svc, s, buf, rc); - if (status != PAPI_OK) { - ipp_set_status(response, status, "write job data: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* close the stream */ - status = papiJobStreamClose(svc, s, &j); - if (status != PAPI_OK) { - ipp_set_status(response, status, "close job stream: %s", - ipp_svc_status_mesg(svc, status)); - papiJobFree(j); /* we shouldn't have a job, but just in case */ - return (status); - } - - /* if it's the last document, commit the job */ - if (last == PAPI_TRUE) { - status = papiJobCommit(svc, queue, id); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/set-job-attributes.c b/usr/src/lib/print/libipp-listener/common/set-job-attributes.c deleted file mode 100644 index 57c0b899f3..0000000000 --- a/usr/src/lib/print/libipp-listener/common/set-job-attributes.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: set-job-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_set_job_attributes(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - papi_status_t status; - papi_stream_t s = NULL; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - - char *queue = NULL; - int32_t id = -1; - ssize_t rc; - char buf[BUFSIZ]; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * job-uri - */ - get_printer_id(operational, &queue, &id); - if (id < 0) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing job-uri or job-id"); - return (PAPI_BAD_REQUEST); - } else if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* get the job-attributes-group attributes for the PAPI call */ - papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &job_attributes); - - /* request job modification */ - status = papiJobModify(svc, queue, id, job_attributes, &j); - if (status != PAPI_OK) { - ipp_set_status(response, status, "job modification: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c b/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c deleted file mode 100644 index 7d80864961..0000000000 --- a/usr/src/lib/print/libipp-listener/common/set-printer-attributes.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: set-printer-attributes.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_set_printer_attributes(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - papi_status_t status; - papi_printer_t p = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **printer_attributes = NULL; - - char *queue = NULL; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, PAPI_BAD_REQUEST, - "missing printer-uri or job-uri"); - return (PAPI_BAD_REQUEST); - } - - /* get the printer-attributes-group attributes for the PAPI call */ - papiAttributeListGetCollection(request, NULL, - "printer-attributes-group", &printer_attributes); - - /* request job modification */ - status = papiPrinterModify(svc, queue, printer_attributes, &p); - if (status != PAPI_OK) { - ipp_set_status(response, status, "printer modification: %s", - ipp_svc_status_mesg(svc, status)); - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (p != NULL) { - papi_to_ipp_printer_group(response, request, - PAPI_ATTR_REPLACE, p); - papiPrinterFree(p); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/common/validate-job.c b/usr/src/lib/print/libipp-listener/common/validate-job.c deleted file mode 100644 index 8ea72ee38b..0000000000 --- a/usr/src/lib/print/libipp-listener/common/validate-job.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: validate-job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <papi.h> -#include <ipp.h> -#include <ipp-listener.h> - -papi_status_t -ipp_validate_job(papi_service_t svc, papi_attribute_t **request, - papi_attribute_t ***response, ipp_reader_t iread, void *fd) -{ - papi_status_t status; - papi_job_t j = NULL; - papi_attribute_t **operational = NULL; - papi_attribute_t **job_attributes = NULL; - char *queue = NULL; - char *files[] = { "/etc/syslog.conf", NULL }; - ssize_t rc; - char buf[BUFSIZ]; - char *keys[] = { "attributes-natural-language", "attributes-charset", - "printer-uri", NULL }; - - /* Get operational attributes from the request */ - (void) papiAttributeListGetCollection(request, NULL, - "operational-attributes-group", &operational); - - /* - * The operational-attributes-group must contain: - * printer-uri - */ - get_printer_id(operational, &queue, NULL); - if (queue == NULL) { - ipp_set_status(response, status, "printer-uri: %s", - papiStatusString(status)); - return (PAPI_BAD_REQUEST); - } - - /* - * The operational-attributes-group may contain: - * job-name - * ipp-attribute-fidelity - * document-name - * compression - * document-format - * document-natural-language - * job-k-octets - * job-impressions - * job-media-sheets - * Simply copy the entire contents of the operational-attributes-group - * for the PAPI call's possible use. - */ - split_and_copy_attributes(keys, operational, NULL, &job_attributes); - - /* copy any job-attributes-group attributes for the PAPI call */ - if (papiAttributeListGetCollection(request, NULL, - "job-attributes-group", &operational) == PAPI_OK) - copy_attributes(&job_attributes, operational); - - /* request job validation */ - status = papiJobValidate(svc, queue, job_attributes, NULL, files, &j); - papiAttributeListFree(job_attributes); - - if (status != PAPI_OK) { - ipp_set_status(response, status, "validating job: %s", - ipp_svc_status_mesg(svc, status)); - papiJobFree(j); /* we shouldn't have a job, but just in case */ - return (status); - } - - /* add the job attributes to the response in a job-attributes-group */ - if (j != NULL) { - papi_to_ipp_job_group(response, request, PAPI_ATTR_REPLACE, j); - papiJobFree(j); - } - - return (status); -} diff --git a/usr/src/lib/print/libipp-listener/i386/Makefile b/usr/src/lib/print/libipp-listener/i386/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libipp-listener/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libipp-listener/sparc/Makefile b/usr/src/lib/print/libipp-listener/sparc/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libipp-listener/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-common/Makefile b/usr/src/lib/print/libpapi-common/Makefile deleted file mode 100644 index ef7e964b85..0000000000 --- a/usr/src/lib/print/libpapi-common/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -HDRS = papi.h -HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber: .WAIT $(SUBDIRS) -install: .WAIT $(SUBDIRS) install_h - -lint: # $(SUBDIRS) - -install_h: $(ROOTHDRS) - -check: $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-common/common/attribute.c b/usr/src/lib/print/libpapi-common/common/attribute.c deleted file mode 100644 index 244e54555d..0000000000 --- a/usr/src/lib/print/libpapi-common/common/attribute.c +++ /dev/null @@ -1,1119 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: attribute.c 157 2006-04-26 15:07:55Z ktou $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <ctype.h> -#include <alloca.h> -#include <papi.h> -#include <regex.h> - -#define MAX_PAGES 32767 -/* - * Assuming the maximum number of pages in - * a document to be 32767 - */ - -static void papiAttributeFree(papi_attribute_t *attribute); - -static void -papiAttributeValueFree(papi_attribute_value_type_t type, - papi_attribute_value_t *value) -{ - if (value != NULL) { - switch (type) { - case PAPI_STRING: - if (value->string != NULL) - free(value->string); - break; - case PAPI_COLLECTION: - if (value->collection != NULL) { - int i; - - for (i = 0; value->collection[i] != NULL; i++) - papiAttributeFree(value->collection[i]); - - free(value->collection); - } - break; - default: /* don't need to free anything extra */ - break; - } - - free(value); - } -} - -static void -papiAttributeValuesFree(papi_attribute_value_type_t type, - papi_attribute_value_t **values) -{ - if (values != NULL) { - int i; - - for (i = 0; values[i] != NULL; i++) - papiAttributeValueFree(type, values[i]); - - free(values); - } -} - -static void -papiAttributeFree(papi_attribute_t *attribute) -{ - if (attribute != NULL) { - if (attribute->name != NULL) - free(attribute->name); - if (attribute->values != NULL) - papiAttributeValuesFree(attribute->type, - attribute->values); - free(attribute); - } -} - -void -papiAttributeListFree(papi_attribute_t **list) -{ - if (list != NULL) { - int i; - - for (i = 0; list[i] != NULL; i++) - papiAttributeFree(list[i]); - - free(list); - } -} - -static papi_attribute_t ** -collection_dup(papi_attribute_t **collection) -{ - papi_attribute_t **result = NULL; - - /* allows a NULL collection that is "empty" or "no value" */ - if (collection != NULL) { - papi_status_t status = PAPI_OK; - int i; - - for (i = 0; ((collection[i] != NULL) && (status == PAPI_OK)); - i++) { - papi_attribute_t *a = collection[i]; - - status = papiAttributeListAddValue(&result, - PAPI_ATTR_APPEND, a->name, a->type, - NULL); - if ((status == PAPI_OK) && (a->values != NULL)) { - int j; - - for (j = 0; ((a->values[j] != NULL) && - (status == PAPI_OK)); j++) - status = papiAttributeListAddValue( - &result, - PAPI_ATTR_APPEND, - a->name, a->type, - a->values[j]); - } - } - if (status != PAPI_OK) { - papiAttributeListFree(result); - result = NULL; - } - } - - return (result); -} - -static papi_attribute_value_t * -papiAttributeValueDup(papi_attribute_value_type_t type, - papi_attribute_value_t *v) -{ - papi_attribute_value_t *result = NULL; - - if ((v != NULL) && ((result = calloc(1, sizeof (*result))) != NULL)) { - switch (type) { - case PAPI_STRING: - if (v->string == NULL) { - free(result); - result = NULL; - } else - result->string = strdup(v->string); - break; - case PAPI_INTEGER: - result->integer = v->integer; - break; - case PAPI_BOOLEAN: - result->boolean = v->boolean; - break; - case PAPI_RANGE: - result->range.lower = v->range.lower; - result->range.upper = v->range.upper; - break; - case PAPI_RESOLUTION: - result->resolution.xres = v->resolution.xres; - result->resolution.yres = v->resolution.yres; - result->resolution.units = v->resolution.units; - break; - case PAPI_DATETIME: - result->datetime = v->datetime; - break; - case PAPI_COLLECTION: - result->collection = collection_dup(v->collection); - break; - case PAPI_METADATA: - result->metadata = v->metadata; - break; - default: /* unknown type, fail to duplicate */ - free(result); - result = NULL; - } - } - - return (result); -} - -static papi_attribute_t * -papiAttributeAlloc(char *name, papi_attribute_value_type_t type) -{ - papi_attribute_t *result = NULL; - - if ((result = calloc(1, sizeof (*result))) != NULL) { - result->name = strdup(name); - result->type = type; - } - - return (result); -} - -static papi_status_t -papiAttributeListAppendValue(papi_attribute_value_t ***values, - papi_attribute_value_type_t type, - papi_attribute_value_t *value) -{ - - if (values == NULL) - return (PAPI_BAD_ARGUMENT); - - if (value != NULL) { /* this allows "empty" attributes */ - papi_attribute_value_t *tmp = NULL; - - if ((tmp = papiAttributeValueDup(type, value)) == NULL) - return (PAPI_TEMPORARY_ERROR); - - list_append(values, tmp); - } - - return (PAPI_OK); -} - -papi_status_t -papiAttributeListAddValue(papi_attribute_t ***list, int flgs, - char *name, papi_attribute_value_type_t type, - papi_attribute_value_t *value) -{ - papi_status_t result; - int flags = flgs; - papi_attribute_t *attribute = NULL; - papi_attribute_value_t **values = NULL; - - if ((list == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((type == PAPI_RANGE) && (value != NULL) && - (value->range.lower > value->range.upper)) - return (PAPI_BAD_ARGUMENT); /* RANGE must have min <= max */ - - if (flags == 0) /* if it wasn't set, set a default behaviour */ - flags = PAPI_ATTR_APPEND; - - /* look for an existing one */ - attribute = papiAttributeListFind(*list, name); - - if (((flags & PAPI_ATTR_EXCL) != 0) && (attribute != NULL)) - return (PAPI_CONFLICT); /* EXISTS */ - - if (((flags & PAPI_ATTR_REPLACE) == 0) && (attribute != NULL) && - (attribute->type != type)) - return (PAPI_CONFLICT); /* TYPE CONFLICT */ - - /* if we don't have one, create it and add it to the list */ - if ((attribute == NULL) && - ((attribute = papiAttributeAlloc(name, type)) != NULL)) - list_append(list, attribute); - - /* if we don't have one by now, it's most likely an alloc fail */ - if (attribute == NULL) - return (PAPI_TEMPORARY_ERROR); - - /* - * if we are replacing, clear any existing values, but don't free - * until after we have replaced the values, in case we are replacing - * a collection with a relocated version of the original collection. - */ - if (((flags & PAPI_ATTR_REPLACE) != 0) && (attribute->values != NULL)) { - values = attribute->values; - attribute->values = NULL; - } - - attribute->type = type; - - result = papiAttributeListAppendValue(&attribute->values, type, value); - - /* free old values if we replaced them */ - if (values != NULL) - papiAttributeValuesFree(type, values); - - return (result); -} - -papi_status_t -papiAttributeListAddString(papi_attribute_t ***list, int flags, - char *name, char *string) -{ - papi_attribute_value_t v; - - v.string = (char *)string; - return (papiAttributeListAddValue(list, flags, name, PAPI_STRING, &v)); -} - -papi_status_t -papiAttributeListAddInteger(papi_attribute_t ***list, int flags, - char *name, int integer) -{ - papi_attribute_value_t v; - - v.integer = integer; - return (papiAttributeListAddValue(list, flags, name, PAPI_INTEGER, &v)); -} - -papi_status_t -papiAttributeListAddBoolean(papi_attribute_t ***list, int flags, - char *name, char boolean) -{ - papi_attribute_value_t v; - - v.boolean = boolean; - return (papiAttributeListAddValue(list, flags, name, PAPI_BOOLEAN, &v)); -} - -papi_status_t -papiAttributeListAddRange(papi_attribute_t ***list, int flags, - char *name, int lower, int upper) -{ - papi_attribute_value_t v; - - v.range.lower = lower; - v.range.upper = upper; - return (papiAttributeListAddValue(list, flags, name, PAPI_RANGE, &v)); -} - -papi_status_t -papiAttributeListAddResolution(papi_attribute_t ***list, int flags, - char *name, int xres, int yres, - papi_resolution_unit_t units) -{ - papi_attribute_value_t v; - - v.resolution.xres = xres; - v.resolution.yres = yres; - v.resolution.units = units; - return (papiAttributeListAddValue(list, flags, name, - PAPI_RESOLUTION, &v)); -} - -papi_status_t -papiAttributeListAddDatetime(papi_attribute_t ***list, int flags, - char *name, time_t datetime) -{ - papi_attribute_value_t v; - - v.datetime = datetime; - return (papiAttributeListAddValue(list, flags, name, - PAPI_DATETIME, &v)); -} - -papi_status_t -papiAttributeListAddCollection(papi_attribute_t ***list, int flags, - char *name, papi_attribute_t **collection) -{ - papi_attribute_value_t v; - - v.collection = (papi_attribute_t **)collection; - return (papiAttributeListAddValue(list, flags, name, - PAPI_COLLECTION, &v)); -} - -papi_status_t -papiAttributeListAddMetadata(papi_attribute_t ***list, int flags, - char *name, papi_metadata_t metadata) -{ - papi_attribute_value_t v; - - v.metadata = metadata; - return (papiAttributeListAddValue(list, flags, name, - PAPI_METADATA, &v)); -} - -papi_status_t -papiAttributeListDelete(papi_attribute_t ***list, char *name) -{ - papi_attribute_t *attribute; - - if ((list == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((attribute = papiAttributeListFind(*list, name)) == NULL) - return (PAPI_NOT_FOUND); - - list_remove(list, attribute); - papiAttributeFree(attribute); - - return (PAPI_OK); -} - -papi_attribute_t * -papiAttributeListFind(papi_attribute_t **list, char *name) -{ - int i; - if ((list == NULL) || (name == NULL)) - return (NULL); - - for (i = 0; list[i] != NULL; i++) - if (strcasecmp(list[i]->name, name) == 0) - return ((papi_attribute_t *)list[i]); - - return (NULL); -} - -papi_attribute_t * -papiAttributeListGetNext(papi_attribute_t **list, void **iter) -{ - papi_attribute_t **tmp, *result; - - if ((list == NULL) && (iter == NULL)) - return (NULL); - - if (*iter == NULL) - *iter = list; - - tmp = *iter; - result = *tmp; - *iter = ++tmp; - - return (result); -} - -papi_status_t -papiAttributeListGetValue(papi_attribute_t **list, void **iter, - char *name, papi_attribute_value_type_t type, - papi_attribute_value_t **value) -{ - papi_attribute_value_t **tmp; - void *fodder = NULL; - - if ((list == NULL) || ((name == NULL) && (iter == NULL)) || - (value == NULL)) - return (PAPI_BAD_ARGUMENT); - - if (iter == NULL) - iter = &fodder; - - if ((iter == NULL) || (*iter == NULL)) { - papi_attribute_t *attr = papiAttributeListFind(list, name); - - if (attr == NULL) - return (PAPI_NOT_FOUND); - - if (attr->type != type) - return (PAPI_NOT_POSSIBLE); - - tmp = attr->values; - } else - tmp = *iter; - - if (tmp == NULL) - return (PAPI_NOT_FOUND); - - *value = *tmp; - *iter = ++tmp; - - if (*value == NULL) - return (PAPI_GONE); - - return (PAPI_OK); -} - -papi_status_t -papiAttributeListGetString(papi_attribute_t **list, void **iter, - char *name, char **vptr) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (vptr == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_STRING, &value); - if (status == PAPI_OK) - *vptr = value->string; - - return (status); -} - -papi_status_t -papiAttributeListGetInteger(papi_attribute_t **list, void **iter, - char *name, int *vptr) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (vptr == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_INTEGER, &value); - if (status == PAPI_OK) - *vptr = value->integer; - - return (status); -} - -papi_status_t -papiAttributeListGetBoolean(papi_attribute_t **list, void **iter, - char *name, char *vptr) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (vptr == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_BOOLEAN, &value); - if (status == PAPI_OK) - *vptr = value->boolean; - - return (status); -} - -papi_status_t -papiAttributeListGetRange(papi_attribute_t **list, void **iter, - char *name, int *min, int *max) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if ((min == NULL) || (max == NULL)) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_RANGE, &value); - if (status == PAPI_OK) { - *min = value->range.lower; - *max = value->range.upper; - } - - return (status); -} - -papi_status_t -papiAttributeListGetResolution(papi_attribute_t **list, void **iter, - char *name, int *x, int *y, - papi_resolution_unit_t *units) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if ((x == NULL) || (y == NULL) || (units == NULL)) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_RESOLUTION, &value); - if (status == PAPI_OK) { - *x = value->resolution.xres; - *y = value->resolution.yres; - *units = value->resolution.units; - } - - return (status); -} - -papi_status_t -papiAttributeListGetDatetime(papi_attribute_t **list, void **iter, - char *name, time_t *dt) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (dt == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_DATETIME, &value); - if (status == PAPI_OK) { - *dt = value->datetime; - } - - return (status); -} - -papi_status_t -papiAttributeListGetCollection(papi_attribute_t **list, void **iter, - char *name, papi_attribute_t ***collection) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (collection == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_COLLECTION, &value); - if (status == PAPI_OK) { - *collection = value->collection; - } - - return (status); -} - -papi_status_t -papiAttributeListGetMetadata(papi_attribute_t **list, void **iter, - char *name, papi_metadata_t *vptr) -{ - papi_status_t status; - papi_attribute_value_t *value = NULL; - - if (vptr == NULL) - return (PAPI_BAD_ARGUMENT); - - status = papiAttributeListGetValue(list, iter, name, - PAPI_METADATA, &value); - if (status == PAPI_OK) - *vptr = value->metadata; - - return (status); -} - - -/* The string is modified by this call */ -static char * -regvalue(regmatch_t match, char *string) -{ - char *result = NULL; - if (match.rm_so != match.rm_eo) { - result = string + match.rm_so; - *(result + (match.rm_eo - match.rm_so)) = '\0'; - } - return (result); -} - -static papi_attribute_value_type_t -_process_value(char *string, char ***parts) -{ - int i; - static struct { - papi_attribute_value_type_t type; - size_t vals; - char *expression; - int compiled; - regex_t re; - } types[] = { - { PAPI_BOOLEAN, 1, "^(true|false|yes|no)$", 0 }, - { PAPI_COLLECTION, 1, "^\\{(.+)\\}$", 0 }, - /* PAPI_DATETIME is unsupported, too much like an integer */ - { PAPI_INTEGER, 1, "^([+-]{0,1}[[:digit:]]+)$", 0 }, - { PAPI_RANGE, 3, "^([[:digit:]]*)-([[:digit:]]*)$", 0 }, - { PAPI_RESOLUTION, 4, "^([[:digit:]]+)x([[:digit:]]+)dp(i|c)$", - 0 }, - NULL - }; - regmatch_t matches[4]; - - for (i = 0; i < 5; i++) { - int j; - - if (types[i].compiled == 0) { - (void) regcomp(&(types[i].re), types[i].expression, - REG_EXTENDED|REG_ICASE); - types[i].compiled = 1; - } - if (regexec(&(types[i].re), string, (size_t)types[i].vals, - matches, 0) == REG_NOMATCH) - continue; - - for (j = 0 ; j < types[i].vals; j++) - list_append(parts, regvalue(matches[j], string)); - return (types[i].type); - } - - list_append(parts, string); - return (PAPI_STRING); -} - -static void -_add_attribute_value(papi_attribute_value_t ***list, - papi_attribute_value_type_t type, - papi_attribute_value_type_t dtype, char **parts) -{ - papi_attribute_value_t *value = calloc(1, sizeof (*value)); - - switch(type) { - case PAPI_STRING: - value->string = strdup(parts[0]); - list_append(list, value); - break; - case PAPI_BOOLEAN: - value->boolean = PAPI_TRUE; - if ((strcasecmp(parts[0], "false") == 0) || - (strcasecmp(parts[0], "no") == 0)) - value->boolean = PAPI_FALSE; - list_append(list, value); - break; - case PAPI_INTEGER: - value->integer = atoi(parts[0]); - list_append(list, value); - break; - case PAPI_RANGE: - if (dtype == PAPI_INTEGER) { - if (atoi(parts[0]) < 0) { - /* - * Handles -P -x case - * which prints from page number 1 - * till page number x - */ - value->range.lower = 1; - value->range.upper = 0 - (atoi(parts[0])); - } else { - value->range.lower = value->range.upper - = atoi(parts[0]); - } - } else if (dtype == PAPI_RANGE) { - if (parts[2] == NULL) { - value->range.lower = atoi(parts[1]); - /* - * Imposing an artificial limit on - * the upper bound for page range. - */ - value->range.upper = MAX_PAGES; - } else if ((parts[1] != NULL) && (parts[2] != NULL)) { - value->range.lower = atoi(parts[1]); - value->range.upper = atoi(parts[2]); - } - } - list_append(list, value); - break; - case PAPI_RESOLUTION: - value->resolution.xres = atoi(parts[1]); - value->resolution.yres = atoi(parts[2]); - if (parts[3][0] == 'i') - value->resolution.units = PAPI_RES_PER_INCH; - else - value->resolution.units = PAPI_RES_PER_CM; - list_append(list, value); - break; - case PAPI_COLLECTION: - papiAttributeListFromString(&(value->collection), 0, parts[0]); - list_append(list, value); - break; - } -} - -static papi_status_t -_papiAttributeFromStrings(papi_attribute_t ***list, int flags, - char *key, char **values) -{ - int i; - papi_status_t result = PAPI_OK; - papi_attribute_t *attr = calloc(1, sizeof (*attr)); - - /* these are specified in the papi spec as ranges */ - char *ranges[] = { "copies-supported", "job-impressions-supported", - "job-k-octets-supported", - "job-media-sheets-supported", "page-ranges", - NULL }; - - if ((attr == NULL) || ((attr->name = strdup(key)) == NULL)) - return (PAPI_TEMPORARY_ERROR); - - attr->type = PAPI_METADATA; - /* these are known ranges */ - for (i = 0; ranges[i] != NULL; i++) - if (strcasecmp(attr->name, ranges[i]) == 0) { - attr->type = PAPI_RANGE; - break; - } - - if (values != NULL) { - papi_attribute_value_t **vals = NULL; - - for (i = 0; values[i] != NULL; i++) { - papi_attribute_value_type_t dtype; - char **parts = NULL; - - dtype = _process_value(values[i], &parts); - if (attr->type == PAPI_METADATA) - attr->type = dtype; - _add_attribute_value(&vals, attr->type, dtype, parts); - free(parts); - } - attr->values = vals; - } - - list_append(list, attr); - - return (result); -} - -static papi_status_t -_parse_attribute_list(papi_attribute_t ***list, int flags, char *string) -{ - papi_status_t result = PAPI_OK; - char *ptr; - - if ((list == NULL) || (string == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((ptr = strdup(string)) == NULL) - return (PAPI_TEMPORARY_ERROR); - - while ((*ptr != '\0') && (result == PAPI_OK)) { - char *key, **values = NULL; - - /* strip any leading whitespace */ - while (isspace(*ptr) != 0) - ptr++; - - /* Get the name: name[=value] */ - key = ptr; - while ((*ptr != '\0') && (*ptr != '=') && (isspace(*ptr) == 0)) - ptr++; - - if (*ptr == '=') { - *ptr++ = '\0'; - - while ((*ptr != '\0') && (isspace(*ptr) == 0)) { - char *value = ptr; - - if ((*ptr == '\'') || (*ptr == '"')) { - char q = *ptr++; - - /* quoted string value */ - while ((*ptr != '\0') && (*ptr != q)) - ptr++; - if (*ptr == q) - ptr++; - } else if (*ptr == '{') { - /* collection */ - while ((*ptr != '\0') && (*ptr != '}')) - ptr++; - if (*ptr == '}') - ptr++; - } else { - /* value */ - while ((*ptr != '\0') && - (*ptr != ',') && - (isspace(*ptr) == 0)) - ptr++; - } - if (*ptr == ',') - *ptr++ = '\0'; - list_append(&values, value); - } - } else { /* boolean "[no]key" */ - char *value = "true"; - - if (strncasecmp(key, "no", 2) == 0) { - key += 2; - value = "false"; - } - list_append(&values, value); - } - if (*ptr != '\0') - *ptr++ = '\0'; - - result = _papiAttributeFromStrings(list, flags, key, values); - free(values); - } - - return (result); -} - -papi_status_t -papiAttributeListFromString(papi_attribute_t ***attrs, - int flags, char *string) -{ - papi_status_t result = PAPI_OK; - - if ((attrs != NULL) && (string != NULL) && - ((flags & ~(PAPI_ATTR_APPEND+PAPI_ATTR_REPLACE+PAPI_ATTR_EXCL)) - == 0)) { - result = _parse_attribute_list(attrs, flags, string); - } else { - result = PAPI_BAD_ARGUMENT; - } - - return (result); -} - -static papi_status_t -papiAttributeToString(papi_attribute_t *attribute, char *delim, - char *buffer, size_t buflen) -{ - papi_attribute_value_t **values = attribute->values; - int rc, i; - - if ((attribute->type == PAPI_BOOLEAN) && (values[1] == NULL)) { - if (values[0]->boolean == PAPI_FALSE) { - if (isupper(attribute->name[0]) == 0) - strlcat(buffer, "no", buflen); - else - strlcat(buffer, "No", buflen); - } - rc = strlcat(buffer, attribute->name, buflen); - } else { - strlcat(buffer, attribute->name, buflen); - rc = strlcat(buffer, "=", buflen); - } - - if (values == NULL) - return (PAPI_OK); - - for (i = 0; values[i] != NULL; i++) { - switch (attribute->type) { - case PAPI_STRING: - rc = strlcat(buffer, values[i]->string, buflen); - break; - case PAPI_INTEGER: { - char string[24]; - - snprintf(string, sizeof (string), "%d", - values[i]->integer); - rc = strlcat(buffer, string, buflen); - } - break; - case PAPI_BOOLEAN: - if (values[1] != NULL) - rc = strlcat(buffer, (values[i]->boolean ? - "true" : "false"), buflen); - break; - case PAPI_RANGE: { - char string[24]; - - if (values[i]->range.lower == values[i]->range.upper) - snprintf(string, sizeof (string), "%d", - values[i]->range.lower); - else - snprintf(string, sizeof (string), "%d-%d", - values[i]->range.lower, - values[i]->range.upper); - rc = strlcat(buffer, string, buflen); - } - break; - case PAPI_RESOLUTION: { - char string[24]; - - snprintf(string, sizeof (string), "%dx%ddp%c", - values[i]->resolution.xres, - values[i]->resolution.yres, - (values[i]->resolution.units == PAPI_RES_PER_CM - ? 'c' : 'i')); - rc = strlcat(buffer, string, buflen); - } - break; - case PAPI_DATETIME: { - struct tm *tm = localtime(&values[i]->datetime); - - if (tm != NULL) { - char string[64]; - - strftime(string, sizeof (string), "%C", tm); - rc = strlcat(buffer, string, buflen); - }} - break; - case PAPI_COLLECTION: { - char *string = alloca(buflen); - - papiAttributeListToString(values[i]->collection, - delim, string, buflen); - rc = strlcat(buffer, string, buflen); - } - break; - default: { - char string[32]; - - snprintf(string, sizeof (string), "unknown-type-0x%x", - attribute->type); - rc = strlcat(buffer, string, buflen); - } - } - if (values[i+1] != NULL) - rc = strlcat(buffer, ",", buflen); - - if (rc >= buflen) - return (PAPI_NOT_POSSIBLE); - - } - - return (PAPI_OK); -} - -papi_status_t -papiAttributeListToString(papi_attribute_t **attrs, - char *delim, char *buffer, size_t buflen) -{ - papi_status_t status = PAPI_OK; - int i; - - if ((attrs == NULL) || (buffer == NULL)) - return (PAPI_BAD_ARGUMENT); - - buffer[0] = '\0'; - if (!delim) - delim = " "; - - for (i = 0; ((attrs[i] != NULL) && (status == PAPI_OK)); i++) { - status = papiAttributeToString(attrs[i], delim, buffer, buflen); - if (attrs[i+1] != NULL) - strlcat(buffer, delim, buflen); - } - - return (status); -} - -static int -is_in_list(char *value, char **list) -{ - if ((list != NULL) && (value != NULL)) { - int i; - - for (i = 0; list[i] != NULL; i++) - if (strcasecmp(value, list[i]) == 0) - return (0); - } - - return (1); -} - -static papi_status_t -copy_attribute(papi_attribute_t ***list, papi_attribute_t *attribute) -{ - papi_status_t status; - int i = 0; - - if ((list == NULL) || (attribute == NULL) || - (attribute->values == NULL)) - return (PAPI_BAD_ARGUMENT); - - for (status = papiAttributeListAddValue(list, PAPI_ATTR_EXCL, - attribute->name, attribute->type, - attribute->values[i]); - ((status == PAPI_OK) && (attribute->values[i] != NULL)); - status = papiAttributeListAddValue(list, PAPI_ATTR_APPEND, - attribute->name, attribute->type, - attribute->values[i])) - i++; - - return (status); -} - -void -copy_attributes(papi_attribute_t ***result, papi_attribute_t **attributes) -{ - int i; - - if ((result == NULL) || (attributes == NULL)) - return; - - for (i = 0; attributes[i] != NULL; i++) - copy_attribute(result, attributes[i]); -} - -void -split_and_copy_attributes(char **list, papi_attribute_t **attributes, - papi_attribute_t ***in, papi_attribute_t ***out) -{ - int i; - - if ((list == NULL) || (attributes == NULL)) - return; - - for (i = 0; attributes[i] != NULL; i++) - if (is_in_list(attributes[i]->name, list) == 0) - copy_attribute(in, attributes[i]); - else - copy_attribute(out, attributes[i]); -} - -void -papiAttributeListPrint(FILE *fp, papi_attribute_t **attributes, - char *prefix_fmt, ...) -{ - char *prefix = NULL; - char *buffer = NULL; - char *newfmt = NULL; - void *mem; - ssize_t size = 0; - va_list ap; - - newfmt = malloc(strlen(prefix_fmt) + 2); - sprintf(newfmt, "\n%s", prefix_fmt); - - va_start(ap, prefix_fmt); - while (vsnprintf(prefix, size, newfmt, ap) > size) { - size += 1024; - mem = realloc(prefix, size); - if (!mem) goto error; - prefix = mem; - } - va_end(ap); - - if (attributes) { - size = 0; - while (papiAttributeListToString(attributes, prefix, buffer, - size) != PAPI_OK) { - size += 1024; - mem = realloc(buffer, size); - if (!mem) goto error; - buffer = mem; - } - } - - fprintf(fp, "%s%s\n", prefix, buffer ? buffer : ""); - fflush(fp); - - error: - free(newfmt); - free(prefix); - free(buffer); -} diff --git a/usr/src/lib/print/libpapi-common/common/common.c b/usr/src/lib/print/libpapi-common/common/common.c deleted file mode 100644 index c14515417b..0000000000 --- a/usr/src/lib/print/libpapi-common/common/common.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: common.c 151 2006-04-25 16:55:34Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Shared "unsupported" function implementations that can be overridden - * by libpapi and the various print service modules (psms). - */ - -#include <stdlib.h> -#include <papi.h> - -static papi_status_t -_unsupported() -{ - return (PAPI_OPERATION_NOT_SUPPORTED); -} - -static void * -_unsupported_null_return() -{ - return (NULL); -} - -static void -_unsupported_no_return() -{ -} - -/* - * Service interfaces - */ -#pragma weak papiServiceCreate = _unsupported -#pragma weak papiServiceDestroy = _unsupported_no_return -#pragma weak papiServiceSetPeer = _unsupported -#pragma weak papiServiceSetUserName = _unsupported -#pragma weak papiServiceSetPassword = _unsupported -#pragma weak papiServiceSetEncryption = _unsupported -#pragma weak papiServiceSetAuthCB = _unsupported -#pragma weak papiServiceSetAppData = _unsupported - -#pragma weak papiServiceGetServiceName = _unsupported_null_return -#pragma weak papiServiceGetUserName = _unsupported_null_return -#pragma weak papiServiceGetPassword = _unsupported_null_return -#pragma weak papiServiceGetAppData = _unsupported_null_return - -papi_encryption_t -papiServiceGetEncryption(papi_service_t handle) -{ - return (PAPI_ENCRYPT_NEVER); -} - -#pragma weak papiServiceGetAttributeList = _unsupported_null_return -#pragma weak papiServiceGetStatusMessage = _unsupported_null_return - -/* - * Printer operations - */ -#pragma weak papiPrintersList = _unsupported -#pragma weak papiPrinterQuery = _unsupported -#pragma weak papiPrinterEnable = _unsupported -#pragma weak papiPrinterDisable = _unsupported -#pragma weak papiPrinterPause = _unsupported -#pragma weak papiPrinterResume = _unsupported -#pragma weak papiPrinterAdd = _unsupported -#pragma weak papiPrinterModify = _unsupported -#pragma weak papiPrinterRemove = _unsupported -#pragma weak papiPrinterPurgeJobs = _unsupported -#pragma weak papiPrinterListJobs = _unsupported -#pragma weak papiPrinterGetAttributeList = _unsupported_null_return -#pragma weak papiPrinterFree = _unsupported_no_return -#pragma weak papiPrinterListFree = _unsupported_no_return - -/* - * Job interfaces - */ -#pragma weak papiJobHold = _unsupported -#pragma weak papiJobRelease = _unsupported -#pragma weak papiJobRestart = _unsupported -#pragma weak papiJobPromote = _unsupported -#pragma weak papiJobModify = _unsupported -#pragma weak papiJobSubmit = _unsupported -#pragma weak papiJobSubmitByReference = _unsupported -#pragma weak papiJobValidate = _unsupported -#pragma weak papiJobStreamOpen = _unsupported -#pragma weak papiJobStreamWrite = _unsupported -#pragma weak papiJobStreamClose = _unsupported -#pragma weak papiJobQuery = _unsupported -#pragma weak papiJobMove = _unsupported -#pragma weak papiJobCancel = _unsupported -#pragma weak papiJobGetAttributeList = _unsupported_null_return -#pragma weak papiJobGetPrinterName = _unsupported_null_return -#pragma weak papiJobCreate = _unsupported -#pragma weak papiJobStreamAdd = _unsupported -#pragma weak papiJobCommit = _unsupported - -int -papiJobGetId(papi_job_t job) -{ - return (-1); -} - -#pragma weak papiJobGetJobTicket = _unsupported_null_return -#pragma weak papiJobFree = _unsupported_no_return -#pragma weak papiJobListFree = _unsupported_no_return - -/* private functions */ -#pragma weak getprinterbyname = _unsupported_null_return diff --git a/usr/src/lib/print/libpapi-common/common/config-site.h b/usr/src/lib/print/libpapi-common/common/config-site.h deleted file mode 100644 index 2007f4f669..0000000000 --- a/usr/src/lib/print/libpapi-common/common/config-site.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _CONFIG_SITE_H -#define _CONFIG_SITE_H - -/* $Id: config-site.h.in 171 2006-05-20 06:00:32Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <config.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* the "default" destination for various commands and libraries */ -#define DEFAULT_DEST "_default" - -/* the "default" server uri to fallback to */ -#define DEFAULT_SERVICE_URI "lpsched://localhost/printers" - -/* the "default" IPP service to fallback to in the IPP psm */ -#define DEFAULT_IPP_SERVICE_URI "ipp://localhost/printers" - -/* the name of the SUID lpd-port binary that hands psm-lpd a connected socket */ -#define SUID_LPD_PORT "/usr/lib/print/lpd-port" - -/* enable/disable printer-uri in enumeration results */ -#define NEED_BROKEN_PRINTER_URI_SEMANTIC - -#ifdef __cplusplus -} -#endif - -#endif /* _CONFIG_SITE_H */ diff --git a/usr/src/lib/print/libpapi-common/common/config.h b/usr/src/lib/print/libpapi-common/common/config.h deleted file mode 100644 index 280ac6d6b4..0000000000 --- a/usr/src/lib/print/libpapi-common/common/config.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _CONFIG_H -#define _CONFIG_H - -/* source/libpapi-common/config.h. Generated by configure. */ -/* source/libpapi-common/config.h.in. Generated from configure.in by autoheader. */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the `dlopen' function. */ -#define HAVE_DLOPEN 1 - -/* Define to 1 if you have the `dlsym' function. */ -#define HAVE_DLSYM 1 - -/* Define to 1 if you have the `fprintf' function. */ -#define HAVE_FPRINTF 1 - -/* define if you have getipnodbyname */ -#define HAVE_GETIPNODEBYNAME 1 - -/* Define to 1 if you have the `getpassphrase' function. */ -#define HAVE_GETPASSPHRASE 1 - -/* Define to 1 if you have the `gettext' function. */ -#define HAVE_GETTEXT 1 - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `is_system_labeled' function. */ -#define HAVE_IS_SYSTEM_LABELED 1 - -/* Define to 1 if you have the `localtime' function. */ -#define HAVE_LOCALTIME 1 - -/* Define to 1 if you have the <memory.h> header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the <priv.h> header file. */ -#define HAVE_PRIV_H 1 - -/* define if you have rresvport_af */ -#define HAVE_RRESVPORT_AF 1 - -/* Define to 1 if you have the <ruby.h> header file. */ -/* #undef HAVE_RUBY_H */ - -/* Define to 1 if you have the `snprintf' function. */ -#define HAVE_SNPRINTF 1 - -/* Define to 1 if you have the <stdarg.h> header file. */ -#define HAVE_STDARG_H 1 - -/* Define to 1 if you have the <stdint.h> header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `strcmp' function. */ -#define HAVE_STRCMP 1 - -/* Define to 1 if you have the `strdup' function. */ -#define HAVE_STRDUP 1 - -/* Define to 1 if you have the `strerror' function. */ -#define HAVE_STRERROR 1 - -/* Define to 1 if you have the `strftime' function. */ -#define HAVE_STRFTIME 1 - -/* Define to 1 if you have the <strings.h> header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the <string.h> header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcat' function. */ -#define HAVE_STRLCAT 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define HAVE_STRLCPY 1 - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the <unistd.h> header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "papi" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.0_rc1" - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - - -#ifdef __cplusplus -} -#endif - -#endif /* _CONFIG_H */ diff --git a/usr/src/lib/print/libpapi-common/common/library.c b/usr/src/lib/print/libpapi-common/common/library.c deleted file mode 100644 index 12b1ffb449..0000000000 --- a/usr/src/lib/print/libpapi-common/common/library.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <alloca.h> -#include <libintl.h> -#include <papi.h> - -static char *calls[] = { - /* Attribute Calls */ - "papiAttributeListAddValue", - "papiAttributeListAddBoolean", "papiAttributeListAddCollection", - "papiAttributeListAddDatetime", "papiAttributeListAddInteger", - "papiAttributeListAddMetadata", "papiAttributeListAddRange", - "papiAttributeListAddResolution", "papiAttributeListAddString", - "papiAttributeListDelete", - "papiAttributeListGetValue", "papiAttributeListGetNext", - "papiAttributeListFind", - "papiAttributeListGetBoolean", "papiAttributeListGetCollection", - "papiAttributeListGetDatetime", "papiAttributeListGetInteger", - "papiAttributeListGetMetadata", "papiAttributeListGetRange", - "papiAttributeListGetResolution", "papiAttributeListGetString", - "papiAttributeListFromString", "papiAttributeListToString", - "papiAttributeListFree", - /* Job Calls */ - "papiJobSubmit", "papiJobSubmitByReference", "papiJobValidate", - "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose", - "papiJobQuery", "papiJobModify", "papiJobCancel", "papiJobPromote", - "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName", - "papiJobGetJobTicket", - "papiJobFree", "papiJobListFree", - "papiJobHold", "papiJobRelease", "papiJobRestart", - /* Printer Calls */ - "papiPrintersList", "papiPrinterQuery", "papiPrinterModify", - "papiPrinterAdd", "papiPrinterRemove", - "papiPrinterPause", "papiPrinterResume", - "papiPrinterDisable", "papiPrinterEnable", - "papiPrinterPurgeJobs", "papiPrinterListJobs", - "papiPrinterGetAttributeList", - "papiPrinterFree", "papiPrinterListFree", - /* Service Calls */ - "papiServiceCreate", "papiServiceDestroy", - "papiServiceGetAppData", - "papiServiceGetEncryption", "papiServiceGetPassword", - "papiServiceGetServiceName", "papiServiceGetUserName", - "papiServiceSetAppData", "papiServiceSetAuthCB", - "papiServiceSetEncryption", "papiServiceSetPassword", - "papiServiceSetUserName", - "papiServiceGetAttributeList", "papiServiceGetStatusMessage", - /* Misc Calls */ - "papiStatusString", - "papiLibrarySupportedCall", "papiLibrarySupportedCalls", - NULL -}; - -char ** -papiLibrarySupportedCalls() -{ - return (calls); -} - -char -papiLibrarySupportedCall(const char *name) -{ - int i; - - for (i = 0; calls[i] != NULL; i++) - if (strcmp(name, calls[i]) == 0) - return (PAPI_TRUE); - - return (PAPI_FALSE); -} diff --git a/usr/src/lib/print/libpapi-common/common/list.c b/usr/src/lib/print/libpapi-common/common/list.c deleted file mode 100644 index b2560c5059..0000000000 --- a/usr/src/lib/print/libpapi-common/common/list.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: list.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <stdarg.h> -#include <errno.h> - -static int __list_increment = 16; - -#define LIST_SIZE(x) ((((x) / __list_increment) + 1) * __list_increment) - -int -list_append(void ***list, void *item) -{ - int count; - - if ((list == NULL) || (item == NULL)) { - errno = EINVAL; - return (-1); - } - - if (item != NULL) { - if (*list == NULL) - *list = (void **)calloc(__list_increment, - sizeof (void *)); - - for (count = 0; (*list)[count] != NULL; count++) - ; - - if ((count + 1) % __list_increment == 0) { /* expand the list */ - void **new_list = NULL; - int new_size = LIST_SIZE(count + 1); - - new_list = (void **)calloc(new_size, sizeof (void *)); - if (new_list == NULL) - return (-1); - - for (count = 0; (*list)[count] != NULL; count++) - new_list[count] = (*list)[count]; - free(*list); - *list = new_list; - } - - (*list)[count] = item; - } - - return (0); -} - -/* - * list_concatenate() takes in two NULL terminated lists of items (type **) - * and creates a new list with items from list2 appended on the end of - * the list of items from list1. The result is a list (type **). If - * there is a failure, -1 is returned. - */ -int -list_concatenate(void ***result, void **list2) -{ - void **list1; - int size1 = 0; - int size2 = 0; - int new_size = 0; - - if ((result == NULL) || ((*result == NULL) && (list2 == NULL))) { - errno = EINVAL; - return (-1); - } - - list1 = *result; - - if (list1 != NULL) - for (size1 = 0; list1[size1] != NULL; size1++) - ; - if (list2 != NULL) - for (size2 = 0; list2[size2] != NULL; size2++) - ; - - /* list1 + list2 padded to a multiple of _list_increment */ - new_size = LIST_SIZE(size1 + size2); - - if ((*result = (void **)calloc((new_size), sizeof (void *))) != NULL) { - int count = 0; - - if (list1 != NULL) - for (size1 = 0; list1[size1] != NULL; size1++) - (*result)[count++] = list1[size1]; - if (list2 != NULL) - for (size2 = 0; list2[size2] != NULL; size2++) - (*result)[count++] = list2[size2]; - free(list1); - } - - return (0); -} - -/* - * list_locate() iterates through the list passed in and uses the comparison - * routine and element passed in to find an element in the list. It - * returns the first element matched, or NULL if none exists - */ -void * -list_locate(void **list, int (*compare)(void *, void *), void *element) -{ - int current = 0; - - if ((list != NULL) && (element != NULL)) - for (current = 0; list[current] != NULL; current++) - if ((compare)(list[current], element) == 0) - return (list[current]); - return (NULL); -} - -void -list_remove(void ***list, void *item) -{ - int i = 0, count; - - if ((list == NULL) || (*list == NULL) || (item == NULL)) - return; - - /* size the original list */ - for (count = 0; (*list)[count] != NULL; count++) - if ((*list)[count] == item) { /* mark the location of item */ - i = count; - item = NULL; - } - - /* if found, remove it */ - if (item == NULL) { - /* shift the list over the item */ - for (++i; ((*list)[i] != NULL); i++) - (*list)[i-1] = (*list)[i]; - (*list)[i-1] = NULL; - } - - /* if found, removed, and list should shrink, shrink it */ - if ((item == NULL) && (LIST_SIZE(i) < LIST_SIZE(count))) { - void **tmp = (void **)calloc(LIST_SIZE(i), sizeof (void *)); - - if (tmp != NULL) { - for (i = 0; (*list)[i] != NULL; i++) - tmp[i] = (*list)[i]; - free(*list); - *list = tmp; - } - } -} diff --git a/usr/src/lib/print/libpapi-common/common/mapfile b/usr/src/lib/print/libpapi-common/common/mapfile deleted file mode 100644 index c1f9e3f1ab..0000000000 --- a/usr/src/lib/print/libpapi-common/common/mapfile +++ /dev/null @@ -1,168 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ -# - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -# -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. -# - -SYMBOL_VERSION SUNW_1.0 { - global: - # PAPI Attribute Calls - papiAttributeListAddValue; - papiAttributeListAddBoolean; - papiAttributeListAddCollection; - papiAttributeListAddDatetime; - papiAttributeListAddInteger; - papiAttributeListAddMetadata; - papiAttributeListAddRange; - papiAttributeListAddResolution; - papiAttributeListAddString; - papiAttributeListDelete; - papiAttributeListGetValue; - papiAttributeListGetNext; - papiAttributeListFind; - papiAttributeListGetBoolean; - papiAttributeListGetCollection; - papiAttributeListGetDatetime; - papiAttributeListGetInteger; - papiAttributeListGetMetadata; - papiAttributeListGetRange; - papiAttributeListGetResolution; - papiAttributeListGetString; - papiAttributeListFromString; - papiAttributeListToString; - papiAttributeListFree; - - # PAPI Service Calls - papiServiceCreate { FLAGS = NODYNSORT }; - papiServiceDestroy { FLAGS = NODYNSORT }; - papiServiceSetUserName { FLAGS = NODYNSORT }; - papiServiceSetPassword { FLAGS = NODYNSORT }; - papiServiceSetEncryption { FLAGS = NODYNSORT }; - papiServiceSetAuthCB { FLAGS = NODYNSORT }; - papiServiceSetAppData { FLAGS = NODYNSORT }; - papiServiceGetUserName { FLAGS = NODYNSORT }; - papiServiceGetPassword { FLAGS = NODYNSORT }; - papiServiceGetEncryption; - papiServiceGetAppData { FLAGS = NODYNSORT }; - papiServiceGetServiceName { FLAGS = NODYNSORT }; - papiServiceGetAttributeList { FLAGS = NODYNSORT }; - papiServiceGetStatusMessage { FLAGS = NODYNSORT }; - - # PAPI Printer Calls - papiPrintersList { FLAGS = NODYNSORT }; - papiPrinterQuery { FLAGS = NODYNSORT }; - papiPrinterAdd { FLAGS = NODYNSORT }; - papiPrinterModify { FLAGS = NODYNSORT }; - papiPrinterRemove { FLAGS = NODYNSORT }; - papiPrinterDisable { FLAGS = NODYNSORT }; - papiPrinterEnable { FLAGS = NODYNSORT }; - papiPrinterPause { FLAGS = NODYNSORT }; - papiPrinterResume { FLAGS = NODYNSORT }; - papiPrinterPurgeJobs { FLAGS = NODYNSORT }; - papiPrinterListJobs { FLAGS = NODYNSORT }; - papiPrinterGetAttributeList { FLAGS = NODYNSORT }; - papiPrinterFree { FLAGS = NODYNSORT }; - papiPrinterListFree { FLAGS = NODYNSORT }; - - # PAPI Job Calls - papiJobSubmit { FLAGS = NODYNSORT }; - papiJobSubmitByReference { FLAGS = NODYNSORT }; - papiJobValidate { FLAGS = NODYNSORT }; - papiJobStreamOpen { FLAGS = NODYNSORT }; - papiJobStreamWrite { FLAGS = NODYNSORT }; - papiJobStreamClose { FLAGS = NODYNSORT }; - papiJobQuery { FLAGS = NODYNSORT }; - papiJobModify { FLAGS = NODYNSORT }; - papiJobMove { FLAGS = NODYNSORT }; - papiJobCancel { FLAGS = NODYNSORT }; - papiJobHold { FLAGS = NODYNSORT }; - papiJobRelease { FLAGS = NODYNSORT }; - papiJobRestart { FLAGS = NODYNSORT }; - papiJobPromote { FLAGS = NODYNSORT }; - papiJobGetAttributeList { FLAGS = NODYNSORT }; - papiJobGetPrinterName { FLAGS = NODYNSORT }; - papiJobGetId; - papiJobGetJobTicket { FLAGS = NODYNSORT }; - papiJobFree { FLAGS = NODYNSORT }; - papiJobListFree { FLAGS = NODYNSORT }; - - # Misc. PAPI Calls - papiStatusString; - papiLibrarySupportedCall; - papiLibrarySupportedCalls; -}; - -SYMBOL_VERSION SUNWprivate_1.0 { # Misc. semi-private supporting calls - global: - papiServiceSetPeer { FLAGS = NODYNSORT }; - papiJobCreate { FLAGS = NODYNSORT }; - papiJobStreamAdd { FLAGS = NODYNSORT }; - papiJobCommit { FLAGS = NODYNSORT }; - - # URI - uri_from_string; - uri_to_string; - uri_free; - - # list - list_remove; - list_append; - list_concatenate; - - # NS - getprinterbyname { FLAGS = NODYNSORT }; - - # extra Attribute Calls - copy_attributes; - split_and_copy_attributes; - papiAttributeListPrint; - - is_localhost; - - local: - *; -}; diff --git a/usr/src/lib/print/libpapi-common/common/misc.c b/usr/src/lib/print/libpapi-common/common/misc.c deleted file mode 100644 index 2688fd0ec0..0000000000 --- a/usr/src/lib/print/libpapi-common/common/misc.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: misc.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <papi.h> -#include <uri.h> -#include <config-site.h> - -/* - * The implementations of strlcpy() and strlcat() have been taken directly - * from OpenSolaris. The contents of this file originated from - * usr/src/lib/libc/port/gen/strlcpy.c - * usr/src/lib/libc/port/gen/strcat.c - */ - -#ifndef HAVE_STRLCPY -size_t -strlcpy(char *dst, const char *src, size_t len) -{ - size_t slen = strlen(src); - size_t copied; - - if (len == 0) - return (slen); - - if (slen >= len) - copied = len - 1; - else - copied = slen; - (void) memcpy(dst, src, copied); - dst[copied] = '\0'; - return (slen); -} -#endif - -#ifndef HAVE_STRLCAT -size_t -strlcat(char *dst, const char *src, size_t dstsize) -{ - char *df = dst; - size_t left = dstsize; - size_t l1; - size_t l2 = strlen(src); - size_t copied; - - while (left-- != 0 && *df != '\0') - df++; - l1 = df - dst; - if (dstsize == l1) - return (l1 + l2); - - copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2; - (void) memcpy(dst + l1, src, copied); - dst[l1+copied] = '\0'; - return (l1 + l2); -} -#endif - -#if defined(__sun) && defined(__SVR4) -#include <sys/systeminfo.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <sys/sockio.h> -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> - -static struct in6_addr ** -local_interfaces() -{ - struct in6_addr **result = NULL; - int s; - struct lifnum n; - struct lifconf c; - struct lifreq *r; - int count; - - /* we need a socket to get the interfaces */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) - return (0); - - /* get the number of interfaces */ - memset(&n, 0, sizeof (n)); - n.lifn_family = AF_UNSPEC; - if (ioctl(s, SIOCGLIFNUM, (char *)&n) < 0) { - close(s); - return (0); /* no interfaces */ - } - - /* get the interface(s) configuration */ - memset(&c, 0, sizeof (c)); - c.lifc_family = AF_UNSPEC; - c.lifc_buf = calloc(n.lifn_count, sizeof (struct lifreq)); - c.lifc_len = (n.lifn_count * sizeof (struct lifreq)); - if (ioctl(s, SIOCGLIFCONF, (char *)&c) < 0) { - free(c.lifc_buf); - close(s); - return (0); /* can't get interface(s) configuration */ - } - close(s); - - r = c.lifc_req; - for (count = c.lifc_len / sizeof (struct lifreq); - count > 0; count--, r++) { - struct in6_addr v6[1], *addr = NULL; - - switch (r->lifr_addr.ss_family) { - case AF_INET: { - struct sockaddr_in *s = - (struct sockaddr_in *)&r->lifr_addr; - IN6_INADDR_TO_V4MAPPED(&s->sin_addr, v6); - addr = v6; - } - break; - case AF_INET6: { - struct sockaddr_in6 *s = - (struct sockaddr_in6 *)&r->lifr_addr; - addr = &s->sin6_addr; - } - break; - } - - if (addr != NULL) { - struct in6_addr *a = malloc(sizeof (*a)); - - memcpy(a, addr, sizeof (*a)); - list_append(&result, a); - } - } - free(c.lifc_buf); - - return (result); -} - -static int -match_interfaces(char *host) -{ - struct in6_addr **lif = local_interfaces(); - struct hostent *hp; - int rc = 0; - int errnum; - - /* are there any local interfaces */ - if (lif == NULL) - return (0); - - /* cycle through the host db addresses */ - hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum); - if (hp != NULL) { - struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list; - int i; - - for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) { - int j; - - for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++) - if (memcmp(tmp[i], lif[j], - sizeof (struct in6_addr)) == 0) - rc = 1; - } - } - free(lif); - - return (rc); -} -#endif - -int -is_localhost(char *host) -{ - char hostname[BUFSIZ]; - - /* is it "localhost" */ - if (strncasecmp(host, "localhost", 10) == 0) - return (1); - - /* is it the {nodename} */ - sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); - if (strncasecmp(host, hostname, strlen(hostname)) == 0) - return (1); - -#if defined(__sun) && defined(__SVR4) - /* does it match one of the host's configured interfaces */ - if (match_interfaces(host) != 0) - return (1); -#endif - return (0); -} diff --git a/usr/src/lib/print/libpapi-common/common/papi.h b/usr/src/lib/print/libpapi-common/common/papi.h deleted file mode 100644 index 5fcaccc584..0000000000 --- a/usr/src/lib/print/libpapi-common/common/papi.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _PAPI_H -#define _PAPI_H - -/* $Id: papi.h 161 2006-05-03 04:32:59Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <time.h> -#include <stdio.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Types - */ - -/* service related types */ -typedef void *papi_service_t; -typedef void *papi_printer_t; -typedef void *papi_job_t; -typedef void *papi_stream_t; - -typedef enum { - PAPI_ENCRYPT_IF_REQUESTED, /* Encrypt if requested (TLS upgrade) */ - PAPI_ENCRYPT_NEVER, /* Never encrypt */ - PAPI_ENCRYPT_REQUIRED, /* Encryption required (TLS upgrade) */ - PAPI_ENCRYPT_ALWAYS /* Always encrypt (SSL) */ -} papi_encryption_t; - -/* attribute related types */ -typedef enum { - PAPI_STRING, - PAPI_INTEGER, - PAPI_BOOLEAN, - PAPI_RANGE, - PAPI_RESOLUTION, - PAPI_DATETIME, - PAPI_COLLECTION, - PAPI_METADATA -} papi_attribute_value_type_t; - -typedef enum { - PAPI_RES_PER_INCH = 3, - PAPI_RES_PER_CM -} papi_resolution_unit_t; - -enum { /* for boolean values */ - PAPI_FALSE = 0, - PAPI_TRUE = 1 -}; - -typedef enum { - PAPI_UNSUPPORTED = 0x10, - PAPI_DEFAULT = 0x11, - PAPI_UNKNOWN, - PAPI_NO_VALUE, - PAPI_NOT_SETTABLE = 0x15, - PAPI_DELETE = 0x16 -} papi_metadata_t; - -#define PAPI_LIST_JOBS_OTHERS 0x0001 -#define PAPI_LIST_JOBS_COMPLETED 0x0002 -#define PAPI_LIST_JOBS_NOT_COMPLETED 0x0004 -#define PAPI_LIST_JOBS_ALL 0xFFFF - -typedef struct papi_attribute_s papi_attribute_t; - -typedef union { - char *string; /* PAPI_STRING value */ - int integer; /* PAPI_INTEGER value */ - char boolean; /* PAPI_BOOLEAN value */ - struct { /* PAPI_RANGE value */ - int lower; - int upper; - } range; - struct { /* PAPI_RESOLUTION value */ - int xres; - int yres; - papi_resolution_unit_t units; - } resolution; - time_t datetime; /* PAPI_DATETIME value */ - papi_attribute_t **collection; /* PAPI_COLLECTION value */ - papi_metadata_t metadata; /* PAPI_METADATA value */ -} papi_attribute_value_t; - -struct papi_attribute_s { - char *name; /* attribute name */ - papi_attribute_value_type_t type; /* type of values */ - papi_attribute_value_t **values; /* list of values */ -}; - -#define PAPI_ATTR_APPEND 0x0001 /* Add values to attr */ -#define PAPI_ATTR_REPLACE 0x0002 /* Delete existing values, then add */ -#define PAPI_ATTR_EXCL 0x0004 /* Fail if attr exists */ - -/* job related types */ -typedef enum { - PAPI_JT_FORMAT_JDF = 0, - PAPI_JT_FORMAT_PWG = 1 -} papi_jt_format_t; - -typedef struct { - papi_jt_format_t format; - char *ticket_data; - char *file_name; -} papi_job_ticket_t; - -/* status related types */ -typedef enum { - PAPI_OK = 0x0000, - PAPI_OK_SUBST, - PAPI_OK_CONFLICT, - PAPI_OK_IGNORED_SUBSCRIPTIONS, - PAPI_OK_IGNORED_NOTIFICATIONS, - PAPI_OK_TOO_MANY_EVENTS, - PAPI_OK_BUT_CANCEL_SUBSCRIPTION, - PAPI_REDIRECTION_OTHER_SITE = 0x0300, - PAPI_BAD_REQUEST = 0x0400, - PAPI_FORBIDDEN, - PAPI_NOT_AUTHENTICATED, - PAPI_NOT_AUTHORIZED, - PAPI_NOT_POSSIBLE, - PAPI_TIMEOUT, - PAPI_NOT_FOUND, - PAPI_GONE, - PAPI_REQUEST_ENTITY, - PAPI_REQUEST_VALUE, - PAPI_DOCUMENT_FORMAT, - PAPI_ATTRIBUTES, - PAPI_URI_SCHEME, - PAPI_CHARSET, - PAPI_CONFLICT, - PAPI_COMPRESSION_NOT_SUPPORTED, - PAPI_COMPRESSION_ERROR, - PAPI_DOCUMENT_FORMAT_ERROR, - PAPI_DOCUMENT_ACCESS_ERROR, - PAPI_ATTRIBUTES_NOT_SETTABLE, - PAPI_IGNORED_ALL_SUBSCRIPTIONS, - PAPI_TOO_MANY_SUBSCRIPTIONS, - PAPI_IGNORED_ALL_NOTIFICATIONS, - PAPI_PRINT_SUPPORT_FILE_NOT_FOUND, - PAPI_INTERNAL_ERROR = 0x0500, - PAPI_OPERATION_NOT_SUPPORTED, - PAPI_SERVICE_UNAVAILABLE, - PAPI_VERSION_NOT_SUPPORTED, - PAPI_DEVICE_ERROR, - PAPI_TEMPORARY_ERROR, - PAPI_NOT_ACCEPTING, - PAPI_PRINTER_BUSY, - PAPI_ERROR_JOB_CANCELLED, - PAPI_MULTIPLE_JOBS_NOT_SUPPORTED, - PAPI_PRINTER_IS_DEACTIVATED, - PAPI_BAD_ARGUMENT, - PAPI_JOB_TICKET_NOT_SUPPORTED -} papi_status_t; - -/* list filter related */ -typedef enum { - PAPI_FILTER_BITMASK = 0 -} papi_filter_type_t; - -typedef struct { - papi_filter_type_t type; - union { - struct { /* PAPI_FILTER_BITMASK */ - unsigned int mask; - unsigned int value; - } bitmask; - } filter; -} papi_filter_t; - -enum { - PAPI_PRINTER_LOCAL = 0x0000, /* Local destination */ - PAPI_PRINTER_CLASS = 0x0001, /* Printer class */ - PAPI_PRINTER_REMOTE = 0x0002, /* Remote destination */ - PAPI_PRINTER_BW = 0x0004, /* Can do B&W printing */ - PAPI_PRINTER_COLOR = 0x0008, /* Can do color printing */ - PAPI_PRINTER_DUPLEX = 0x0010, /* Can do duplex printing */ - PAPI_PRINTER_STAPLE = 0x0020, /* Can do stapling */ - PAPI_PRINTER_COPIES = 0x0040, /* Can do copies */ - PAPI_PRINTER_COLLATE = 0x0080, /* Can collate copies */ - PAPI_PRINTER_PUNCH = 0x0100, /* Can punch output */ - PAPI_PRINTER_COVER = 0x0200, /* Can cover output */ - PAPI_PRINTER_BIND = 0x0400, /* Can bind output */ - PAPI_PRINTER_SORT = 0x0800, /* Can sort output */ - PAPI_PRINTER_SMALL = 0x1000, /* Can do letter/legal/a4 */ - PAPI_PRINTER_MEDIUM = 0x2000, /* Can do tabloid/B/C/A3/A2 */ - PAPI_PRINTER_LARGE = 0x4000, /* Can do D/E/A1/A0 */ - PAPI_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */ - PAPI_PRINTER_IMPLICIT = 0x10000, /* implicit class */ - PAPI_PRINTER_DEFAULT = 0x20000, /* Default printer on network */ - PAPI_PRINTER_OPTIONS = 0xfffc /* ~ (CLASS | REMOTE | IMPLICIT) */ -}; - -/* - * Functions - */ - -/* Service related */ -extern papi_status_t papiServiceCreate(papi_service_t *handle, - char *service_name, char *user_name, - char *password, - int (*authCB)(papi_service_t svc, - void *app_data), - papi_encryption_t encryption, - void *app_data); -extern void papiServiceDestroy(papi_service_t handle); -extern papi_status_t papiServiceSetUserName(papi_service_t handle, - char *user_name); -extern papi_status_t papiServiceSetPassword(papi_service_t handle, - char *password); -extern papi_status_t papiServiceSetEncryption(papi_service_t handle, - papi_encryption_t encryption); -extern papi_status_t papiServiceSetAuthCB(papi_service_t handle, - int (*authCB)(papi_service_t s, - void *app_data)); -extern papi_status_t papiServiceSetAppData(papi_service_t handle, - void *app_data); -extern char *papiServiceGetServiceName(papi_service_t handle); -extern char *papiServiceGetUserName(papi_service_t handle); -extern char *papiServiceGetPassword(papi_service_t handle); -extern papi_encryption_t papiServiceGetEncryption(papi_service_t handle); -extern void *papiServiceGetAppData(papi_service_t handle); -extern papi_attribute_t **papiServiceGetAttributeList(papi_service_t handle); -extern char *papiServiceGetStatusMessage(papi_service_t handle); - -/* Attribute related */ -extern papi_status_t papiAttributeListAddValue(papi_attribute_t ***attrs, - int flags, char *name, - papi_attribute_value_type_t type, - papi_attribute_value_t *value); -extern papi_status_t papiAttributeListAddString(papi_attribute_t ***attrs, - int flags, char *name, char *string); -extern papi_status_t papiAttributeListAddInteger(papi_attribute_t ***attrs, - int flags, char *name, int integer); -extern papi_status_t papiAttributeListAddBoolean(papi_attribute_t ***attrs, - int flags, char *name, char boolean); -extern papi_status_t papiAttributeListAddRange(papi_attribute_t ***attrs, - int flags, char *name, - int lower, int upper); -extern papi_status_t papiAttributeListAddResolution(papi_attribute_t ***attrs, - int flags, char *name, - int xres, int yres, - papi_resolution_unit_t units); -extern papi_status_t papiAttributeListAddDatetime(papi_attribute_t ***attrs, - int flags, char *name, time_t datetime); -extern papi_status_t papiAttributeListAddCollection(papi_attribute_t ***attrs, - int flags, char *name, - papi_attribute_t **collection); -extern papi_status_t papiAttributeListAddMetadata(papi_attribute_t ***attrs, - int flags, char *name, - papi_metadata_t metadata); -extern papi_status_t papiAttributeListDelete(papi_attribute_t ***attributes, - char *name); -extern papi_status_t papiAttributeListGetValue(papi_attribute_t **list, - void **iterator, char *name, - papi_attribute_value_type_t type, - papi_attribute_value_t **value); -extern papi_status_t papiAttributeListGetString(papi_attribute_t **list, - void **iterator, char *name, - char **vptr); -extern papi_status_t papiAttributeListGetInteger(papi_attribute_t **list, - void **iterator, char *name, int *vptr); -extern papi_status_t papiAttributeListGetBoolean(papi_attribute_t **list, - void **iterator, char *name, - char *vptr); -extern papi_status_t papiAttributeListGetRange(papi_attribute_t **list, - void **iterator, char *name, - int *min, int *max); -extern papi_status_t papiAttributeListGetResolution(papi_attribute_t **list, - void **iterator, char *name, - int *x, int *y, - papi_resolution_unit_t *units); -extern papi_status_t papiAttributeListGetDatetime(papi_attribute_t **list, - void **iterator, char *name, - time_t *dt); -extern papi_status_t papiAttributeListGetCollection(papi_attribute_t **list, - void **iterator, char *name, - papi_attribute_t ***collection); -extern papi_status_t papiAttributeListGetMetadata(papi_attribute_t **list, - void **iterator, char *name, - papi_metadata_t *vptr); -extern papi_attribute_t *papiAttributeListFind(papi_attribute_t **list, - char *name); -extern papi_attribute_t *papiAttributeListGetNext(papi_attribute_t **list, - void **iterator); -extern void papiAttributeListFree(papi_attribute_t **attributes); - -extern papi_status_t papiAttributeListFromString(papi_attribute_t ***attrs, - int flags, char *string); -extern papi_status_t papiAttributeListToString(papi_attribute_t **attrs, - char *delim, - char *buffer, size_t buflen); -extern void papiAttributeListPrint(FILE *fp, papi_attribute_t **list, - char *prefix_fmt, ...); - -/* Printer related */ -extern papi_status_t papiPrintersList(papi_service_t handle, - char **requested_attrs, - papi_filter_t *filter, - papi_printer_t **printers); -extern papi_status_t papiPrinterQuery(papi_service_t handle, char *name, - char **requested_attrs, - papi_attribute_t **job_attributes, - papi_printer_t *printer); -extern papi_status_t papiPrinterAdd(papi_service_t handle, char *name, - papi_attribute_t **attributes, - papi_printer_t *printer); -extern papi_status_t papiPrinterModify(papi_service_t handle, char *name, - papi_attribute_t **attributes, - papi_printer_t *printer); -extern papi_status_t papiPrinterRemove(papi_service_t handle, char *name); -extern papi_status_t papiPrinterDisable(papi_service_t handle, char *name, - char *message); -extern papi_status_t papiPrinterEnable(papi_service_t handle, char *name); -extern papi_status_t papiPrinterPause(papi_service_t handle, char *name, - char *message); -extern papi_status_t papiPrinterResume(papi_service_t handle, char *name); -extern papi_status_t papiPrinterPurgeJobs(papi_service_t handle, - char *name, papi_job_t **jobs); -extern papi_status_t papiPrinterListJobs(papi_service_t handle, - char *name, char **requested_attrs, - int type_mask, int max_num_jobs, - papi_job_t **jobs); -extern papi_attribute_t **papiPrinterGetAttributeList(papi_printer_t printer); -extern void papiPrinterFree(papi_printer_t printer); -extern void papiPrinterListFree(papi_printer_t *printers); - -/* Job related */ -extern papi_status_t papiJobSubmit(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - char **files, papi_job_t *job); -extern papi_status_t papiJobSubmitByReference(papi_service_t handle, - char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - char **files, papi_job_t *job); -extern papi_status_t papiJobValidate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - char **files, papi_job_t *job); -extern papi_status_t papiJobStreamOpen(papi_service_t handle, - char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - papi_stream_t *stream); -extern papi_status_t papiJobStreamWrite(papi_service_t handle, - papi_stream_t stream, - void *buffer, size_t buflen); -extern papi_status_t papiJobStreamClose(papi_service_t handle, - papi_stream_t stream, - papi_job_t *job); -extern papi_status_t papiJobQuery(papi_service_t handle, char *printer, - int32_t job_id, char **requested_attrs, - papi_job_t *job); -extern papi_status_t papiJobModify(papi_service_t handle, char *printer, - int32_t job_id, - papi_attribute_t **attributes, - papi_job_t *job); -extern papi_status_t papiJobMove(papi_service_t handle, char *printer, - int32_t job_id, char *destination); -extern papi_status_t papiJobCancel(papi_service_t handle, char *printer, - int32_t job_id); -extern papi_status_t papiJobHold(papi_service_t handle, char *printer, - int32_t job_id); -extern papi_status_t papiJobRelease(papi_service_t handle, char *printer, - int32_t job_id); -extern papi_status_t papiJobRestart(papi_service_t handle, char *printer, - int32_t job_id); -extern papi_status_t papiJobPromote(papi_service_t handle, char *printer, - int32_t job_id); -extern papi_attribute_t **papiJobGetAttributeList(papi_job_t printer); -extern char *papiJobGetPrinterName(papi_job_t printer); -extern int32_t papiJobGetId(papi_job_t printer); -extern papi_job_ticket_t *papiJobGetJobTicket(papi_job_t printer); -extern void papiJobFree(papi_job_t job); -extern void papiJobListFree(papi_job_t *jobs); - -#ifdef SOLARIS_PRIVATE_POST_0_9 -/* - * These have been added to support IPP create-job/send-document with PAPI v0.9 - * in an IPP listener using PAPI as it's spooler interface. A future version - * of the API is expected to support this type of functionality - */ -extern papi_status_t papiJobCreate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - papi_job_t *job); -extern papi_status_t papiJobStreamAdd(papi_service_t handle, char *printer, - int32_t id, papi_stream_t *stream); -extern papi_status_t papiJobCommit(papi_service_t handle, char *printer, - int32_t id); -extern papi_status_t papiServiceSetPeer(papi_service_t handle, int peerfd); -#endif /* SOLARIS_PRIVATE_POST_0_9 */ - -extern char *papiStatusString(papi_status_t status); - -/* - * Internal functions that aren't in the API, but are shared across - * protocol support implementations(psms) and the tightly bound - * listener library. Do not use these in your applications. - */ -extern void list_append(); -extern void list_concatenate(); -extern void list_remove(); -extern void copy_attributes(papi_attribute_t ***result, - papi_attribute_t **list); -extern void split_and_copy_attributes(char **list, - papi_attribute_t **attributes, - papi_attribute_t ***in, - papi_attribute_t ***out); - -extern papi_attribute_t **getprinterbyname(char *name, char *ns); - -extern int is_localhost(char *hostname); - -#ifdef __cplusplus -} -#endif - -#endif /* _PAPI_H */ diff --git a/usr/src/lib/print/libpapi-common/common/status.c b/usr/src/lib/print/libpapi-common/common/status.c deleted file mode 100644 index 897aa1322d..0000000000 --- a/usr/src/lib/print/libpapi-common/common/status.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: status.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdlib.h> -#include <papi.h> -#include <libintl.h> - -char * -papiStatusString(const papi_status_t status) -{ - switch (status) { - case PAPI_OK: - return (gettext("ok")); - case PAPI_OK_SUBST: - return (gettext("ok-substitution")); - case PAPI_OK_CONFLICT: - return (gettext("ok-conflict")); - case PAPI_OK_IGNORED_SUBSCRIPTIONS: - return (gettext("ok-ignored-subscriptions")); - case PAPI_OK_IGNORED_NOTIFICATIONS: - return (gettext("ok-ignored-notifications")); - case PAPI_OK_TOO_MANY_EVENTS: - return (gettext("ok-too-many-events")); - case PAPI_OK_BUT_CANCEL_SUBSCRIPTION: - return (gettext("ok-but-cancel-subscription")); - case PAPI_REDIRECTION_OTHER_SITE: - return (gettext("redirection-to-other-site")); - case PAPI_BAD_REQUEST: - return (gettext("bad-request")); - case PAPI_FORBIDDEN: - return (gettext("forbidden")); - case PAPI_NOT_AUTHENTICATED: - return (gettext("not-authenticated")); - case PAPI_NOT_AUTHORIZED: - return (gettext("not-authorized")); - case PAPI_NOT_POSSIBLE: - return (gettext("not-possible")); - case PAPI_TIMEOUT: - return (gettext("timeout")); - case PAPI_NOT_FOUND: - return (gettext("not-found")); - case PAPI_GONE: - return (gettext("gone")); - case PAPI_REQUEST_ENTITY: - return (gettext("request-entity")); - case PAPI_REQUEST_VALUE: - return (gettext("request-value")); - case PAPI_DOCUMENT_FORMAT: - return (gettext("document-format")); - case PAPI_ATTRIBUTES: - return (gettext("attributes")); - case PAPI_URI_SCHEME: - return (gettext("uri-scheme")); - case PAPI_CHARSET: - return (gettext("charset")); - case PAPI_CONFLICT: - return (gettext("conflict")); - case PAPI_COMPRESSION_NOT_SUPPORTED: - return (gettext("compression-not-supported")); - case PAPI_COMPRESSION_ERROR: - return (gettext("compression-error")); - case PAPI_DOCUMENT_FORMAT_ERROR: - return (gettext("document-format-error")); - case PAPI_DOCUMENT_ACCESS_ERROR: - return (gettext("document-access-error")); - case PAPI_ATTRIBUTES_NOT_SETTABLE: - return (gettext("attributes-not-settable")); - case PAPI_IGNORED_ALL_SUBSCRIPTIONS: - return (gettext("ignored-all-subscriptions")); - case PAPI_TOO_MANY_SUBSCRIPTIONS: - return (gettext("too-many-subscriptions")); - case PAPI_IGNORED_ALL_NOTIFICATIONS: - return (gettext("ignored-all-notifications")); - case PAPI_PRINT_SUPPORT_FILE_NOT_FOUND: - return (gettext("print-support-file-not-found")); - case PAPI_INTERNAL_ERROR: - return (gettext("internal-error")); - case PAPI_OPERATION_NOT_SUPPORTED: - return (gettext("operation-not-supported")); - case PAPI_SERVICE_UNAVAILABLE: - return (gettext("service-unavailable")); - case PAPI_VERSION_NOT_SUPPORTED: - return (gettext("version-not-supported")); - case PAPI_DEVICE_ERROR: - return (gettext("device-error")); - case PAPI_TEMPORARY_ERROR: - return (gettext("temporary-error")); - case PAPI_NOT_ACCEPTING: - return (gettext("not-accepting")); - case PAPI_PRINTER_BUSY: - return (gettext("printer-busy")); - case PAPI_ERROR_JOB_CANCELLED: - return (gettext("error-job-cancelled")); - case PAPI_MULTIPLE_JOBS_NOT_SUPPORTED: - return (gettext("multiple-jobs-not-supported")); - case PAPI_PRINTER_IS_DEACTIVATED: - return (gettext("printer-is-deactivated")); - case PAPI_BAD_ARGUMENT: - return (gettext("bad-argument")); - case PAPI_JOB_TICKET_NOT_SUPPORTED: - return (gettext("job-ticket-not-supported")); - default: - return (gettext("unknown-error")); - } -} diff --git a/usr/src/lib/print/libpapi-common/common/uri.c b/usr/src/lib/print/libpapi-common/common/uri.c deleted file mode 100644 index 31f6ce4eff..0000000000 --- a/usr/src/lib/print/libpapi-common/common/uri.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* $Id: uri.c 146 2006-03-24 00:26:54Z njacobs $ */ - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <errno.h> -#include "uri.h" - -/* - * This will handle the following forms: - * scheme:scheme_data - * scheme://[[user[:password]@]host[:port]]/path[[#fragment]|[?query]] - */ -int -uri_from_string(char *string, uri_t **uri) -{ - char *ptr; - uri_t *u; - - if ((string == NULL) || (uri == NULL)) { - errno = EINVAL; - return (-1); - } - - /* find the scheme:scheme_part split */ - if ((ptr = strchr(string, ':')) == NULL) { - errno = EINVAL; - return (-1); - } - - if ((*uri = u = calloc(1, sizeof (*u))) == NULL) - return (-1); - - u->scheme = strndup(string, ptr - string); - - if ((ptr[1] == '/') && (ptr[2] == '/')) { - /* - * CSTYLED - * scheme://[host_part]/[path_part] - */ - char *end = NULL, *user = NULL, *host = NULL, *path = NULL; - - string = ptr + 3; /* skip the :// */ - - if ((path = end = strchr(string, '/')) == NULL) - for (end = string; *end != '\0'; end++) - continue; - - u->host_part = strndup(string, end - string); - - for (host = string; host < end; host ++) - if (*host == '@') { - /* string to host is the user part */ - u->user_part = strndup(string, host-string); - /* host+1 to end is the host part */ - u->host_part = strndup(host + 1, - end - (host+1)); - user = string; - host++; - break; - } - - if (user != NULL) { - char *password = NULL; - - for (password = user; (password < host - 1); password++) - if (*password == ':') { - u->password = strndup(password + 1, - host - password - 2); - break; - } - u->user = strndup(user, password - user); - } else - host = string; - - if (host != NULL) { - char *port = NULL; - - for (port = host; (port < path); port++) - if ((*port == ':') || (*port == '/')) - break; - - if (port < path) { - u->port = strndup(port + 1, path - port - 1); - } - - u->host = strndup(host, port - host); - } - - if (path != NULL) { - char *name = strrchr(path, '/'); - - u->path_part = strdup(path); - - if (name != NULL) { - char *query, *fragment; - - query = strrchr(name, '?'); - if ((query != NULL) && (*query != '\0')) { - u->query = strdup(query + 1); - end = query; - } else { - for (end = path; *end != '\0'; end++) - continue; - } - - fragment = strrchr(name, '#'); - if ((fragment != NULL) && (*fragment != '\0')) { - u->fragment = strndup(fragment + 1, - end - fragment - 1); - end = fragment; - } - - u->path = strndup(path, end - path); - } - } - } else { /* scheme:scheme_part */ - u->scheme_part = strdup(&ptr[1]); - } - - if ((u->host_part == NULL) && (u->path_part == NULL) && - (u->scheme_part == NULL)) { - errno = EINVAL; - uri_free(u); - *uri = NULL; - return (-1); - } - - return (0); -} - -int -uri_to_string(uri_t *uri, char *buffer, size_t buflen) -{ - char *uri_ppfix; - - if ((uri == NULL) || (buffer == NULL) || (buflen == 0) || - (uri->scheme == NULL) || - ((uri->password != NULL) && (uri->user == NULL)) || - ((uri->user != NULL) && (uri->host == NULL)) || - ((uri->port != NULL) && (uri->host == NULL)) || - ((uri->fragment != NULL) && (uri->path == NULL)) || - ((uri->query != NULL) && (uri->path == NULL))) { - errno = EINVAL; - return (-1); - } - if (uri->path == NULL || uri->path[0] == '/') - uri_ppfix = ""; - else - uri_ppfix = "/"; - - (void) memset(buffer, 0, buflen); - - if (uri->scheme_part == NULL) { - (void) snprintf(buffer, buflen, - "%s://%s%s%s%s%s%s%s%s%s%s%s%s%s", - uri->scheme, - (uri->user ? uri->user : ""), - (uri->password ? ":" : ""), - (uri->password ? uri->password : ""), - (uri->user ? "@": ""), - (uri->host ? uri->host : ""), - (uri->port ? ":" : ""), - (uri->port ? uri->port : ""), - uri_ppfix, - (uri->path ? uri->path : ""), - (uri->fragment ? "#" : ""), - (uri->fragment ? uri->fragment : ""), - (uri->query ? "?" : ""), - (uri->query ? uri->query : "")); - } else { - (void) snprintf(buffer, buflen, "%s:%s", uri->scheme, - uri->scheme_part); - } - - return (0); -} - -void -uri_free(uri_t *uri) -{ - if (uri != NULL) { - if (uri->scheme != NULL) - free(uri->scheme); - if (uri->scheme_part != NULL) - free(uri->scheme_part); - if (uri->user != NULL) - free(uri->user); - if (uri->password != NULL) - free(uri->password); - if (uri->host != NULL) - free(uri->host); - if (uri->port != NULL) - free(uri->port); - if (uri->path != NULL) - free(uri->path); - if (uri->fragment != NULL) - free(uri->fragment); - if (uri->query != NULL) - free(uri->query); - /* help me debug */ - if (uri->user_part != NULL) - free(uri->user_part); - if (uri->host_part != NULL) - free(uri->host_part); - if (uri->path_part != NULL) - free(uri->path_part); - free(uri); - } -} - -#ifdef DEADBEEF -static void -uri_dump(FILE *fp, uri_t *uri) -{ - if (uri != NULL) { - fprintf(fp, "URI:\n"); - if (uri->scheme != NULL) - fprintf(fp, "scheme: %s\n", uri->scheme); - if (uri->scheme_part != NULL) - fprintf(fp, "scheme_part: %s\n", uri->scheme_part); - if (uri->user != NULL) - fprintf(fp, "user: %s\n", uri->user); - if (uri->password != NULL) - fprintf(fp, "password: %s\n", uri->password); - if (uri->host != NULL) - fprintf(fp, "host: %s\n", uri->host); - if (uri->port != NULL) - fprintf(fp, "port: %s\n", uri->port); - if (uri->path != NULL) - fprintf(fp, "path: %s\n", uri->path); - if (uri->fragment != NULL) - fprintf(fp, "fragment: %s\n", uri->fragment); - if (uri->query != NULL) - fprintf(fp, "query: %s\n", uri->query); - /* help me debug */ - if (uri->user_part != NULL) - fprintf(fp, "user_part: %s\n", uri->user_part); - if (uri->host_part != NULL) - fprintf(fp, "host_part: %s\n", uri->host_part); - if (uri->path_part != NULL) - fprintf(fp, "path_part: %s\n", uri->path_part); - fflush(fp); - } -} - -int -main(int argc, char *argv[]) -{ - uri_t *u = NULL; - - if (argc != 2) { - fprintf(stderr, "Usage: %s uri\n", argv[0]); - exit(1); - } - - if (uri_from_string(argv[1], &u) == 0) { - char buf[BUFSIZ]; - - uri_dump(stdout, u); - uri_to_string(u, buf, sizeof (buf)); - fprintf(stdout, "reconstituted: %s\n", buf); - - uri_to_string(u, buf, 12); - fprintf(stdout, "reconstituted(12): %s\n", buf); - } else - printf(" failed for %s (%s)\n", argv[1], strerror(errno)); - - exit(0); -} -#endif /* DEADBEEF */ diff --git a/usr/src/lib/print/libpapi-common/i386/Makefile b/usr/src/lib/print/libpapi-common/i386/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libpapi-common/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-common/sparc/Makefile b/usr/src/lib/print/libpapi-common/sparc/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libpapi-common/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-dynamic/Makefile.com b/usr/src/lib/print/libpapi-dynamic/Makefile.com deleted file mode 100644 index 8a51154c48..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/Makefile.com +++ /dev/null @@ -1,57 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = libpapi.a -VERS = .0 -OBJECTS = job.o nss.o printer.o psm.o service.o - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -MAPFILES = $(SRCDIR)/mapfile - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common -CPPFLAGS += -DNSS_SOLARIS -LDLIBS += -lc - -CERRWARN += -_gcc=-Wno-unused-variable - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-dynamic/common/job.c b/usr/src/lib/print/libpapi-dynamic/common/job.c deleted file mode 100644 index e7bca751a0..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/job.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: job.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <papi_impl.h> - -void -papiJobFree(papi_job_t job) -{ - job_t *tmp = (job_t *)job; - - if (tmp != NULL) { - void (*f)(); - - f = (void (*)())psm_sym(tmp->svc, "papiJobFree"); - if (f != NULL) - f(tmp->job); - free(tmp); - } -} - -void -papiJobListFree(papi_job_t *jobs) -{ - if (jobs != NULL) { - int i; - - for (i = 0; jobs[i] != NULL; i++) - papiJobFree(jobs[i]); - free(jobs); - } -} - -papi_attribute_t ** -papiJobGetAttributeList(papi_job_t job) -{ - papi_attribute_t **result = NULL; - job_t *j = job; - - if (job != NULL) { - papi_attribute_t **(*f)(); - - f = (papi_attribute_t **(*)())psm_sym(j->svc, - "papiJobGetAttributeList"); - if (f != NULL) - result = f(j->job); - } - - return (result); -} - -char * -papiJobGetPrinterName(papi_job_t job) -{ - char *result = NULL; - job_t *j = job; - - if (job != NULL) { - char *(*f)(); - - f = (char *(*)())psm_sym(j->svc, "papiJobGetPrinterName"); - if (f != NULL) - result = f(j->job); - } - - return (result); -} - -int32_t -papiJobGetId(papi_job_t job) -{ - int32_t result = -1; - job_t *j = job; - - if (job != NULL) { - int32_t (*f)(); - - f = (int32_t (*)())psm_sym(j->svc, "papiJobGetId"); - if (f != NULL) - result = f(j->job); - } - - return (result); -} - -papi_job_ticket_t * -papiJobGetJobTicket(papi_job_t job) -{ - papi_job_ticket_t *result = NULL; - job_t *j = job; - - if (job != NULL) { - papi_job_ticket_t *(*f)(); - - f = (papi_job_ticket_t *(*)())psm_sym(j->svc, - "papiJobGetJobTicket"); - if (f != NULL) - result = f(j->job); - } - - return (result); -} - -/* common support for papiJob{Submit|SubmitByReference|Validate} */ -static papi_status_t -_papi_job_submit_reference_or_validate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job, - char *function) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (files == NULL) || - (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - f = (papi_status_t (*)())psm_sym(j->svc, function); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_attributes, - job_ticket, files, &j->job); - - return (result); -} - -papi_status_t -papiJobSubmit(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (_papi_job_submit_reference_or_validate(handle, printer, - job_attributes, job_ticket, files, job, - "papiJobSubmit")); -} - -papi_status_t -papiJobSubmitByReference(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (_papi_job_submit_reference_or_validate(handle, printer, - job_attributes, job_ticket, files, job, - "papiJobSubmitByReference")); -} - -papi_status_t -papiJobValidate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (_papi_job_submit_reference_or_validate(handle, printer, - job_attributes, job_ticket, files, job, - "papiJobValidate")); -} - -papi_status_t -papiJobStreamOpen(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, papi_stream_t *stream) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (stream == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamOpen"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_attributes, - job_ticket, stream); - - return (result); -} - -papi_status_t -papiJobStreamWrite(papi_service_t handle, - papi_stream_t stream, void *buffer, size_t buflen) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || - (buflen == 0)) - return (PAPI_BAD_ARGUMENT); - - f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamWrite"); - if (f != NULL) - result = f(svc->svc_handle, stream, buffer, buflen); - - return (result); -} - -papi_status_t -papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (stream == NULL) || (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - f = (papi_status_t (*)())psm_sym(j->svc, "papiJobStreamClose"); - if (f != NULL) - result = f(svc->svc_handle, stream, &j->job); - - return (result); -} - -papi_status_t -papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, - char **requested_attrs, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - f = (papi_status_t (*)())psm_sym(j->svc, "papiJobQuery"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_id, - requested_attrs, &j->job); - - return (result); -} - -papi_status_t -papiJobMove(papi_service_t handle, char *printer, int32_t job_id, - char *destination) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (job_id < 0)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiJobMove"); - if (f != NULL) { - papi_attribute_t **attrs = getprinterbyname(destination, NULL); - - papiAttributeListGetString(attrs, NULL, - "printer-uri-supported", &destination); - result = f(svc->svc_handle, svc->name, job_id, destination); - papiAttributeListFree(attrs); - } - - return (result); -} - -/* common support for papiJob{Cancel|Release|Restart|Promote} */ -static papi_status_t -_papi_job_handle_printer_id(papi_service_t handle, - char *printer, int32_t job_id, char *function) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (job_id < 0)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, function); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_id); - - return (result); -} - -papi_status_t -papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobCancel")); -} - -papi_status_t -papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobRelease")); -} - -papi_status_t -papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobRestart")); -} - -papi_status_t -papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobPromote")); -} - -papi_status_t -papiJobCommit(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobCommit")); -} - -papi_status_t -papiJobHold(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_papi_job_handle_printer_id(handle, printer, job_id, - "papiJobHold")); -} - -papi_status_t -papiJobModify(papi_service_t handle, char *printer, int32_t job_id, - papi_attribute_t **attributes, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (job_id < 0) || - (attributes == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - f = (papi_status_t (*)())psm_sym(j->svc, "papiJobModify"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_id, attributes, - &j->job); - - return (result); -} - -/* - * The functions defined below are private to Solaris. They are here - * temporarily, until equivalent functionality makes it's way into the PAPI - * spec. This is expected in the next minor version after v1.0. - */ -papi_status_t -papiJobCreate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL) || (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - f = (papi_status_t (*)())psm_sym(j->svc, "papiJobCreate"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, job_attributes, - job_ticket, &j->job); - - return (result); -} - -papi_status_t -papiJobStreamAdd(papi_service_t handle, char *printer, int32_t id, - papi_stream_t *stream) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiJobStreamAdd"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, id, stream); - - return (result); -} diff --git a/usr/src/lib/print/libpapi-dynamic/common/mapfile b/usr/src/lib/print/libpapi-dynamic/common/mapfile deleted file mode 100644 index cc8cb45239..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/mapfile +++ /dev/null @@ -1,279 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ -# - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -# -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. -# - -SYMBOL_VERSION SUNW_1.0 { - global: - # PAPI Attribute Calls - papiAttributeListAddValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListDelete { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetNext { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFind { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFromString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListToString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFree { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # PAPI Service Calls - papiServiceCreate ; - papiServiceDestroy ; - papiServiceSetUserName ; - papiServiceSetPassword ; - papiServiceSetEncryption ; - papiServiceSetAuthCB ; - papiServiceSetAppData ; - papiServiceGetUserName ; - papiServiceGetPassword ; - papiServiceGetEncryption ; - papiServiceGetAppData ; - papiServiceGetServiceName ; - papiServiceGetAttributeList ; - papiServiceGetStatusMessage ; - - # PAPI Printer Calls - papiPrintersList ; - papiPrinterQuery ; - papiPrinterAdd ; - papiPrinterModify ; - papiPrinterRemove ; - papiPrinterDisable ; - papiPrinterEnable ; - papiPrinterPause ; - papiPrinterResume ; - papiPrinterPurgeJobs ; - papiPrinterListJobs ; - papiPrinterGetAttributeList ; - papiPrinterFree ; - papiPrinterListFree ; - - # PAPI Job Calls - papiJobSubmit ; - papiJobSubmitByReference ; - papiJobValidate ; - papiJobStreamOpen ; - papiJobStreamWrite ; - papiJobStreamClose ; - papiJobQuery ; - papiJobModify ; - papiJobMove ; - papiJobCancel ; - papiJobHold ; - papiJobRelease ; - papiJobRestart ; - papiJobPromote ; - papiJobGetAttributeList ; - papiJobGetPrinterName ; - papiJobGetId ; - papiJobGetJobTicket ; - papiJobFree ; - papiJobListFree ; - - # Misc. PAPI Calls - papiStatusString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiLibrarySupportedCall { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiLibrarySupportedCalls { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; -}; - -SYMBOL_VERSION SUNWprivate_1.0 { - global: - papiServiceSetPeer ; # extension - papiJobCreate ; - papiJobStreamAdd ; - papiJobCommit ; - - # Misc. supporting calls - # URI - uri_from_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_to_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_free { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # list - list_remove { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_append { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_concatenate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # NS - getprinterbyname ; - is_localhost { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # extra Attribute Calls - copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - split_and_copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListPrint { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - local: - * ; -} ; - -SYMBOL_VERSION FSG_1.0 {} SUNW_1.0; diff --git a/usr/src/lib/print/libpapi-dynamic/common/nss.c b/usr/src/lib/print/libpapi-dynamic/common/nss.c deleted file mode 100644 index 5ab245e936..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/nss.c +++ /dev/null @@ -1,532 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - * - */ - -/* Id: nss.c 180 2006-07-20 17:33:02Z njacobs $ */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <syslog.h> -#include <papi.h> -#include <uri.h> -#include <papi_impl.h> -#ifdef NSS_EMULATION -#include <nss-emulation.h> -#elif NSS_SOLARIS -#include <nss_dbdefs.h> -#endif -#include <config-site.h> -#if defined(__sun) && defined(__SVR4) -#include <sys/systeminfo.h> -#endif - - -static char * -bsdaddr_to_uri(papi_attribute_t **list, char *bsdaddr) -{ - char *result = NULL; - - if (bsdaddr != NULL) { - char *bsd[3], *tmp, *iter = NULL; - char buf[512]; - - tmp = strdup(bsdaddr); - - bsd[0] = strtok_r(tmp, ":,", &iter); - if ((bsd[1] = strtok_r(NULL, ":,", &iter)) == NULL) - papiAttributeListGetString(list, NULL, - "printer-name", &bsd[1]); - bsd[2] = strtok_r(NULL, ":,", &iter); - - snprintf(buf, sizeof (buf), "lpd://%s/printers/%s%s%s", bsd[0], - (bsd[1] != NULL) ? bsd[1] : "", - (bsd[2] != NULL) ? "#" : "", - (bsd[2] != NULL) ? bsd[2] : ""); - - free(tmp); - - result = strdup(buf); - } - - return (result); -} - -#if defined(__sun) && defined(__SVR4) -/* - * This is an awful HACK to force the dynamic PAPI library to use the - * lpsched support when the destination apears to be a local lpsched - * queue on Solaris. - */ -static void -solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) -{ - papi_attribute_t *attribute; - uri_t *uri = NULL; - char *printer = NULL; - char buf[128], buf2[128]; - - /* setting this in the calling env can be useful for debugging */ - if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) - return; - - papiAttributeListGetString(*list, NULL, - "printer-uri-supported", &printer); - /* if there is no printer-uri-supported, there is nothing to do */ - if (printer == NULL) { - return; - } - - if (uri_from_string(printer, &uri) < 0) { - papiAttributeListFree(*list); - *list = NULL; - uri_free(uri); - return; - } - - /* already an lpsched URI ? */ - if (strcasecmp(uri->scheme, "lpsched") == 0) { - uri_free(uri); - return; - } - - if (uri->path == NULL) { - printer = ""; - } else { - if ((printer = strrchr(uri->path, '/')) == NULL) - printer = uri->path; - else - printer++; - } - - /* is there an lpsched queue (printer/class) */ - snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); - snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); - if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) { - uri_free(uri); - return; - } - - /* is this the "local" host */ - if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) { - uri_free(uri); - return; - } - - snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s", - (uri->host ? uri->host : "localhost"), printer); - papiAttributeListAddString(list, PAPI_ATTR_REPLACE, - "printer-uri-supported", buf); - uri_free(uri); -} -#endif - -static void -fill_printer_uri_supported(papi_attribute_t ***list) -{ - papi_attribute_t *attribute; - char *string = NULL; - - /* do we have a printer-uri-supported */ - attribute = papiAttributeListFind(*list, "printer-uri-supported"); - if (attribute != NULL) /* we have what we need, return */ - return; - - /* do we have a printer-uri (in URI form) to rename */ - attribute = papiAttributeListFind(*list, "printer-uri"); - if ((attribute != NULL) && - (attribute->type == PAPI_STRING) && - (attribute->values != NULL) && - (attribute->values[0]->string != NULL) && - (strstr(attribute->values[0]->string, "://") != NULL)) { - /* rename it in place and return */ - free(attribute->name); - attribute->name = strdup("printer-uri-supported"); - return; - } - - /* do we have a printers.conf(4) "bsdaddr" to convert */ - papiAttributeListGetString(*list, NULL, "bsdaddr", &string); - if (string != NULL) { /* parse it, convert it, add it */ - char *uri = bsdaddr_to_uri(*list, string); - - if (uri != NULL) { - papiAttributeListAddString(list, PAPI_ATTR_APPEND, - "printer-uri-supported", uri); - papiAttributeListDelete(list, "bsdaddr"); - free(uri); - return; - } - } - - /* do we have a printers.conf(4) "rm" (and "rp") to convert */ - papiAttributeListGetString(*list, NULL, "rm", &string); - if (string != NULL) { - char *rp = NULL; - - /* default to "printer-name", but use "rp" if we have it */ - papiAttributeListGetString(*list, NULL, "printer-name", &rp); - papiAttributeListGetString(*list, NULL, "rp", &rp); - - if (rp != NULL) { /* fill in the uri if we have the data */ - char buf[BUFSIZ]; - - snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", - string, rp); - papiAttributeListAddString(list, PAPI_ATTR_APPEND, - "printer-uri-supported", strdup(buf)); - return; - } - } - - /* if were are here, we don't have a printer-uri-supported */ -} - -#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC -static void -fill_printer_uri(papi_attribute_t ***list) -{ - papi_attribute_t *attribute; - char *uri = NULL; - - if ((list == NULL) || (*list == NULL)) - return; - - /* do we have a printer-uri */ - attribute = papiAttributeListFind(*list, "printer-uri"); - if (attribute != NULL) /* we have what we need, return */ - return; - - /* - * this is sufficient to fool libgnomeprintpapi, but not promote it's - * use in the future. - */ - papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", - "broken printer-uri semantic"); -} -#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ - -static void -cvt_all_to_member_names(papi_attribute_t ***list) -{ - papi_status_t status; - void *iter = NULL; - char *string = NULL; - - papiAttributeListGetString(*list, NULL, "member-names", &string); - if (string != NULL) /* already have a member-names */ - return; - - for (status = papiAttributeListGetString(*list, &iter, "all", &string); - status == PAPI_OK; - status = papiAttributeListGetString(*list, &iter, NULL, &string)) { - char *s_iter = NULL, *value, *tmp = strdup(string); - - for (value = strtok_r(tmp, ", \t", &s_iter); - value != NULL; - value = strtok_r(NULL, ", \t", &s_iter)) - papiAttributeListAddString(list, PAPI_ATTR_APPEND, - "member-names", value); - free(tmp); - } -} - -static papi_attribute_t ** -_cvt_nss_entry_to_printer(char *entry) -{ - char *key = NULL; - char *cp; - char buf[BUFSIZ]; - int in_namelist = 1, buf_pos = 0; - papi_attribute_t **list = NULL; - - if (entry == NULL) - return (NULL); - - memset(buf, 0, sizeof (buf)); - for (cp = entry; *cp != '\0'; cp++) { - switch (*cp) { - case ':': /* end of kvp */ - if (in_namelist != 0) { - papiAttributeListAddString(&list, - PAPI_ATTR_APPEND, "printer-name", buf); - in_namelist = 0; - } else if (key != NULL) { - papiAttributeListAddString(&list, - PAPI_ATTR_APPEND, key, buf); - free(key); - } - memset(buf, 0, sizeof (buf)); - buf_pos = 0; - key = NULL; - break; - case '=': /* kvp seperator */ - if (key == NULL) { - key = strdup(buf); - memset(buf, 0, sizeof (buf)); - buf_pos = 0; - } else - buf[buf_pos++] = *cp; - break; - case '|': /* namelist seperator */ - if (in_namelist != 0) { - papiAttributeListAddString(&list, - PAPI_ATTR_APPEND, "printer-name", buf); - memset(buf, 0, sizeof (buf)); - buf_pos = 0; - } else /* add it to the buffer */ - buf[buf_pos++] = *cp; - break; - case '\\': /* escape char */ - buf[buf_pos++] = *(++cp); - break; - default: - buf[buf_pos++] = *cp; - } - - } - - if (key != NULL) { - papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); - free(key); - } - - /* resolve any "use" references in the configuration DB */ - key = NULL; - papiAttributeListGetString(list, NULL, "use", &key); - if (key != NULL) { - papi_attribute_t **use_attrs = getprinterbyname(key, NULL); - - list_concatenate(&list, use_attrs); - } - - fill_printer_uri_supported(&list); - cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ - - return (list); -} - -#if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) - -#ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ -#define NSS_DBNAM__PRINTERS "_printers" -#endif - -static DEFINE_NSS_DB_ROOT(db_root); -static DEFINE_NSS_GETENT(context); - -static char *private_ns = NULL; - -static void -_nss_initf_printers(p) - nss_db_params_t *p; -{ - if (private_ns != NULL) { - /* - * because we need to support a legacy interface that allows - * us to select a specific name service, we need to dummy up - * the parameters to use a private nsswitch database and set - * the * default_config entry to the name service we are - * looking into. - */ - p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ - p->default_config = private_ns; - } else { - /* regular behaviour */ - p->name = NSS_DBNAM_PRINTERS; /* "printers" */ - p->default_config = NSS_DEFCONF_PRINTERS; - } - syslog(LOG_DEBUG, "database: %s, default: %s", - (p->name ? p->name : "NULL"), - (p->default_config ? p->default_config : "NULL")); -} - -/* - * Return values: 0 = success, 1 = parse error, 2 = erange ... - * The structure pointer passed in is a structure in the caller's space - * wherein the field pointers would be set to areas in the buffer if - * need be. instring and buffer should be separate areas. - */ -/* ARGSUSED */ -static int -str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) -{ - if (lenstr + 1 > buflen) - return (NSS_STR_PARSE_ERANGE); - - /* skip entries that begin with '#' */ - if (instr[0] == '#') - return (NSS_STR_PARSE_PARSE); - - /* - * We copy the input string into the output buffer - */ - (void) memcpy(buffer, instr, lenstr); - buffer[lenstr] = '\0'; - - return (NSS_STR_PARSE_SUCCESS); -} -#endif /* NSS_SOLARIS */ - -int -setprinterentry(int stayopen, char *ns) -{ -#ifdef NSS_EMULATION - emul_setprinterentry(stayopen); -#elif NSS_SOLARIS - private_ns = ns; - nss_setent(&db_root, _nss_initf_printers, &context); - private_ns = NULL; -#endif - return (0); -} - - -int -endprinterentry(int i) -{ -#ifdef NSS_EMULATION - emul_endprinterentry(); -#elif NSS_SOLARIS - nss_endent(&db_root, _nss_initf_printers, &context); - nss_delete(&db_root); - private_ns = NULL; -#endif - return (0); -} - -/* ARGSUSED2 */ -papi_attribute_t ** -getprinterentry(char *ns) -{ - papi_attribute_t **result = NULL; - -#if defined(NSS_EMULATION) || defined(NSS_SOLARIS) - char buf[10240]; - nss_status_t res = NSS_NOTFOUND; - -#ifdef NSS_EMULATION - res = emul_getprinterentry_r(buf, sizeof (buf)); -#elif NSS_SOLARIS - nss_XbyY_args_t arg; - - private_ns = ns; - buf[0] = '\0'; - NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); - res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); - (void) NSS_XbyY_FINI(&arg); - private_ns = NULL; -#endif - - if (res != NSS_SUCCESS) - buf[0] = '\0'; - - result = _cvt_nss_entry_to_printer(buf); -#if defined(__sun) && defined(__SVR4) - solaris_lpsched_shortcircuit_hack(&result); -#endif -#ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC - fill_printer_uri(&result); -#endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ -#endif - -#ifdef DEBUG - printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); - if (result != NULL) { - char buf[4096]; - - papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); - printf("\t%s\n", buf); - } -#endif /* DEBUG */ - - return (result); -} - - -papi_attribute_t ** -getprinterbyname(char *name, char *ns) -{ - papi_attribute_t **result = NULL; - - if (strstr(name, "://") != NULL) { /* shortcut for URI form */ - papiAttributeListAddString(&result, PAPI_ATTR_APPEND, - "printer-name", name); - papiAttributeListAddString(&result, PAPI_ATTR_APPEND, - "printer-uri-supported", name); - } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ - char *uri = bsdaddr_to_uri(result, name); - - papiAttributeListAddString(&result, PAPI_ATTR_APPEND, - "printer-name", name); - if (uri != NULL) { - papiAttributeListAddString(&result, PAPI_ATTR_APPEND, - "printer-uri-supported", uri); - free(uri); - } - } else { /* anything else */ -#if defined(NSS_EMULATION) || defined(NSS_SOLARIS) - char buf[10240]; - nss_status_t res = NSS_NOTFOUND; - -#ifdef NSS_EMULATION - res = emul_getprinterbyname_r(name, buf, sizeof (buf)); -#elif NSS_SOLARIS - nss_XbyY_args_t arg; - - private_ns = ns; - NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); - arg.key.name = name; - res = nss_search(&db_root, _nss_initf_printers, - NSS_DBOP_PRINTERS_BYNAME, &arg); - (void) NSS_XbyY_FINI(&arg); - private_ns = NULL; - - if (res != NSS_SUCCESS) - buf[0] = '\0'; -#endif - - result = _cvt_nss_entry_to_printer(buf); -#endif - } -#if defined(__sun) && defined(__SVR4) - solaris_lpsched_shortcircuit_hack(&result); -#endif -#ifdef DEBUG - printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), - name, result); - if (result != NULL) { - char buf[4096]; - - papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); - printf("\t%s\n", buf); - } -#endif /* DEBUG */ - - return (result); -} diff --git a/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h b/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h deleted file mode 100644 index be28a9de0c..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/papi_impl.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _PAPI_IMPL_H -#define _PAPI_IMPL_H - -/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <papi.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include <time.h> -#include <sys/types.h> -#include <stdarg.h> -#include <uri.h> - -/* - * Implementation specific types/prototypes/definitions follow - * - * - * Ex: - */ - -typedef struct { - papi_attribute_t **attributes; - void *so_handle; - void *svc_handle; - char *name; - char *user; - char *password; - int (*authCB)(papi_service_t svc, void *app_data); - papi_encryption_t encryption; - void *app_data; - uri_t *uri; - int peer_fd; -} service_t; - -typedef struct job { - service_t *svc; - papi_job_t *job; -} job_t; - -typedef struct { - service_t *svc; - papi_printer_t *printer; - papi_attribute_t **attributes; - char svc_is_internal; -} printer_t; - -extern papi_status_t psm_open(service_t *svc, char *name); -extern void *psm_sym(service_t *svc, char *name); -extern void psm_close(void *handle); -extern void detailed_error(service_t *svc, char *fmt, ...); -extern papi_status_t service_connect(service_t *svc, char *uri); -extern papi_attribute_t **getprinterentry(char *ns); -extern papi_attribute_t **getprinterbyname(char *name, char *ns); -extern int setprinterentry(int stayopen, char *ns); -extern int endprinterentry(int stayopen); - - - -extern void list_remove(); - -#ifdef __cplusplus -} -#endif - -#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-dynamic/common/printer.c b/usr/src/lib/print/libpapi-dynamic/common/printer.c deleted file mode 100644 index e02a325ebd..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/printer.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <papi_impl.h> - -void -papiPrinterFree(papi_printer_t printer) -{ - printer_t *tmp = printer; - - if (tmp != NULL) { - void (*f)(); - - f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree"); - if (f != NULL) - f(tmp->printer); - if (tmp->attributes != NULL) - papiAttributeListFree(tmp->attributes); - if (tmp->svc_is_internal != 0) - papiServiceDestroy(tmp->svc); - free(tmp); - } -} - -void -papiPrinterListFree(papi_printer_t *printers) -{ - if (printers != NULL) { - int i; - - for (i = 0; printers[i] != NULL; i++) - papiPrinterFree(printers[i]); - free(printers); - } -} - -/* Enumerate a list of printers from the loaded print service. */ -static papi_status_t -printers_from_service(service_t *svc, char **requested_attrs, - papi_filter_t *filter, papi_printer_t **printers) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - papi_printer_t *svc_printers = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printers == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* connect to the service if we are not connected */ - if ((result = service_connect(svc, svc->name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList"); - if (f != NULL) - result = f(svc->svc_handle, requested_attrs, filter, - &svc_printers); - - /* - * copy the resulting printer object pointers into our own - * representation of a printer object because we need the - * service context to operate against the individual printer - * objects. We free the list now because we no longer need - * it and would have no way of freeing it later. - */ - if ((result == PAPI_OK) && (svc_printers != NULL)) { - int i; - - *printers = NULL; - for (i = 0; svc_printers[i] != NULL; i++) { - printer_t *p = NULL; - - if ((p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - p->svc = svc; - p->printer = svc_printers[i]; - list_append(printers, p); - } - free(svc_printers); - } - - return (result); -} - -/* Get printer attributes from it's print service */ -static papi_status_t -printer_from_service(service_t *svc, printer_t *p, char **requested_attrs) -{ - papi_status_t result; - papi_service_t p_svc = NULL; - papi_printer_t printer = NULL; - char *psm = NULL; - char *uri = NULL; - - /* get the psm and uri from the attributes */ - papiAttributeListGetString(p->attributes, NULL, - "print-service-module", &psm); - papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri); - papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported", - &uri); - - /* contact the service for the printer */ - result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user, - svc->password, svc->authCB, svc->encryption, - svc->app_data); - if (result != PAPI_OK) - return (result); - - /* get the printer from the service */ - result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer); - if (result == PAPI_OK) { - papi_attribute_t **attributes; - - attributes = papiPrinterGetAttributeList(printer); - copy_attributes(&p->attributes, attributes); - } - papiPrinterFree(printer); - papiServiceDestroy(p_svc); - - return (result); -} - -/* are the requested attributes contained in the list */ -static int -contained(char **requested, papi_attribute_t **list) -{ - int i; - - if (requested == NULL) /* we want every possible attribute */ - return (0); - - for (i = 0; requested[i] != NULL; i++) - if (papiAttributeListFind(list, requested[i]) == NULL) - return (0); - - return (1); -} - -/* Enumerate a list of printers from the Name Service */ -static papi_status_t -printers_from_name_service(service_t *svc, char **requested_attrs, - papi_filter_t *filter, papi_printer_t **printers) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - papi_attribute_t **attrs; - - if ((svc == NULL) || (printers == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* retrieve printers from the nameservice */ - setprinterentry(0, NULL); - while ((attrs = getprinterentry(NULL)) != NULL) { - printer_t *p = NULL; - - if ((p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - p->attributes = attrs; - list_append(printers, p); - } - - /* if we have printers, check if our request has been satisfied */ - if ((printers != NULL) && (*printers != NULL)) { - int i; - - /* walk through the list */ - for (i = 0; (*printers)[i] != NULL; i++) { - printer_t *p = (*printers)[i]; - - /* see if the name service satisfied the request */ - if (contained(requested_attrs, p->attributes) == 0) - printer_from_service(svc, p, requested_attrs); - } - } - - return (PAPI_OK); -} - -papi_status_t -papiPrintersList(papi_service_t handle, char **requested_attrs, - papi_filter_t *filter, papi_printer_t **printers) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_printer_t *svc_printers = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (printers == NULL)) - return (PAPI_BAD_ARGUMENT); - - if (svc->so_handle != NULL) /* connected, use the print svc */ - result = printers_from_service(svc, requested_attrs, - filter, printers); - else /* not connected, use the name svc */ - result = printers_from_name_service(svc, requested_attrs, - filter, printers); - - return (result); -} - -papi_status_t -papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, - papi_attribute_t **job_attributes, papi_printer_t *printer) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - printer_t *p = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - if ((*printer = p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - if ((svc->name != NULL) && (svc->svc_handle != NULL) && - (svc->uri != NULL)) { - p->svc = svc; - f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, requested_attrs, - job_attributes, &p->printer); - } else { - setprinterentry(0, NULL); - p->attributes = getprinterbyname(name, NULL); - if (p->attributes == NULL) - result = PAPI_NOT_FOUND; - else - result = PAPI_OK; - } - - return (result); -} - -static papi_status_t -_papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message, - char *function) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, function); - if (f != NULL) - result = f(svc->svc_handle, svc->name, message); - - return (result); -} - -static papi_status_t -_papi_printer_enable_or_resume(papi_service_t handle, char *name, - char *function) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, function); - if (f != NULL) - result = f(svc->svc_handle, svc->name); - - return (result); -} - -papi_status_t -papiPrinterDisable(papi_service_t handle, char *name, char *message) -{ - return (_papi_printer_disable_or_pause(handle, name, message, - "papiPrinterDisable")); -} - -papi_status_t -papiPrinterPause(papi_service_t handle, char *name, char *message) -{ - return (_papi_printer_disable_or_pause(handle, name, message, - "papiPrinterPause")); -} - -papi_status_t -papiPrinterEnable(papi_service_t handle, char *name) -{ - return (_papi_printer_enable_or_resume(handle, name, - "papiPrinterEnable")); -} - -papi_status_t -papiPrinterResume(papi_service_t handle, char *name) -{ - return (_papi_printer_enable_or_resume(handle, name, - "papiPrinterResume")); -} - -static papi_status_t -_papi_printer_add_or_modify(papi_service_t handle, char *name, - papi_attribute_t **attributes, papi_printer_t *printer, - char *function) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - printer_t *p = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL) || (attributes == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - if ((*printer = p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - p->svc = svc; - f = (papi_status_t (*)())psm_sym(p->svc, function); - if (f != NULL) - result = f(svc->svc_handle, svc->name, attributes, - &p->printer); - - return (result); -} - -papi_status_t -papiPrinterAdd(papi_service_t handle, char *name, - papi_attribute_t **attributes, papi_printer_t *printer) -{ - return (_papi_printer_add_or_modify(handle, name, attributes, printer, - "papiPrinterAdd")); -} - -papi_status_t -papiPrinterModify(papi_service_t handle, char *name, - papi_attribute_t **attributes, papi_printer_t *printer) -{ - return (_papi_printer_add_or_modify(handle, name, attributes, printer, - "papiPrinterModify")); -} - - -papi_status_t -papiPrinterRemove(papi_service_t handle, char *name) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove"); - if (f != NULL) - result = f(svc->svc_handle, svc->name); - - return (result); -} - -papi_status_t -papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_job_t *svc_jobs = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, &svc_jobs); - - /* - * copy the resulting job object pointers into our own - * representation of a job object because we need the - * service context to operate against the individual job - * objects. We free the list now because we no longer need - * it and would have no way of freeing it later. - */ - if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) { - int i; - - *jobs = NULL; - for (i = 0; svc_jobs[i] != NULL; i++) { - job_t *j = NULL; - - if ((j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - j->job = svc_jobs[i]; - list_append(jobs, j); - } - free(svc_jobs); - } - - return (result); -} - -papi_status_t -papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, - int type_mask, int max_num_jobs, papi_job_t **jobs) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_job_t *svc_jobs = NULL; - papi_status_t (*f)(); - - if ((svc == NULL) || (name == NULL) || (jobs == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs"); - if (f != NULL) - result = f(svc->svc_handle, svc->name, requested_attrs, - type_mask, max_num_jobs, &svc_jobs); - - /* - * copy the resulting job object pointers into our own - * representation of a job object because we need the - * service context to operate against the individual job - * objects. We free the list now because we no longer need - * it and would have no way of freeing it later. - */ - if ((result == PAPI_OK) && (svc_jobs != NULL)) { - int i; - - *jobs = NULL; - for (i = 0; svc_jobs[i] != NULL; i++) { - job_t *j = NULL; - - if ((j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - j->svc = svc; - j->job = svc_jobs[i]; - list_append(jobs, j); - } - free(svc_jobs); - } - - return (result); -} - -papi_attribute_t ** -papiPrinterGetAttributeList(papi_printer_t printer) -{ - papi_attribute_t **result = NULL; - printer_t *p = printer; - - if ((p != NULL) && (p->printer != NULL)) { - papi_attribute_t **(*f)(); - - f = (papi_attribute_t **(*)())psm_sym(p->svc, - "papiPrinterGetAttributeList"); - if (f != NULL) - result = f(p->printer); - } else - result = p->attributes; - - return (result); -} diff --git a/usr/src/lib/print/libpapi-dynamic/common/psm.c b/usr/src/lib/print/libpapi-dynamic/common/psm.c deleted file mode 100644 index af31f24b4e..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/psm.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: psm.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <dlfcn.h> -#include <papi_impl.h> - -#ifndef RTLD_GROUP -#define RTLD_GROUP 0 -#endif /* RTLD_GROUP */ - -#ifndef PSM_DIR -#define PSM_DIR "/usr/lib/print" -#endif - -papi_status_t -psm_open(service_t *svc, char *scheme) -{ - papi_status_t result = PAPI_OK; - char path[BUFSIZ]; - - if ((scheme == NULL) || (strchr(scheme, '/') != NULL)) - return (PAPI_BAD_ARGUMENT); - - snprintf(path, sizeof (path), PSM_DIR "/psm-%s.so", scheme); - - svc->so_handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_GROUP); - if (svc->so_handle == NULL) { /* failed, set the result/message */ - if ((access(path, F_OK) < 0) && (errno == ENOENT)) - result = PAPI_URI_SCHEME; - else - result = PAPI_NOT_POSSIBLE; -#ifdef DEBUG - detailed_error(svc, "psm_open(%s): %s: %s", scheme, path, - dlerror()); -#endif - } - - return (result); -} - -void -psm_close(void *handle) -{ - dlclose(handle); -} - -void * -psm_sym(service_t *svc, char *name) -{ - char *error = "invalid input"; - void *func = NULL; - - if ((svc != NULL) && (svc->so_handle != NULL) && (name != NULL)) { - if ((func = dlsym(svc->so_handle, name)) == NULL) - error = dlerror(); - } -#ifdef DEBUG - if (func == NULL) - detailed_error(svc, "psm_sym(%s): %s", name, error); -#endif - - return (func); -} diff --git a/usr/src/lib/print/libpapi-dynamic/common/service.c b/usr/src/lib/print/libpapi-dynamic/common/service.c deleted file mode 100644 index 55f1732a65..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/common/service.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: service.c 172 2006-05-24 20:54:00Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <sys/types.h> -#include <unistd.h> -#include <string.h> -#include <alloca.h> -#include <libintl.h> -#include <papi_impl.h> -#include <config-site.h> - -static int -interposed_auth_callback(papi_service_t handle, void *app_data) -{ - int result = -1; - service_t *svc = app_data; - - if (svc != NULL) - result = svc->authCB(svc, svc->app_data); - - return (result); -} - -static char * -default_service_uri(char *fallback) -{ - char *result = NULL; - - if (getuid() == geteuid()) - result = getenv("PAPI_SERVICE_URI"); - - if (result == NULL) { - char *cups; - - if ((cups = getenv("CUPS_SERVER")) != NULL) { - char buf[BUFSIZ]; - - snprintf(buf, sizeof (buf), "ipp://%s/printers/", cups); - result = strdup(buf); - } - } - - if (result == NULL) - result = fallback; - - return (result); -} - -static char * -default_print_service() -{ - static char *result = NULL; - - if (result == NULL) { - char *service_uri = default_service_uri(DEFAULT_SERVICE_URI); - uri_t *uri = NULL; - - if (uri_from_string(service_uri, &uri) != -1) - result = strdup(uri->scheme); - - if (uri != NULL) - uri_free(uri); - } - - return (result); -} - -static papi_status_t -service_load(service_t *svc, char *name) -{ - papi_status_t result; - char *scheme = default_print_service(); - - if (svc->so_handle != NULL) /* already loaded */ - return (PAPI_OK); - - if (name == NULL) /* no info, can't load yet */ - return (PAPI_OK); - - /* Lookup the printer in the configuration DB */ - svc->attributes = getprinterbyname((char *)name, NULL); - - if (svc->attributes != NULL) { - char *tmp = NULL; - - /* Printer found (or was a URI), use the attribute data */ - papiAttributeListGetString(svc->attributes, NULL, - "printer-uri-supported", &tmp); - if (tmp != NULL) - svc->name = strdup(tmp); - - /* parse the URI and set the scheme(print service) */ - if (uri_from_string(svc->name, &svc->uri) != -1) - scheme = (svc->uri)->scheme; - - /* override the scheme if it was in the attributes */ - papiAttributeListGetString(svc->attributes, NULL, - "print-service-module", &scheme); - - } else /* not found, assume it is the actual print service name */ - scheme = name; - - result = psm_open(svc, scheme); - switch (result) { - case PAPI_OK: - break; /* no error */ - case PAPI_URI_SCHEME: - result = PAPI_NOT_FOUND; -#ifdef DEBUG - detailed_error(svc, "Unable to load service for: %s", name); -#endif - break; - default: /* set the detailed message */ - detailed_error(svc, "Unable to load service (%s) for: %s", - scheme, name); - } - - return (result); -} - -static papi_status_t -service_send_peer(service_t *svc) -{ - papi_status_t result = PAPI_OK; - - if ((svc->peer_fd != -1) && (svc->so_handle != NULL) && - (svc->svc_handle != NULL)) { - papi_status_t (*f)(); - - f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPeer"); - - if (f != NULL) - result = f(svc->svc_handle, svc->peer_fd); - } - - return (result); -} - -papi_status_t -service_connect(service_t *svc, char *name) -{ - papi_status_t result = PAPI_NOT_POSSIBLE; - - /* if there is no print service module loaded, try and load one. */ - if (svc->so_handle == NULL) - result = service_load(svc, name); - else if ((svc->name == NULL) && (name != NULL)) - svc->name = strdup(name); - - /* - * the print service module is loaded, but we don't have a service - * handle. - */ - if (svc->so_handle != NULL) { - papi_status_t (*f)(); - - if (svc->svc_handle != NULL) /* already connected? */ - return (PAPI_OK); - - f = (papi_status_t (*)())psm_sym(svc, "papiServiceCreate"); - - if (f != NULL) { - char *user = svc->user; - char *password = svc->password; - - /* if no API user, try the URI user */ - if ((user == NULL) && (svc->uri != NULL)) - user = (svc->uri)->user; - /* if no API password, try the URI password */ - if ((password == NULL) && (svc->uri != NULL)) - password = (svc->uri)->password; - - result = f(&svc->svc_handle, svc->name, user, password, - (svc->authCB ? interposed_auth_callback - : NULL), - svc->encryption, svc); - (void) service_send_peer(svc); - } - } - - return (result); -} - -papi_status_t -papiServiceCreate(papi_service_t *handle, char *service_name, char *user_name, - char *password, - int (*authCB)(papi_service_t svc, void *app_data), - papi_encryption_t encryption, void *app_data) -{ - papi_status_t result = PAPI_NOT_POSSIBLE; - service_t *svc = NULL; - uri_t *u = NULL; - - if (handle == NULL) - return (PAPI_BAD_ARGUMENT); - - if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - svc->peer_fd = -1; - - if (user_name != NULL) - svc->user = strdup(user_name); - - if (password != NULL) - svc->password = strdup(password); - - svc->encryption = encryption; - - if (authCB != NULL) - svc->authCB = authCB; - - if (app_data != NULL) - svc->app_data = app_data; - - /* If not specified, get a "default" service from the environment */ - if (service_name == NULL) - service_name = default_service_uri(NULL); - - if (service_name != NULL) { - result = service_load(svc, service_name); - /* if the psm loaded and the svc contains a URI, connect */ - if ((result == PAPI_OK) && (svc->uri != NULL)) - result = service_connect(svc, service_name); - } else - result = PAPI_OK; - - return (result); -} - -void -papiServiceDestroy(papi_service_t handle) -{ - if (handle != NULL) { - service_t *svc = handle; - - if (svc->so_handle != NULL) { - if (svc->svc_handle != NULL) { - void (*f)(); - - f = (void (*)())psm_sym(svc, - "papiServiceDestroy"); - f(svc->svc_handle); - } - psm_close(svc->so_handle); - } - if (svc->attributes != NULL) - papiAttributeListFree(svc->attributes); - if (svc->name != NULL) - free(svc->name); - if (svc->user != NULL) - free(svc->user); - if (svc->password != NULL) - free(svc->password); - if (svc->uri != NULL) - uri_free(svc->uri); - - free(handle); - } -} - -papi_status_t -papiServiceSetPeer(papi_service_t handle, int fd) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - svc->peer_fd = fd; - result = service_send_peer(svc); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetUserName(papi_service_t handle, char *user_name) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - papi_status_t (*f)(); - - if (svc->user != NULL) - free(svc->user); - if (user_name != NULL) - svc->user = strdup(user_name); - f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetUserName"); - if (f != NULL) - result = f(svc->svc_handle, user_name); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetPassword(papi_service_t handle, char *password) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - papi_status_t (*f)(); - - if (svc->password != NULL) - free(svc->password); - if (password != NULL) - svc->password = strdup(password); - f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetPassword"); - if (f != NULL) - result = f(svc->svc_handle, password); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetEncryption(papi_service_t handle, papi_encryption_t encryption) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - papi_status_t (*f)(); - - svc->encryption = encryption; - f = (papi_status_t (*)())psm_sym(svc, - "papiServiceSetEncryption"); - if (f != NULL) - result = f(svc->svc_handle, encryption); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetAuthCB(papi_service_t handle, - int (*authCB)(papi_service_t svc, void *app_data)) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - papi_status_t (*f)(); - - svc->authCB = authCB; - f = (papi_status_t (*)())psm_sym(svc, "papiServiceSetAuthCB"); - if (f != NULL) - result = f(svc->svc_handle, interposed_auth_callback); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - - -papi_status_t -papiServiceSetAppData(papi_service_t handle, void *app_data) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - papi_status_t (*f)(); - - svc->app_data = (void *)app_data; - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -char * -papiServiceGetServiceName(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - char *(*f)(); - - f = (char *(*)())psm_sym(svc, "papiServiceGetServiceName"); - if (f != NULL) - result = f(svc->svc_handle); - if (result == NULL) - result = svc->name; - } - - return (result); -} - -char * -papiServiceGetUserName(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - char *(*f)(); - - f = (char *(*)())psm_sym(svc, "papiServiceGetUserName"); - if (f != NULL) - result = f(svc->svc_handle); - if (result == NULL) - result = svc->user; - } - - return (result); -} - -char * -papiServiceGetPassword(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - char *(*f)(); - - f = (char *(*)())psm_sym(svc, "papiServiceGetPassword"); - if (f != NULL) - result = f(svc->svc_handle); - if (result == NULL) - result = svc->password; - } - - return (result); -} - -papi_encryption_t -papiServiceGetEncryption(papi_service_t handle) -{ - papi_encryption_t result = PAPI_ENCRYPT_NEVER; - - if (handle != NULL) { - service_t *svc = handle; - papi_encryption_t (*f)(); - - f = (papi_encryption_t (*)())psm_sym(svc, - "papiServiceGetEncryption"); - if (f != NULL) - result = f(svc->svc_handle); - if (result == PAPI_ENCRYPT_NEVER) - result = svc->encryption; - } - - return (result); -} - -void * -papiServiceGetAppData(papi_service_t handle) -{ - void *result = NULL; - service_t *svc = handle; - - if (handle != NULL) - result = svc->app_data; - - return (result); -} - -papi_attribute_t ** -papiServiceGetAttributeList(papi_service_t handle) -{ - papi_attribute_t **result = NULL; - service_t *svc = handle; - - if (handle != NULL) { - papi_attribute_t **(*f)(); - - if (svc->so_handle == NULL) { - char *uri = default_service_uri(DEFAULT_SERVICE_URI); - - if (service_connect(svc, uri) != PAPI_OK) - return (NULL); - } - - f = (papi_attribute_t **(*)())psm_sym(svc, - "papiServiceGetAttributeList"); - if (f != NULL) - result = f(svc->svc_handle); - } else - result = svc->attributes; - - return (result); -} - -char * -papiServiceGetStatusMessage(papi_service_t handle) -{ - char *result = NULL; - service_t *svc = handle; - - if (handle != NULL) { - char *(*f)(); - - f = (char *(*)())psm_sym(svc, "papiServiceGetStatusMessage"); - if (f != NULL) - result = f(svc->svc_handle); - } - if (result == NULL) { - papiAttributeListGetString(svc->attributes, NULL, - "detailed-status-message", &result); - } - - return (result); -} - -void -detailed_error(service_t *svc, char *fmt, ...) -{ - if ((svc != NULL) && (fmt != NULL)) { - va_list ap; - size_t size; - char *message = alloca(BUFSIZ); - - va_start(ap, fmt); - /* - * fill in the message. If the buffer is too small, allocate - * one that is large enough and fill it in. - */ - if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) - if ((message = alloca(size)) != NULL) - vsnprintf(message, size, fmt, ap); - va_end(ap); - - papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, - "detailed-status-message", message); -#ifdef DEBUG - fprintf(stderr, "detailed_error(%s)\n", message); -#endif - } -} diff --git a/usr/src/lib/print/libpapi-dynamic/i386/Makefile b/usr/src/lib/print/libpapi-dynamic/i386/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-dynamic/sparc/Makefile b/usr/src/lib/print/libpapi-dynamic/sparc/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libpapi-dynamic/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libpapi-ipp/Makefile b/usr/src/lib/print/libpapi-ipp/Makefile deleted file mode 100644 index b92d620b10..0000000000 --- a/usr/src/lib/print/libpapi-ipp/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) - -install_h: # $(ROOTHDRS) - -check: # $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-ipp/Makefile.com b/usr/src/lib/print/libpapi-ipp/Makefile.com deleted file mode 100644 index f5abebce00..0000000000 --- a/usr/src/lib/print/libpapi-ipp/Makefile.com +++ /dev/null @@ -1,71 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = psm-ipp.a -VERS = .1 -OBJECTS = ipp-support.o job.o printer.o service.o -ROOTLIBDIR = $(ROOT)/usr/lib/print - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib/print -ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) - -EXTRALINKS= $(ROOTLIBDIR)/psm-http.so -$(EXTRALINKS): $(ROOTLINKS) - $(RM) $@; $(SYMLINK) $(LIBLINKS) $@ - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common -CPPFLAGS += -I../../libipp-core/common -CPPFLAGS += -I../../libhttp-core/common - -CERRWARN += -_gcc=-Wno-type-limits -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-uninitialized - -MAPFILES = $(SRCDIR)/mapfile - -LDLIBS += -L$(ROOTLIBDIR) -R/usr/lib/print -lhttp-core -lmd5 -LDLIBS += -lipp-core -lc - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -$(ROOTLIBDIR): - $(INS.dir) - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-ipp/common/ipp-support.c b/usr/src/lib/print/libpapi-ipp/common/ipp-support.c deleted file mode 100644 index b2caff84ac..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/ipp-support.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: ipp-support.c 148 2006-04-25 16:54:17Z njacobs $ */ - - -#include <papi_impl.h> -#include <stdlib.h> -#include <pwd.h> -#include <locale.h> -#include <errno.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <md5.h> - -#include <config-site.h> - -#include <ipp.h> - -static void ipp_add_printer_uri(service_t *svc, char *name, - papi_attribute_t ***op); - -papi_status_t -http_to_papi_status(http_status_t status) -{ - switch (status) { - case HTTP_OK: - return (PAPI_OK); - case HTTP_BAD_REQUEST: - return (PAPI_BAD_REQUEST); - case HTTP_UNAUTHORIZED: - case HTTP_FORBIDDEN: - return (PAPI_NOT_AUTHORIZED); - case HTTP_NOT_FOUND: - return (PAPI_NOT_FOUND); - case HTTP_GONE: - return (PAPI_GONE); - case HTTP_SERVICE_UNAVAILABLE: - return (PAPI_SERVICE_UNAVAILABLE); - default: - return ((papi_status_t)status); - } -} - -papi_status_t -ipp_to_papi_status(uint16_t status) -{ - switch (status) { - case IPP_OK: - return (PAPI_OK); - case IPP_OK_IGNORED_ATTRIBUTES: - return (PAPI_OK); - case IPP_OK_CONFLICTING_ATTRIBUTES: - return (PAPI_OK); - case IPP_OK_IGNORED_SUBSCRIPTIONS: - return (PAPI_OK_IGNORED_SUBSCRIPTIONS); - case IPP_OK_IGNORED_NOTIFICATIONS: - return (PAPI_OK_IGNORED_NOTIFICATIONS); - case IPP_CERR_BAD_REQUEST: - return (PAPI_BAD_REQUEST); - case IPP_CERR_FORBIDDEN: - return (PAPI_FORBIDDEN); - case IPP_CERR_NOT_AUTHENTICATED: - return (PAPI_NOT_AUTHENTICATED); - case IPP_CERR_NOT_AUTHORIZED: - return (PAPI_NOT_AUTHORIZED); - case IPP_CERR_NOT_POSSIBLE: - return (PAPI_NOT_POSSIBLE); - case IPP_CERR_TIMEOUT: - return (PAPI_TIMEOUT); - case IPP_CERR_NOT_FOUND: - return (PAPI_NOT_FOUND); - case IPP_CERR_GONE: - return (PAPI_GONE); - case IPP_CERR_REQUEST_ENTITY: - return (PAPI_REQUEST_ENTITY); - case IPP_CERR_REQUEST_VALUE: - return (PAPI_REQUEST_VALUE); - case IPP_CERR_DOCUMENT_FORMAT: - return (PAPI_DOCUMENT_FORMAT); - case IPP_CERR_ATTRIBUTES: - return (PAPI_ATTRIBUTES); - case IPP_CERR_URI_SCHEME: - return (PAPI_URI_SCHEME); - case IPP_CERR_CHARSET: - return (PAPI_CHARSET); - case IPP_CERR_CONFLICT: - return (PAPI_CONFLICT); - case IPP_CERR_COMPRESSION_NOT_SUPPORTED: - return (PAPI_COMPRESSION_NOT_SUPPORTED); - case IPP_CERR_COMPRESSION_ERROR: - return (PAPI_COMPRESSION_ERROR); - case IPP_CERR_DOCUMENT_FORMAT_ERROR: - return (PAPI_DOCUMENT_FORMAT_ERROR); - case IPP_CERR_DOCUMENT_ACCESS_ERROR: - return (PAPI_DOCUMENT_ACCESS_ERROR); - case IPP_CERR_ATTRIBUTES_NOT_SETTABLE: - return (PAPI_ATTRIBUTES_NOT_SETTABLE); - case IPP_CERR_IGNORED_ALL_SUBSCRIPTIONS: - return (PAPI_IGNORED_ALL_SUBSCRIPTIONS); - case IPP_CERR_TOO_MANY_SUBSCRIPTIONS: - return (PAPI_TOO_MANY_SUBSCRIPTIONS); - case IPP_CERR_IGNORED_ALL_NOTIFICATIONS: - return (PAPI_IGNORED_ALL_NOTIFICATIONS); - case IPP_CERR_PRINT_SUPPORT_FILE_NOT_FOUND: - return (PAPI_PRINT_SUPPORT_FILE_NOT_FOUND); - case IPP_SERR_INTERNAL: - return (PAPI_INTERNAL_ERROR); - case IPP_SERR_OPERATION_NOT_SUPPORTED: - return (PAPI_OPERATION_NOT_SUPPORTED); - case IPP_SERR_SERVICE_UNAVAILABLE: - return (PAPI_SERVICE_UNAVAILABLE); - case IPP_SERR_VERSION_NOT_SUPPORTED: - return (PAPI_VERSION_NOT_SUPPORTED); - case IPP_SERR_DEVICE_ERROR: - return (PAPI_DEVICE_ERROR); - case IPP_SERR_TEMPORARY_ERROR: - return (PAPI_TEMPORARY_ERROR); - case IPP_SERR_NOT_ACCEPTING: - return (PAPI_NOT_ACCEPTING); - case IPP_SERR_BUSY: - case IPP_SERR_CANCELLED: - default: - return (PAPI_TEMPORARY_ERROR); - } -} - -void -ipp_initialize_request(service_t *svc, papi_attribute_t ***request, - uint16_t operation) -{ - papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, - "version-major", 1); - papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, - "version-minor", 1); - papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, - "request-id", (short)lrand48()); - papiAttributeListAddInteger(request, PAPI_ATTR_EXCL, - "operation-id", operation); -} - -void -ipp_initialize_operational_attributes(service_t *svc, papi_attribute_t ***op, - char *printer, int job_id) -{ - char *charset = "utf-8"; /* default to UTF-8 encoding */ - char *language = setlocale(LC_ALL, ""); - char *user = "nobody"; - struct passwd *pw = NULL; - - /* - * All IPP requests must contain the following: - * attributes-charset (UTF-8) - * attributes-natural-language (our current locale) - * (object identifier) printer-uri/job-id or job-uri - * requesting-user-name (process user or none) - */ - papiAttributeListAddString(op, PAPI_ATTR_EXCL, - "attributes-charset", charset); - - papiAttributeListAddString(op, PAPI_ATTR_EXCL, - "attributes-natural-language", language); - - if (printer != NULL) - ipp_add_printer_uri(svc, printer, op); - - if ((printer != NULL) && (job_id >= 0)) - papiAttributeListAddInteger(op, PAPI_ATTR_EXCL, - "job-id", job_id); - - if ((pw = getpwuid(getuid())) != NULL) - user = pw->pw_name; - /* - * if our euid is 0 "super user", we will allow the system supplied - * user name to be overridden, if the requestor wants to. - */ - if (geteuid() == 0) { - if (svc->user != NULL) - user = svc->user; - } - papiAttributeListAddString(op, PAPI_ATTR_REPLACE, - "requesting-user-name", user); -} - -#ifndef OPID_CUPS_GET_DEFAULT /* for servers that will enumerate */ -#define OPID_CUPS_GET_DEFAULT 0x4001 -#endif /* OPID_CUPS_GET_DEFAULT */ - -static papi_status_t -_default_destination(service_t *svc, char **uri) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - printer_t *p = NULL; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - char *tmp = NULL; - - if ((svc == NULL) || (uri == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* we must be connected to find the default destination */ - if (svc->connection == NULL) - return (PAPI_NOT_POSSIBLE); - - if ((p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - ipp_initialize_request(svc, &request, OPID_CUPS_GET_DEFAULT); - ipp_initialize_operational_attributes(svc, &op, NULL, -1); - papiAttributeListAddString(&op, PAPI_ATTR_APPEND, - "requested-attributes", "printer-uri-supported"); - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - papiAttributeListGetCollection(response, NULL, - "printer-attributes-group", &op); - - if (uri != NULL) { - char *tmp = NULL; - - papiAttributeListGetString(op, NULL, "printer-uri", &tmp); - papiAttributeListGetString(op, NULL, - "printer-uri-supported", &tmp); - if (tmp != NULL) - *uri = strdup(tmp); - } - - papiAttributeListFree(response); - - return (result); -} - -static void -ipp_add_printer_uri(service_t *svc, char *name, papi_attribute_t ***op) -{ - char *uri = name; - char buf[BUFSIZ]; - uri_t *tmp = NULL; - - if (strstr(name, "://") == NULL) { /* not in URI form */ - if (strcmp(name, DEFAULT_DEST) != 0) { - /* not the "default" */ - snprintf(buf, sizeof (buf), "%s/%s", svc->name, name); - uri = buf; - } else - _default_destination(svc, &uri); - } - - papiAttributeListAddString(op, PAPI_ATTR_EXCL, "printer-uri", uri); - - /* save the printer-uri's path to be used by http POST request */ - if ((uri_from_string(uri, &tmp) == 0) && (tmp != NULL)) { - if (svc->post != NULL) - free(svc->post); - svc->post = strdup(tmp->path); - uri_free(tmp); - } -} - - -/* - * don't actually write anything, just add to the total size and return the - * size of what would be written, so we can figure out how big the request - * is going to be. - */ -static ssize_t -size_calculate(void *fd, void *buffer, size_t length) -{ - ssize_t *size = (ssize_t *)fd; - - *size += length; - return (length); -} - - -static ssize_t -build_chunk(void *fd, void *buffer, size_t length) -{ - char **s1 = fd; - - memcpy(*s1, buffer, length); - *s1 = *s1 + length; - - return (length); -} - -ssize_t -ipp_request_write(void *fd, void *buffer, size_t length) -{ - service_t *svc = (service_t *)fd; - -#ifdef DEBUG - printf("ipp_request_write(0x%8.8x, 0x%8.8x, %d)\n", fd, buffer, length); - httpDumpData(stdout, "ipp_request_write:", buffer, length); -#endif - return (httpWrite(svc->connection, buffer, length)); -} - -ssize_t -ipp_request_read(void *fd, void *buffer, size_t length) -{ - service_t *svc = (service_t *)fd; - ssize_t rc, i = length; - char *p = buffer; - - while ((rc = httpRead(svc->connection, p, i)) != i) { - if (rc == 0) - return (rc); - if (rc < 0) - return (rc); - i -= rc; - p += rc; - } -#ifdef DEBUG - printf("ipp_request_read(0x%8.8x, 0x%8.8x, %d) = %d\n", - fd, buffer, length, rc); - httpDumpData(stdout, "ipp_request_read:", buffer, length); -#endif - - return (length); -} - -papi_status_t -ipp_send_initial_request_block(service_t *svc, papi_attribute_t **request, - ssize_t file_size) -{ - papi_status_t result = PAPI_OK; - ssize_t chunk_size = 0; - char length[32]; - void *chunk, *ptr; - http_status_t status; - - /* calculate the request size */ - (void) ipp_write_message(&size_calculate, &chunk_size, request); - - /* Fill in the HTTP Header information */ - httpClearFields(svc->connection); - if (svc->transfer_encoding == TRANSFER_ENCODING_CHUNKED) - httpSetField(svc->connection, HTTP_FIELD_TRANSFER_ENCODING, - "chunked"); - else { - sprintf(length, "%lu", (unsigned long)(file_size + chunk_size)); - httpSetField(svc->connection, HTTP_FIELD_CONTENT_LENGTH, - length); - } - httpSetField(svc->connection, HTTP_FIELD_CONTENT_TYPE, - "application/ipp"); - httpSetField(svc->connection, HTTP_FIELD_AUTHORIZATION, - svc->connection->authstring); - - /* flush any state information about this connection */ - httpFlush(svc->connection); - - /* if we have don't have a POST path, use the service uri path */ - if ((svc->post == NULL) && (svc->uri->path)) - svc->post = strdup(svc->uri->path); - /* send the HTTP POST message for the IPP request */ - /* if the POST fails, return the error */ - status = httpPost(svc->connection, svc->post); - if (status != 0) - return (http_to_papi_status(status)); - - if (httpCheck(svc->connection) != 0) { - status = httpUpdate(svc->connection); - if (status != HTTP_OK) - return (http_to_papi_status(status)); - } - - /* build the request chunk */ - chunk = ptr = calloc(1, chunk_size); - result = ipp_write_message(&build_chunk, &ptr, request); -#ifdef DEBUG - printf("request: %d (0x%x) bytes\n", chunk_size, chunk_size); - httpDumpData(stdout, "request:", chunk, chunk_size); -#endif - - /* send the actual IPP request */ - if (ipp_request_write(svc, chunk, chunk_size) != chunk_size) - result = PAPI_TEMPORARY_ERROR; - free(chunk); - - if (httpCheck(svc->connection) != 0) { - status = httpUpdate(svc->connection); - if (status != HTTP_OK) - return (http_to_papi_status(status)); - } - - return (result); -} - -static int -setAuthString(service_t *svc) -{ - http_t *http; - char *user, *passphrase; - char encoded[BUFSIZ]; - - if ((svc == NULL) || (svc->connection == NULL) || (svc->name == NULL)) - return (-1); - - http = svc->connection; - - if (svc->user == NULL) { - struct passwd *p; - - if ((p = getpwuid(getuid())) != NULL) { - user = p->pw_name; - } else if ((user = getenv("LOGNAME")) == NULL) - user = getenv("USER"); - if (user == NULL) - user = "nobody"; - } else - user = svc->user; - - /* if the passphrase is not set, use the Authentication Callback */ - if (((svc->password == NULL) || (svc->password[0] == '\0')) && - (svc->authCB != NULL)) - (svc->authCB)(svc, svc->app_data); - passphrase = svc->password; - - /* if there is still no passphrase, we have to fail */ - if ((passphrase == NULL) || (passphrase[0] == '\0')) - return (-1); - - if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], - "Basic", 5) == 0) { - char plain[BUFSIZ]; - - snprintf(plain, sizeof (plain), "%s:%s", user, passphrase); - httpEncode64(encoded, plain); - snprintf(http->authstring, sizeof (http->authstring), - "Basic %s", encoded); - } else if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], - "Digest", 6) == 0) { - char realm[HTTP_MAX_VALUE]; - char nonce[HTTP_MAX_VALUE]; - char line [BUFSIZ]; - char urp[128]; - char mr[128]; - char *uri = svc->post; - - httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, - "realm", realm); - httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, - "nonce", nonce); - - snprintf(line, sizeof (line), "%s:%s:%s", user, realm, - passphrase); - md5_calc(urp, line, strlen(line)); - - snprintf(line, sizeof (line), "POST:%s", uri); - md5_calc(mr, line, strlen(line)); - - snprintf(line, sizeof (line), "%s:%s:%s", urp, mr, nonce); - md5_calc(encoded, line, strlen(line)); - - snprintf(http->authstring, sizeof (http->authstring), - "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", " - "uri=\"%s\", response=\"%s\"", user, realm, nonce, uri, - encoded); - } - - return (0); -} - -papi_status_t -ipp_status_info(service_t *svc, papi_attribute_t **response) -{ - papi_attribute_t **operational = NULL; - int32_t status = 0; - - papiAttributeListGetCollection(response, NULL, - "operational-attributes-group", &operational); - if (operational != NULL) { - char *message = NULL; - - papiAttributeListGetString(response, NULL, - "status-message", &message); - papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE, - "detailed-status-message", message); - } - papiAttributeListGetInteger(response, NULL, "status-code", &status); - - return (ipp_to_papi_status(status)); -} - -papi_status_t -ipp_send_request_with_file(service_t *svc, papi_attribute_t **request, - papi_attribute_t ***response, char *file) -{ - papi_status_t result = PAPI_OK; - ssize_t size = 0; - struct stat statbuf; - int fd; - -#ifdef DEBUG - fprintf(stderr, "\nIPP-REQUEST: (%s)", (file ? file : "")); - papiAttributeListPrint(stderr, request, " "); - putc('\n', stderr); - fflush(stderr); -#endif - - /* - * if we are sending a file, open it and include it's size in the - * message size. - */ - if (file != NULL) { - if ((fd = open(file, O_RDONLY)) < 0) { - detailed_error(svc, "%s: %s", file, strerror(errno)); - return (PAPI_DOCUMENT_ACCESS_ERROR); - } else if (strcmp("standard input", file) != 0) { - if (stat(file, &statbuf) < 0) { - detailed_error(svc, - gettext("Cannot access file: %s: %s"), - file, strerror(errno)); - return (PAPI_DOCUMENT_ACCESS_ERROR); - } - if (statbuf.st_size == 0) { - detailed_error(svc, - "Zero byte (empty) file: %s", file); - return (PAPI_BAD_ARGUMENT); - } - } else if (svc->transfer_encoding != - TRANSFER_ENCODING_CHUNKED) { - struct stat st; - - if (fstat(fd, &st) >= 0) - size = st.st_size; - } - } - - *response = NULL; - while (*response == NULL) { - http_status_t status = HTTP_CONTINUE; - - result = ipp_send_initial_request_block(svc, request, size); - - if (result == PAPI_OK) { - if (file != NULL) { - /* send the file contents if we have it */ - int rc; - char buf[BUFSIZ]; - - lseek(fd, 0L, SEEK_SET); - while ((rc = read(fd, buf, sizeof (buf))) > 0) { - if (ipp_request_write(svc, buf, rc) - < rc) { - break; - } - } - } - - (void) ipp_request_write(svc, "", 0); - } - - /* update our connection info */ - while (status == HTTP_CONTINUE) - status = httpUpdate(svc->connection); - - if (status == HTTP_UNAUTHORIZED) { - httpFlush(svc->connection); - if ((svc->connection->authstring[0] == '\0') && - (setAuthString(svc) == 0)) { - httpReconnect(svc->connection); - continue; - } - } else if (status == HTTP_UPGRADE_REQUIRED) { - /* - * If the transport was built with TLS support, we can - * try to use it. - */ - httpFlush(svc->connection); - httpReconnect(svc->connection); - httpEncryption(svc->connection, HTTP_ENCRYPT_REQUIRED); - continue; - } - - if (status != HTTP_OK) - return (http_to_papi_status(status)); - - /* read the IPP response */ - result = ipp_read_message(&ipp_request_read, svc, response, - IPP_TYPE_RESPONSE); - - if (result == PAPI_OK) - result = ipp_status_info(svc, *response); -#ifdef DEBUG - fprintf(stderr, "\nIPP-RESPONSE: (%s) (%s)", (file ? file : ""), - papiStatusString(result)); - papiAttributeListPrint(stderr, *response, " "); - putc('\n', stderr); - fflush(stderr); -#endif - } - - return (result); -} - -papi_status_t -ipp_send_request(service_t *svc, papi_attribute_t **request, - papi_attribute_t ***response) -{ - return (ipp_send_request_with_file(svc, request, response, NULL)); -} diff --git a/usr/src/lib/print/libpapi-ipp/common/job.c b/usr/src/lib/print/libpapi-ipp/common/job.c deleted file mode 100644 index 65575d44db..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/job.c +++ /dev/null @@ -1,666 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: job.c 148 2006-04-25 16:54:17Z njacobs $ */ - - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <papi_impl.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <libintl.h> - -#ifndef OPID_CUPS_MOVE_JOB -#define OPID_CUPS_MOVE_JOB 0x400D -#endif - -void -papiJobFree(papi_job_t job) -{ - job_t *tmp = (job_t *)job; - - if (tmp != NULL) { - if (tmp->attributes != NULL) - papiAttributeListFree(tmp->attributes); - free(tmp); - } -} - -void -papiJobListFree(papi_job_t *jobs) -{ - if (jobs != NULL) { - int i; - - for (i = 0; jobs[i] != NULL; i++) - papiJobFree(jobs[i]); - free(jobs); - } -} - -papi_attribute_t ** -papiJobGetAttributeList(papi_job_t job) -{ - papi_attribute_t **result = NULL; - job_t *j = job; - - if (j != NULL) - result = j->attributes; - - return (result); -} - -char * -papiJobGetPrinterName(papi_job_t job) -{ - char *result = NULL; - job_t *j = job; - - if (j != NULL) - (void) papiAttributeListGetString(j->attributes, NULL, - "printer-name", &result); - - return (result); -} - -int32_t -papiJobGetId(papi_job_t job) -{ - int32_t result = -1; - job_t *j = job; - - if (j != NULL) - (void) papiAttributeListGetInteger(j->attributes, NULL, - "job-id", &result); - - return (result); -} - -papi_job_ticket_t * -papiJobGetJobTicket(papi_job_t job) -{ - papi_job_ticket_t *result = NULL; - - return (result); -} - -static void -populate_job_request(service_t *svc, papi_attribute_t ***request, - papi_attribute_t **attributes, char *printer, uint16_t type) -{ - papi_attribute_t **operational = NULL, **job = NULL; - static char *operational_names[] = { - "job-name", "ipp-attribute-fidelity", "document-name", - "compression", "document-format", "document-natural-language", - "job-k-octets", "job-impressions", "job-media-sheets", NULL - }; - - /* create the base IPP request */ - ipp_initialize_request(svc, request, type); - - /* create an operational attributes group */ - ipp_initialize_operational_attributes(svc, &operational, printer, -1); - - /* split up the attributes into operational and job attributes */ - split_and_copy_attributes(operational_names, attributes, - &operational, &job); - - /* add the operational attributes group to the request */ - papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, - "operational-attributes-group", operational); - papiAttributeListFree(operational); - - /* add the job attributes group to the request */ - if (job != NULL) { - /* - * Add job-originating-host-name to attributes - * if not already set. - */ - char *hostname = NULL; - - papiAttributeListGetString(job, NULL, - "job-originating-host-name", &hostname); - - if (hostname == NULL) { - char host[BUFSIZ]; - - if (gethostname(host, sizeof (host)) == 0) - papiAttributeListAddString(&job, PAPI_ATTR_EXCL, - "job-originating-host-name", host); - } - - papiAttributeListAddCollection(request, PAPI_ATTR_REPLACE, - "job-attributes-group", job); - papiAttributeListFree(job); - } -} - -static papi_status_t -send_document_uri(service_t *svc, char *file, papi_attribute_t **attributes, - char *printer, int32_t id, char last, uint16_t type) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - /* create the base IPP request */ - ipp_initialize_request(svc, &request, type); - - /* create an operational attributes group */ - ipp_initialize_operational_attributes(svc, &op, printer, id); - - papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, "document-name", - file); - papiAttributeListAddBoolean(&op, PAPI_ATTR_REPLACE, "last-document", - (last ? PAPI_TRUE : PAPI_FALSE)); - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - - /* send the IPP request to the server */ - result = ipp_send_request_with_file(svc, request, &response, file); - papiAttributeListFree(request); - papiAttributeListFree(response); - - return (result); -} - -typedef enum {_WITH_DATA, _BY_REFERENCE, _VALIDATE} call_type_t; - -papi_status_t -internal_job_submit(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, - char **files, papi_job_t *job, - call_type_t call_type) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - struct stat statbuf; - job_t *j = NULL; - int i; - uint16_t req_type = OPID_PRINT_JOB; - uint16_t data_type = OPID_SEND_DOCUMENT; - papi_attribute_t **request = NULL, **response = NULL; - - if ((svc == NULL) || (printer == NULL) || (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - switch (call_type) { - case _BY_REFERENCE: -#ifdef SOME_DAY_WE_WILL_BE_ABLE_TO_USE_URIS_FOR_JOB_DATA - /* - * For the time being, this is disabled. There are a number - * of issues to be dealt with before we can send a URI - * across the network to the server. For example, the file - * name(s) passed in are most likely relative to the current - * hosts filesystem. They also most likely will require some - * form of authentication information to be passed with the - * URI. - */ - req_type = OPID_PRINT_URI; - req_type = OPID_SEND_URI; -#endif - /* fall-through */ - case _WITH_DATA: - if ((files == NULL) || (files[0] == NULL)) - return (PAPI_BAD_ARGUMENT); - - if (files[1] != NULL) /* more than 1 file */ - req_type = OPID_CREATE_JOB; - - break; - case _VALIDATE: - req_type = OPID_VALIDATE_JOB; - /* if we have files, validate access to them */ - if (files != NULL) { - for (i = 0; files[i] != NULL; i++) { - if (access(files[i], R_OK) < 0) { - detailed_error(svc, "%s: %s", files[i], - strerror(errno)); - return (PAPI_DOCUMENT_ACCESS_ERROR); - } - - if (strcmp("standard input", files[i]) != 0) { - if (stat(files[i], &statbuf) < 0) { - detailed_error(svc, gettext( - "Cannot access file: %s:" - " %s"), files[i], - strerror(errno)); - return ( - PAPI_DOCUMENT_ACCESS_ERROR); - } - if (statbuf.st_size == 0) { - detailed_error(svc, - "Zero byte (empty) file: " - "%s", - files[i]); - return (PAPI_BAD_ARGUMENT); - } - } - } - files = NULL; - } - break; - } - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - /* - * before creating IPP request - * add the job-name - */ - if ((files != NULL) && (files[0] != NULL)) - papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, - "job-name", files[0]); - - /* create IPP request */ - populate_job_request(svc, &request, job_attributes, printer, req_type); - - switch (req_type) { - case OPID_PRINT_JOB: - result = ipp_send_request_with_file(svc, request, &response, - files[0]); - break; - case OPID_CREATE_JOB: - case OPID_VALIDATE_JOB: - case OPID_PRINT_URI: - result = ipp_send_request(svc, request, &response); - break; - } - papiAttributeListFree(request); - - if (result == PAPI_OK) { - papi_attribute_t **op = NULL; - - /* retrieve the job attributes */ - papiAttributeListGetCollection(response, NULL, - "job-attributes-group", &op); - copy_attributes(&j->attributes, op); - - if (req_type == OPID_CREATE_JOB) { - int32_t id = 0; - - papiAttributeListGetInteger(j->attributes, NULL, - "job-id", &id); - /* send each document */ - for (i = 0; ((result == PAPI_OK) && (files[i] != NULL)); - i++) - result = send_document_uri(svc, files[i], - job_attributes, - printer, id, (files[i+1]?0:1), - data_type); - } - } - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiJobSubmit(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (internal_job_submit(handle, printer, job_attributes, - job_ticket, files, job, _WITH_DATA)); -} - -papi_status_t -papiJobSubmitByReference(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (internal_job_submit(handle, printer, job_attributes, - job_ticket, files, job, _BY_REFERENCE)); -} - -papi_status_t -papiJobValidate(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (internal_job_submit(handle, printer, job_attributes, - job_ticket, files, job, _VALIDATE)); -} - -papi_status_t -papiJobStreamOpen(papi_service_t handle, char *printer, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, papi_stream_t *stream) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - papi_attribute_t **request = NULL; - service_t *svc = handle; - - if ((svc == NULL) || (printer == NULL) || (stream == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - papiAttributeListAddString(&job_attributes, PAPI_ATTR_EXCL, - "job-name", "standard input"); - - /* create job request */ - populate_job_request(svc, &request, job_attributes, printer, - OPID_PRINT_JOB); - - *stream = svc->connection; - - result = ipp_send_initial_request_block(svc, request, 0); - papiAttributeListFree(request); - - return (result); -} - -papi_status_t -papiJobStreamWrite(papi_service_t handle, - papi_stream_t stream, void *buffer, size_t buflen) -{ - papi_status_t result = PAPI_OK; - service_t *svc = handle; - size_t rc; - -#ifdef DEBUG - printf("papiJobStreamWrite(0x%8.8x, 0x%8.8x, 0x%8.8x, %d)\n", - handle, stream, buffer, buflen); - httpDumpData(stdout, "papiJobStreamWrite:", buffer, buflen); -#endif - - if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || - (buflen == 0)) - return (PAPI_BAD_ARGUMENT); - - while ((result == PAPI_OK) && (buflen > 0)) { - rc = ipp_request_write(svc, buffer, buflen); - if (rc < 0) - result = PAPI_TEMPORARY_ERROR; - else { - buffer = (char *)buffer + rc; - buflen -= rc; - } - } - -#ifdef DEBUG - printf("papiJobStreamWrite(): %s\n", papiStatusString(result)); -#endif - - return (result); -} - -papi_status_t -papiJobStreamClose(papi_service_t handle, - papi_stream_t stream, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - http_status_t status = HTTP_CONTINUE; - service_t *svc = handle; - papi_attribute_t **response = NULL; - job_t *j = NULL; - - if ((svc == NULL) || (stream == NULL) || (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - (void) ipp_request_write(svc, "", 0); - - /* update our connection info */ - while (status == HTTP_CONTINUE) - status = httpUpdate(svc->connection); - - if (status != HTTP_OK) - return (http_to_papi_status(status)); - httpWait(svc->connection, 1000); - - /* read the IPP response */ - result = ipp_read_message(&ipp_request_read, svc, &response, - IPP_TYPE_RESPONSE); - if (result == PAPI_OK) - result = ipp_status_info(svc, response); - - if (result == PAPI_OK) { - papi_attribute_t **op = NULL; - - papiAttributeListGetCollection(response, NULL, - "job-attributes-group", &op); - copy_attributes(&j->attributes, op); - } - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiJobQuery(papi_service_t handle, char *printer, int32_t job_id, - char **requested_attrs, - papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - ipp_initialize_request(svc, &request, OPID_GET_JOB_ATTRIBUTES); - - ipp_initialize_operational_attributes(svc, &op, printer, job_id); - - if (requested_attrs != NULL) { - int i; - - for (i = 0; requested_attrs[i] != NULL; i++) - papiAttributeListAddString(&op, PAPI_ATTR_APPEND, - "requested-attributes", requested_attrs[i]); - } - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - papiAttributeListGetCollection(response, NULL, - "job-attributes-group", &op); - copy_attributes(&j->attributes, op); - papiAttributeListFree(response); - - return (result); -} - -/* papiJob{Cancel|Hold|Release|Restart|Promote} are all the same */ -static papi_status_t -_job_cancel_hold_release_restart_promote(papi_service_t handle, - char *printer, int32_t job_id, uint16_t type) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (printer == NULL) || (job_id < 0)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, type); - - ipp_initialize_operational_attributes(svc, &op, printer, job_id); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiJobCancel(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_job_cancel_hold_release_restart_promote(handle, printer, - job_id, OPID_CANCEL_JOB)); -} - - -papi_status_t -papiJobHold(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_job_cancel_hold_release_restart_promote(handle, printer, - job_id, OPID_HOLD_JOB)); -} - -papi_status_t -papiJobRelease(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_job_cancel_hold_release_restart_promote(handle, printer, - job_id, OPID_RELEASE_JOB)); -} - -papi_status_t -papiJobRestart(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_job_cancel_hold_release_restart_promote(handle, printer, - job_id, OPID_RESTART_JOB)); -} - -papi_status_t -papiJobPromote(papi_service_t handle, char *printer, int32_t job_id) -{ - return (_job_cancel_hold_release_restart_promote(handle, printer, - job_id, OPID_PROMOTE_JOB)); -} - -papi_status_t -papiJobMove(papi_service_t handle, char *printer, int32_t job_id, - char *destination) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (printer == NULL) || (job_id < 0) || - (destination == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, OPID_CUPS_MOVE_JOB); - - ipp_initialize_operational_attributes(svc, &op, printer, job_id); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - - op = NULL; - papiAttributeListAddString(&op, PAPI_ATTR_EXCL, - "job-printer-uri", destination); - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "job-attributes-group", op); - papiAttributeListFree(op); - - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiJobModify(papi_service_t handle, char *printer, int32_t job_id, - papi_attribute_t **attributes, papi_job_t *job) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - job_t *j = NULL; - - if ((svc == NULL) || (printer == NULL) || (job_id < 0) || - (attributes == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((*job = j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, printer)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, OPID_SET_JOB_ATTRIBUTES); - - ipp_initialize_operational_attributes(svc, &op, printer, job_id); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "job-attributes-group", attributes); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - papiAttributeListGetCollection(response, NULL, - "job-attributes-group", &op); - copy_attributes(&j->attributes, op); - papiAttributeListFree(response); - - return (result); -} diff --git a/usr/src/lib/print/libpapi-ipp/common/mapfile b/usr/src/lib/print/libpapi-ipp/common/mapfile deleted file mode 100644 index 847a5bb76f..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/mapfile +++ /dev/null @@ -1,292 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ -# - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -# -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. -# - -SYMBOL_VERSION SUNW_1.0 { - global: - # PAPI Attribute Calls - papiAttributeListAddValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListDelete { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetNext { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFind { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFromString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListToString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFree { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # PAPI Service Calls - papiServiceCreate ; - papiServiceDestroy ; - papiServiceSetUserName ; - papiServiceSetPassword ; - papiServiceSetEncryption ; - papiServiceSetAuthCB ; - papiServiceSetAppData ; - papiServiceGetUserName ; - papiServiceGetPassword ; - papiServiceGetEncryption ; - papiServiceGetAppData ; - papiServiceGetServiceName ; - papiServiceGetAttributeList ; - papiServiceGetStatusMessage ; - - # PAPI Printer Calls - papiPrintersList ; - papiPrinterQuery ; - papiPrinterAdd ; - papiPrinterModify ; - papiPrinterRemove ; - papiPrinterDisable ; - papiPrinterEnable ; - papiPrinterPause ; - papiPrinterResume ; - papiPrinterPurgeJobs ; - papiPrinterListJobs ; - papiPrinterGetAttributeList ; - papiPrinterFree ; - papiPrinterListFree ; - - # PAPI Job Calls - papiJobSubmit ; - papiJobSubmitByReference ; - papiJobValidate ; - papiJobStreamOpen ; - papiJobStreamWrite ; - papiJobStreamClose ; - papiJobQuery ; - papiJobModify ; - papiJobMove ; - papiJobCancel ; - papiJobHold ; - papiJobRelease ; - papiJobRestart ; - papiJobPromote ; - papiJobGetAttributeList ; - papiJobGetPrinterName ; - papiJobGetId ; - papiJobGetJobTicket ; - papiJobFree ; - papiJobListFree ; - - # Misc. PAPI Calls - papiStatusString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiLibrarySupportedCall { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiLibrarySupportedCalls { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; -} ; - -SYMBOL_VERSION SUNWprivate_1.0 { - global: - papiServiceSetPeer { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobCreate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobStreamAdd { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobCommit { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # Misc. supporting calls - # URI - uri_from_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_to_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_free { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # list - list_remove { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_append { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_concatenate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # NS - getprinterbyname { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - is_localhost { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # extra Attribute Calls - copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - split_and_copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListPrint { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - local: - * ; -} ; diff --git a/usr/src/lib/print/libpapi-ipp/common/papi_impl.h b/usr/src/lib/print/libpapi-ipp/common/papi_impl.h deleted file mode 100644 index c7048665a8..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/papi_impl.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _PAPI_IMPL_H -#define _PAPI_IMPL_H - -/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <papi.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include <time.h> -#include <sys/types.h> -#include <stdarg.h> -#include <uri.h> - -#include <http.h> -#include <ipp.h> - -/* - * Implementation specific types/prototypes/definitions follow - * - * - * Ex: - */ -typedef enum { - TRANSFER_ENCODING_CHUNKED, - TRANSFER_ENCODING_LENGTH -} http_transfer_encoding_t; - -typedef struct { - papi_attribute_t **attributes; - char *name; - char *user; - char *password; - int (*authCB)(papi_service_t svc, void *app_data); - papi_encryption_t encryption; - void *app_data; - uri_t *uri; - char *post; - http_t *connection; - http_transfer_encoding_t transfer_encoding; -} service_t; - -typedef struct job { - papi_attribute_t **attributes; -} job_t; - -typedef struct { - papi_attribute_t **attributes; -} printer_t; - -/* IPP glue interfaces */ -extern ssize_t ipp_request_read(void *fd, void *buffer, size_t length); -extern ssize_t ipp_request_write(void *fd, void *buffer, size_t length); -extern papi_status_t ipp_send_request(service_t *svc, - papi_attribute_t **request, - papi_attribute_t ***response); -extern papi_status_t ipp_send_request_with_file(service_t *svc, - papi_attribute_t **request, - papi_attribute_t ***response, char *file); -extern papi_status_t ipp_send_initial_request_block(service_t *svc, - papi_attribute_t **request, ssize_t file_size); -extern papi_status_t ipp_status_info(service_t *svc, - papi_attribute_t **response); -extern void ipp_initialize_request(service_t *svc, - papi_attribute_t ***request, uint16_t type); -extern void ipp_initialize_operational_attributes(service_t *svc, - papi_attribute_t ***op, - char *printer, int job_id); -extern papi_status_t ipp_to_papi_status(uint16_t status); -extern papi_status_t http_to_papi_status(http_status_t status); - -/* service related interfaces */ -extern void detailed_error(service_t *svc, char *fmt, ...); -extern papi_status_t service_connect(service_t *svc, char *service_name); - -#ifdef __cplusplus -} -#endif - -#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-ipp/common/printer.c b/usr/src/lib/print/libpapi-ipp/common/printer.c deleted file mode 100644 index c49c4adb03..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/printer.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: printer.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <papi_impl.h> - -#include <config-site.h> - -void -papiPrinterFree(papi_printer_t printer) -{ - printer_t *tmp = printer; - - if (tmp != NULL) { - if (tmp->attributes != NULL) - papiAttributeListFree(tmp->attributes); - free(tmp); - } -} - -void -papiPrinterListFree(papi_printer_t *printers) -{ - if (printers != NULL) { - int i; - - for (i = 0; printers[i] != NULL; i++) - papiPrinterFree(printers[i]); - free(printers); - } -} - -/* - * Enumeration of printers is not part of the IPP specification, so many - * servers will probably not respond back with a list of printers, but - * CUPS has implemented an extension to IPP to enumerate printers and - * classes. the Apache/mod_ipp IPP listener module available in Solaris - * implements this IPP extension, so CUPS and Solaris can provide this - * to IPP clients. - */ -#ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */ -#define OPID_CUPS_GET_PRINTERS 0x4002 -#endif /* OPID_CUPS_GET_PRINTERS */ -#ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */ -#define OPID_CUPS_DELETE_PRINTER 0x4004 -#endif /* OPID_CUPS_DELETE_PRINTER */ -#ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */ -#define OPID_CUPS_GET_CLASSES 0x4005 -#endif /* OPID_CUPS_GET_CLASSES */ - -papi_status_t -papiPrintersList(papi_service_t handle, char **requested_attrs, - papi_filter_t *filter, papi_printer_t **printers) -{ - papi_status_t status, result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - void *iter = NULL; - - if ((svc == NULL) || (printers == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK) - return (result); - ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS); - - ipp_initialize_operational_attributes(svc, &op, NULL, -1); - - if (requested_attrs != NULL) { - int i; - - for (i = 0; requested_attrs[i] != NULL; i++) - papiAttributeListAddString(&op, PAPI_ATTR_APPEND, - "requested-attributes", requested_attrs[i]); - } - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - for (status = papiAttributeListGetCollection(response, &iter, - "printer-attributes-group", &op); - status == PAPI_OK; - status = papiAttributeListGetCollection(response, &iter, - NULL, &op)) { - printer_t *p = NULL; - - if ((p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - copy_attributes(&p->attributes, op); - op = NULL; - list_append(printers, p); - } - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiPrinterQuery(papi_service_t handle, char *name, - char **requested_attrs, - papi_attribute_t **job_attributes, - papi_printer_t *printer) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - printer_t *p = NULL; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (name == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - if ((*printer = p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES); - - ipp_initialize_operational_attributes(svc, &op, name, -1); - - if (requested_attrs != NULL) { - int i; - - for (i = 0; requested_attrs[i] != NULL; i++) - papiAttributeListAddString(&op, PAPI_ATTR_APPEND, - "requested-attributes", requested_attrs[i]); - } - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - papiAttributeListGetCollection(response, NULL, - "printer-attributes-group", &op); - copy_attributes(&p->attributes, op); - papiAttributeListFree(response); - - return (result); -} - -static papi_status_t -_printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name, - char *message, uint16_t type) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, type); - - ipp_initialize_operational_attributes(svc, &op, name, -1); - - switch (type) { - case OPID_DISABLE_PRINTER: - papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, - "printer-message-from-operator", message); - break; - case OPID_PAUSE_PRINTER: - papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, - "printer-state-message", message); - break; - default: /* a message value is of no use */ - break; - } - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiPrinterEnable(papi_service_t handle, char *name) -{ - return (_printer_enable_disable_pause_resume_delete(handle, name, - NULL, OPID_ENABLE_PRINTER)); -} - -papi_status_t -papiPrinterResume(papi_service_t handle, char *name) -{ - return (_printer_enable_disable_pause_resume_delete(handle, name, - NULL, OPID_RESUME_PRINTER)); -} - -papi_status_t -papiPrinterPause(papi_service_t handle, char *name, char *message) -{ - return (_printer_enable_disable_pause_resume_delete(handle, name, - message, OPID_PAUSE_PRINTER)); -} - -papi_status_t -papiPrinterDisable(papi_service_t handle, char *name, char *message) -{ - return (_printer_enable_disable_pause_resume_delete(handle, name, - message, OPID_PAUSE_PRINTER)); -} - -/* - * there is no IPP create operation, the set-printer-attibutes operation - * is the closest we have, so we will assume that the server will create - * a printer and set attributes if there is none. - */ -papi_status_t -papiPrinterAdd(papi_service_t handle, char *name, - papi_attribute_t **attributes, papi_printer_t *printer) -{ - return (papiPrinterModify(handle, name, attributes, printer)); -} - -papi_status_t -papiPrinterModify(papi_service_t handle, char *name, - papi_attribute_t **attributes, papi_printer_t *printer) -{ - papi_status_t result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - printer_t *p = NULL; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - - if ((svc == NULL) || (name == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - if ((*printer = p = calloc(1, sizeof (*p))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES); - - ipp_initialize_operational_attributes(svc, &op, name, -1); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "printer-attributes-group", attributes); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - papiAttributeListGetCollection(response, NULL, - "printer-attributes-group", &op); - copy_attributes(&p->attributes, op); - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiPrinterRemove(papi_service_t handle, char *name) -{ - return (_printer_enable_disable_pause_resume_delete(handle, name, - NULL, OPID_CUPS_DELETE_PRINTER)); -} - -papi_status_t -papiPrinterPurgeJobs(papi_service_t handle, char *name, - papi_job_t **jobs) -{ - papi_status_t status, result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - void *iter = NULL; - - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, OPID_PURGE_JOBS); - - ipp_initialize_operational_attributes(svc, &op, name, -1); - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - for (status = papiAttributeListGetCollection(response, &iter, - "job-attributes-group", &op); - status == PAPI_OK; - status = papiAttributeListGetCollection(response, &iter, - NULL, &op)) { - job_t *j = NULL; - - if ((j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - copy_attributes(&j->attributes, op); - op = NULL; - list_append(jobs, j); - } - papiAttributeListFree(response); - - return (result); -} - -papi_status_t -papiPrinterListJobs(papi_service_t handle, char *name, - char **requested_attrs, int type_mask, - int max_num_jobs, papi_job_t **jobs) -{ - papi_status_t status, result = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - papi_attribute_t **request = NULL, **op = NULL, **response = NULL; - void *iter = NULL; - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - /* if we are already connected, use that connection. */ - if (svc->connection == NULL) - if ((result = service_connect(svc, name)) != PAPI_OK) - return (result); - - ipp_initialize_request(svc, &request, OPID_GET_JOBS); - - ipp_initialize_operational_attributes(svc, &op, name, -1); - - if (requested_attrs != NULL) { - int i; - - for (i = 0; requested_attrs[i] != NULL; i++) - papiAttributeListAddString(&op, PAPI_ATTR_APPEND, - "requested-attributes", requested_attrs[i]); - } - - papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, - "operational-attributes-group", op); - papiAttributeListFree(op); - result = ipp_send_request(svc, request, &response); - papiAttributeListFree(request); - - op = NULL; - for (status = papiAttributeListGetCollection(response, &iter, - "job-attributes-group", &op); - status == PAPI_OK; - status = papiAttributeListGetCollection(response, &iter, - NULL, &op)) { - job_t *j = NULL; - - if ((j = calloc(1, sizeof (*j))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - copy_attributes(&j->attributes, op); - op = NULL; - list_append(jobs, j); - } - papiAttributeListFree(response); - - return (result); -} - -papi_attribute_t ** -papiPrinterGetAttributeList(papi_printer_t printer) -{ - papi_attribute_t **result = NULL; - printer_t *p = printer; - - if (p != NULL) - result = p->attributes; - - return (result); -} diff --git a/usr/src/lib/print/libpapi-ipp/common/service.c b/usr/src/lib/print/libpapi-ipp/common/service.c deleted file mode 100644 index e5531f1422..0000000000 --- a/usr/src/lib/print/libpapi-ipp/common/service.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: service.c 171 2006-05-20 06:00:32Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <alloca.h> -#include <libintl.h> -#include <papi_impl.h> - -#include <config-site.h> - -http_encryption_t -http_encryption_type(papi_encryption_t encryption) -{ - switch (encryption) { - case PAPI_ENCRYPT_IF_REQUESTED: - return (HTTP_ENCRYPT_IF_REQUESTED); - case PAPI_ENCRYPT_REQUIRED: - return (HTTP_ENCRYPT_REQUIRED); - case PAPI_ENCRYPT_ALWAYS: - return (HTTP_ENCRYPT_ALWAYS); - case PAPI_ENCRYPT_NEVER: - return (HTTP_ENCRYPT_NEVER); - default: - ; /* this should log an error */ - } - - return (HTTP_ENCRYPT_NEVER); /* should never get here */ -} - -papi_status_t -service_connect(service_t *svc, char *service_name) -{ - papi_status_t result = PAPI_OK; - int port = 631; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - if (svc->connection != NULL) /* alread connected ? */ - return (PAPI_OK); - - if (svc->uri == NULL) - uri_from_string(service_name, &svc->uri); - - if ((service_name != NULL) && (svc->uri == NULL)) { - /* - * a name was supplied and it's not in URI form, we will - * try to use a "default" IPP service under the assumption - * that this is most likely a short-form printer name from - * from a papiPrinter*() or papiJob*() call and not from a - * papiServiceCreate() call. - */ - if ((service_name = getenv("PAPI_SERVICE_URI")) == NULL) { - char *cups; - - if ((cups = getenv("CUPS_SERVER")) != NULL) { - char buf[BUFSIZ]; - - snprintf(buf, sizeof (buf), - "ipp://%s/printers/", cups); - service_name = strdup(buf); - } - } - if (service_name == NULL) - service_name = DEFAULT_IPP_SERVICE_URI; - - uri_from_string(service_name, &svc->uri); - } - - if (svc->uri == NULL) - return (PAPI_NOT_POSSIBLE); - - if (svc->uri->port != NULL) - port = strtol(svc->uri->port, NULL, 10); - - svc->connection = httpConnectEncrypt(svc->uri->host, port, - http_encryption_type(svc->encryption)); - if (svc->connection == NULL) { - if (svc->uri != NULL) { - uri_free(svc->uri); - svc->uri = NULL; - } - result = PAPI_SERVICE_UNAVAILABLE; - } else if (service_name != NULL) - svc->name = strdup(service_name); - - return (result); -} - -papi_status_t -papiServiceCreate(papi_service_t *handle, char *service_name, - char *user_name, char *password, - int (*authCB)(papi_service_t svc, void *app_data), - papi_encryption_t encryption, void *app_data) -{ - papi_status_t result = PAPI_NOT_POSSIBLE; - service_t *svc = NULL; - char *encoding = getenv("HTTP_TRANSFER_ENCODING"); - - if (handle == NULL) - return (PAPI_BAD_ARGUMENT); - - if ((*handle = svc = calloc(1, sizeof (*svc))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - if (user_name != NULL) - svc->user = strdup(user_name); - - if (password != NULL) - svc->password = strdup(password); - - svc->encryption = encryption; - - if (authCB != NULL) - svc->authCB = authCB; - - if (app_data != NULL) - svc->app_data = app_data; - - if ((encoding != NULL) && (strcasecmp(encoding, "content-length") == 0)) - svc->transfer_encoding = TRANSFER_ENCODING_LENGTH; - else - svc->transfer_encoding = TRANSFER_ENCODING_CHUNKED; - - if (service_name != NULL) { - result = service_connect(svc, service_name); - } else - result = PAPI_OK; - - return (result); -} - -void -papiServiceDestroy(papi_service_t handle) -{ - if (handle != NULL) { - service_t *svc = handle; - - if (svc->attributes != NULL) - papiAttributeListFree(svc->attributes); - if (svc->name != NULL) - free(svc->name); - if (svc->user != NULL) - free(svc->user); - if (svc->password != NULL) - free(svc->password); - if (svc->uri != NULL) - uri_free(svc->uri); - if (svc->post != NULL) - free(svc->post); - if (svc->connection != NULL) - httpClose(svc->connection); - - free(handle); - } -} - -papi_status_t -papiServiceSetUserName(papi_service_t handle, char *user_name) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - if (svc->user != NULL) - free(svc->user); - svc->user = NULL; - if (user_name != NULL) - svc->user = strdup(user_name); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetPassword(papi_service_t handle, char *password) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - if (svc->password != NULL) - free(svc->password); - svc->password = NULL; - if (password != NULL) - svc->password = strdup(password); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetEncryption(papi_service_t handle, - papi_encryption_t encryption) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - svc->encryption = encryption; - httpEncryption(svc->connection, - (http_encryption_t)svc->encryption); - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -papi_status_t -papiServiceSetAuthCB(papi_service_t handle, - int (*authCB)(papi_service_t svc, void *app_data)) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - svc->authCB = authCB; - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - - -papi_status_t -papiServiceSetAppData(papi_service_t handle, void *app_data) -{ - papi_status_t result = PAPI_OK; - - if (handle != NULL) { - service_t *svc = handle; - - svc->app_data = (void *)app_data; - } else - result = PAPI_BAD_ARGUMENT; - - return (result); -} - -char * -papiServiceGetServiceName(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - - result = svc->name; - } - - return (result); -} - -char * -papiServiceGetUserName(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - - result = svc->user; - } - - return (result); -} - -char * -papiServiceGetPassword(papi_service_t handle) -{ - char *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - - result = svc->password; - } - - return (result); -} - -papi_encryption_t -papiServiceGetEncryption(papi_service_t handle) -{ - papi_encryption_t result = PAPI_ENCRYPT_NEVER; - - if (handle != NULL) { - service_t *svc = handle; - - result = svc->encryption; - } - - return (result); -} - -void * -papiServiceGetAppData(papi_service_t handle) -{ - void *result = NULL; - - if (handle != NULL) { - service_t *svc = handle; - - result = svc->app_data; - } - - return (result); -} - -papi_attribute_t ** -papiServiceGetAttributeList(papi_service_t handle) -{ - papi_attribute_t **result = NULL; - service_t *svc = handle; - - if (handle != NULL) - result = svc->attributes; - - return (result); -} - -char * -papiServiceGetStatusMessage(papi_service_t handle) -{ - char *result = NULL; - service_t *svc = handle; - - papiAttributeListGetString(svc->attributes, NULL, - "detailed-status-message", &result); - - return (result); -} - -void -detailed_error(service_t *svc, char *fmt, ...) -{ - if ((svc != NULL) && (fmt != NULL)) { - va_list ap; - size_t size; - char *message = alloca(BUFSIZ); - - va_start(ap, fmt); - /* - * fill in the message. If the buffer is too small, allocate - * one that is large enough and fill it in. - */ - if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) - if ((message = alloca(size)) != NULL) - vsnprintf(message, size, fmt, ap); - va_end(ap); - - papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, - "detailed-status-message", message); - } -} diff --git a/usr/src/lib/print/libpapi-ipp/i386/Makefile b/usr/src/lib/print/libpapi-ipp/i386/Makefile deleted file mode 100644 index 39b4a998ec..0000000000 --- a/usr/src/lib/print/libpapi-ipp/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) diff --git a/usr/src/lib/print/libpapi-ipp/sparc/Makefile b/usr/src/lib/print/libpapi-ipp/sparc/Makefile deleted file mode 100644 index 39b4a998ec..0000000000 --- a/usr/src/lib/print/libpapi-ipp/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) diff --git a/usr/src/lib/print/libpapi-lpd/Makefile b/usr/src/lib/print/libpapi-lpd/Makefile deleted file mode 100644 index b92d620b10..0000000000 --- a/usr/src/lib/print/libpapi-lpd/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../../Makefile.lib - -#HDRS = papi.h -#HDRDIR = common -SUBDIRS = $(MACH) -#$(BUILD64)SUBDIRS += $(MACH64) - -all := TARGET = all -clean := TARGET = clean -clobber := TARGET = clobber -install := TARGET = install -lint := TARGET = lint - -.KEEP_STATE: - -all clean clobber install: .WAIT $(SUBDIRS) - -lint: # $(SUBDIRS) - -install_h: # $(ROOTHDRS) - -check: # $(CHECKHDRS) - -$(SUBDIRS): FRC - @cd $@; pwd; $(MAKE) $(TARGET) - -FRC: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/libpapi-lpd/Makefile.com b/usr/src/lib/print/libpapi-lpd/Makefile.com deleted file mode 100644 index c50fd8b223..0000000000 --- a/usr/src/lib/print/libpapi-lpd/Makefile.com +++ /dev/null @@ -1,92 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = psm-lpd.a -VERS = .1 -COMMON_OBJS = lpd-misc.o -OBJECTS = job.o library.o lpd-cancel.o lpd-job.o lpd-query.o printer.o \ - service.o $(COMMON_OBJS) - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib/print -ROOTLIBDIR64= $(ROOT)/usr/lib/print/$(MACH) - -EXTRALINKS= $(ROOTLIBDIR)/psm-rfc-1179.so -$(EXTRALINKS): $(ROOTLINKS) - $(RM) $@; $(SYMLINK) $(LIBLINKS) $@ - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../libpapi-common/common - -CERRWARN += -_gcc=-Wno-unused-variable - -MAPFILES = $(SRCDIR)/mapfile - -LDLIBS += -lc - -.KEEP_STATE: - -all: $(LIBS) $(PROG) - -lint: lintcheck - -include ../../../Makefile.targ - -# -# NEEDED to build lpd-port -# -PROG = lpd-port -LPD_PORT_OBJS = lpd-port.o $(COMMON_OBJS) - -$(PROG) := LDLIBS += -lsocket -lnsl -lsendfile - -PROG_OBJS = $(LPD_PORT_OBJS:%=pics/%) -OBJS += $(PROG_OBJS) - -LDFLAGS.cmd = \ - $(ENVLDFLAGS1) $(ENVLDFLAGS2) $(ENVLDFLAGS3) $(BDIRECT) \ - $(MAPFILE.NES:%=-M%) $(MAPFILE.PGA:%=-M%) $(MAPFILE.NED:%=-M%) - -$(PROG): $(PROG_OBJS) - $(LINK.c) -o $@ $(PROG_OBJS) $(LDFLAGS.cmd) $(LDLIBS) - $(POST_PROCESS) - -# needed for the 'install' phase -ROOTLIBPRINTPROG = $(PROG:%=$(ROOTLIBDIR)/%) -$(ROOTLIBPRINTPROG) := FILEMODE = 04511 - -$(ROOTLIBDIR)/%: $(ROOTLIBDIR) % - $(INS.file) -$(ROOTLIBDIR): - $(INS.dir) diff --git a/usr/src/lib/print/libpapi-lpd/common/job.c b/usr/src/lib/print/libpapi-lpd/common/job.c deleted file mode 100644 index 8663816337..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/job.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* $Id: job.c 179 2006-07-17 18:24:07Z njacobs $ */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <limits.h> -#include <libintl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <papi_impl.h> -#include <uri.h> - -/* - * must copy files before leaving routine - */ -papi_status_t -papiJobSubmit(papi_service_t handle, char *name, papi_attribute_t **attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - papi_status_t status = PAPI_OK; - service_t *svc = handle; - job_t *j = NULL; - char *metadata = NULL; - - if ((svc == NULL) || (name == NULL) || (files == NULL) || - (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - if (job_ticket != NULL) { - detailed_error(svc, - gettext("papiJobSubmit: job ticket not supported")); - return (PAPI_OPERATION_NOT_SUPPORTED); - } - - if ((status = service_fill_in(svc, name)) != PAPI_OK) - return (status); - - if ((*job = j = (job_t *)calloc(1, sizeof (*j))) == NULL) { - detailed_error(svc, - gettext("calloc() failed")); - return (PAPI_TEMPORARY_ERROR); - } - - /* before creating a control file add the job-name */ - if ((files != NULL) && (files[0] != NULL)) - papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, - "job-name", files[0]); - - /* create a control file */ - (void) lpd_job_add_attributes(svc, attributes, &metadata, - &j->attributes); - - if ((status = lpd_job_add_files(svc, attributes, files, &metadata, - &j->attributes)) != PAPI_OK) { - return (status); - } - - /* send the job to the server */ - status = lpd_submit_job(svc, metadata, &j->attributes, NULL); - free(metadata); - - return (status); - -} - - -papi_status_t -papiJobSubmitByReference(papi_service_t handle, char *name, - papi_attribute_t **job_attributes, - papi_job_ticket_t *job_ticket, char **files, papi_job_t *job) -{ - return (papiJobSubmit(handle, name, job_attributes, - job_ticket, files, job)); -} - -papi_status_t -papiJobStreamOpen(papi_service_t handle, char *name, - papi_attribute_t **attributes, - papi_job_ticket_t *job_ticket, papi_stream_t *stream) -{ - papi_status_t status = PAPI_OK; - service_t *svc = handle; - char *metadata = NULL; - stream_t *s = NULL; - - if ((svc == NULL) || (name == NULL) || (stream == NULL)) - return (PAPI_BAD_ARGUMENT); - - if (job_ticket != NULL) - return (PAPI_OPERATION_NOT_SUPPORTED); - - if ((status = service_fill_in(svc, name)) != PAPI_OK) - return (status); - - /* create the stream container */ - if ((*stream = s = calloc(1, sizeof (*s))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - /* create the job */ - if ((s->job = calloc(1, sizeof (*(s->job)))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, - "job-name", "standard input"); - - /* process the attribute list */ - lpd_job_add_attributes(svc, attributes, &metadata, &s->job->attributes); - - /* if we can stream, do it */ - if ((svc->uri->fragment != NULL) && - (strcasecmp(svc->uri->fragment, "streaming") == 0)) { - char *files[] = { "standard input", NULL }; - - lpd_job_add_files(svc, attributes, files, &metadata, - &(s->job->attributes)); - status = lpd_submit_job(svc, metadata, &(s->job->attributes), - &s->fd); - } else { - char dfname[18]; - char buf[256]; - - strcpy(dfname, "/tmp/stdin-XXXXX"); - - if ((s->fd = mkstemp(dfname)) >= 0) - s->dfname = strdup(dfname); - if (s->job->attributes) - papiAttributeListFree(s->job->attributes); - s->job->attributes = NULL; - papiAttributeListToString(attributes, " ", buf, sizeof (buf)); - papiAttributeListFromString(&(s->job->attributes), - PAPI_ATTR_APPEND, buf); - } - s->metadata = metadata; - - return (status); -} - - -papi_status_t -papiJobStreamWrite(papi_service_t handle, papi_stream_t stream, - void *buffer, size_t buflen) -{ - service_t *svc = handle; - stream_t *s = stream; - - if ((svc == NULL) || (stream == NULL) || (buffer == NULL) || - (buflen == 0)) - return (PAPI_BAD_ARGUMENT); - - if (write(s->fd, buffer, buflen) != buflen) - return (PAPI_DEVICE_ERROR); - - return (PAPI_OK); -} - -papi_status_t -papiJobStreamClose(papi_service_t handle, papi_stream_t stream, papi_job_t *job) -{ - papi_status_t status = PAPI_INTERNAL_ERROR; - service_t *svc = handle; - job_t *j = NULL; - stream_t *s = stream; - int ret; - - if ((svc == NULL) || (stream == NULL) || (job == NULL)) - return (PAPI_BAD_ARGUMENT); - - close(s->fd); /* close the stream */ - - if (s->dfname != NULL) { /* if it is a tmpfile, print it */ - char *files[2]; - - files[0] = s->dfname; - files[1] = NULL; - - lpd_job_add_files(svc, s->job->attributes, files, &s->metadata, - &(s->job->attributes)); - status = lpd_submit_job(svc, s->metadata, - &(s->job->attributes), NULL); - unlink(s->dfname); - free(s->dfname); - } else - status = PAPI_OK; - - if (s->metadata != NULL) - free(s->metadata); - - *job = s->job; - - return (status); -} - -papi_status_t -papiJobQuery(papi_service_t handle, char *name, int32_t job_id, - char **job_attributes, papi_job_t *job) -{ - papi_status_t status = PAPI_OK; - service_t *svc = handle; - - if ((svc == NULL) || (name == NULL) || job_id < 0) - return (PAPI_BAD_ARGUMENT); - - if ((status = service_fill_in(svc, name)) == PAPI_OK) - status = lpd_find_job_info(svc, job_id, (job_t **)job); - - return (status); -} - -papi_status_t -papiJobCancel(papi_service_t handle, char *name, int32_t job_id) -{ - papi_status_t status; - service_t *svc = handle; - - if ((svc == NULL) || (name == NULL) || (job_id < 0)) - return (PAPI_BAD_ARGUMENT); - - if ((status = service_fill_in(svc, name)) == PAPI_OK) - status = lpd_cancel_job(svc, job_id); - - return (status); -} - -papi_attribute_t ** -papiJobGetAttributeList(papi_job_t job) -{ - job_t *j = (job_t *)job; - - if (j != NULL) - return ((papi_attribute_t **)j->attributes); - - return (NULL); -} - -char * -papiJobGetPrinterName(papi_job_t job) -{ - char *result = NULL; - job_t *j = (job_t *)job; - - if (j != NULL) - papiAttributeListGetString(j->attributes, NULL, - "printer-name", &result); - - return (result); -} - -int -papiJobGetId(papi_job_t job) -{ - int result = -1; - job_t *j = (job_t *)job; - - if (j != NULL) - papiAttributeListGetInteger(j->attributes, NULL, - "job-id", &result); - - return (result); -} - -void -papiJobFree(papi_job_t job) -{ - job_t *j = (job_t *)job; - - - if (j != NULL) { - papiAttributeListFree(j->attributes); - free(j); - } -} - -void -papiJobListFree(papi_job_t *jobs) -{ - if (jobs != NULL) { - int i; - - for (i = 0; jobs[i] != NULL; i++) - papiJobFree(jobs[i]); - free(jobs); - } -} diff --git a/usr/src/lib/print/libpapi-lpd/common/library.c b/usr/src/lib/print/libpapi-lpd/common/library.c deleted file mode 100644 index de38c2bbfa..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/library.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: library.c 146 2006-03-24 00:26:54Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <alloca.h> -#include <libintl.h> -#include <papi_impl.h> - -static char *calls[] = { - /* Attribute Calls */ - "papiAttributeListAdd", - "papiAttributeListAddBoolean", "papiAttributeListAddCollection", - "papiAttributeListAddDatetime", "papiAttributeListAddInteger", - "papiAttributeListAddMetadata", "papiAttributeListAddRange", - "papiAttributeListAddResolution", "papiAttributeListAddString", - "papiAttributeListDelete", - "papiAttributeListGetValue", "papiAttributeListGetNext", - "papiAttributeListFind", - "papiAttributeListGetBoolean", "papiAttributeListGetCollection", - "papiAttributeListGetDatetime", "papiAttributeListGetInteger", - "papiAttributeListGetMetadata", "papiAttributeListGetRange", - "papiAttributeListGetResolution", "papiAttributeListGetString", - "papiAttributeListFromString", "papiAttributeListToString", - "papiAttributeListFree", - /* Job Calls */ - "papiJobSubmit", "papiJobSubmitByReference", - "papiJobStreamOpen", "papiJobStreamWrite", "papiJobStreamClose", - "papiJobQuery", "papiJobCancel", - "papiJobGetAttributeList", "papiJobGetId", "papiJobGetPrinterName", - "papiJobFree", "papiJobListFree", - /* Printer Calls */ - "papiPrinterQuery", "papiPrinterPurgeJobs", "papiPrinterListJobs", - "papiPrinterGetAttributeList", "papiPrinterFree", - /* Service Calls */ - "papiServiceCreate", "papiServiceDestroy", - "papiServiceGetStatusMessage", - /* Misc Calls */ - "papiStatusString", - "papiLibrarySupportedCall", "papiLibrarySupportedCalls", - NULL -}; - -char ** -papiLibrarySupportedCalls() -{ - return (calls); -} - -char -papiLibrarySupportedCall(char *name) -{ - int i; - - for (i = 0; calls[i] != NULL; i++) - if (strcmp(name, calls[i]) == 0) - return (PAPI_TRUE); - - return (PAPI_FALSE); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c b/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c deleted file mode 100644 index d5a8fd30fd..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/lpd-cancel.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: lpd-cancel.c 155 2006-04-26 02:34:54Z ktou $ */ - -#define __EXTENSIONS__ /* for strtok_r() */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <papi_impl.h> - -papi_status_t -lpd_cancel_job(service_t *svc, int id) -{ - papi_status_t status = PAPI_INTERNAL_ERROR; - int fd; - char *list[2]; - char buf[128]; /* this should be overkill */ - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - snprintf(buf, sizeof (buf), "%d", id); - list[0] = buf; - list[1] = NULL; - - if ((fd = lpd_open(svc, 'c', list, 15)) < 0) - return (PAPI_INTERNAL_ERROR); - - memset(buf, 0, sizeof (buf)); - if (fdgets(buf, sizeof (buf), fd) != NULL) { - if (buf[0] == '\0') - status = PAPI_NOT_FOUND; - else if ((strstr(buf, "permission denied") != NULL) || - (strstr(buf, "not-authorized") != NULL)) - status = PAPI_NOT_AUTHORIZED; - else if ((strstr(buf, "cancelled") != NULL) || - (strstr(buf, "removed") != NULL)) - status = PAPI_OK; - } else - status = PAPI_NOT_FOUND; - - close(fd); - - return (status); -} - -papi_status_t -lpd_purge_jobs(service_t *svc, job_t ***jobs) -{ - papi_status_t status = PAPI_INTERNAL_ERROR; - int fd; - char *queue; - char buf[256]; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - if ((fd = lpd_open(svc, 'c', NULL, 15)) < 0) - return (PAPI_INTERNAL_ERROR); - - queue = queue_name_from_uri(svc->uri); - - status = PAPI_OK; - memset(buf, 0, sizeof (buf)); - while (fdgets(buf, sizeof (buf), fd) != NULL) { - /* if we canceled it, add it to the list */ - if ((strstr(buf, "cancelled") != NULL) || - (strstr(buf, "removed") != NULL)) { - job_t *job; - papi_attribute_t **attributes = NULL; - char *ptr, *iter = NULL; - int id; - - ptr = strtok_r(buf, ":", &iter); - papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, - "job-name", ptr); - id = atoi(ptr); - papiAttributeListAddInteger(&attributes, PAPI_ATTR_EXCL, - "job-id", id); - papiAttributeListAddString(&attributes, PAPI_ATTR_EXCL, - "job-printer", queue); - - if ((job = (job_t *)calloc(1, (sizeof (*job)))) - != NULL) { - job->attributes = attributes; - list_append(jobs, job); - } else - papiAttributeListFree(attributes); - } else if (strstr(buf, "permission denied") != NULL) - status = PAPI_NOT_AUTHORIZED; - } - close(fd); - - return (status); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-job.c b/usr/src/lib/print/libpapi-lpd/common/lpd-job.c deleted file mode 100644 index c958a51e06..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/lpd-job.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: lpd-job.c 157 2006-04-26 15:07:55Z ktou $ */ - - -#define __EXTENSIONS__ /* for strtok_r() */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <limits.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <pwd.h> -#include <libintl.h> -#include <papi_impl.h> - -enum { LPD_RFC, LPD_SVR4 }; - -static char -mime_type_to_rfc1179_type(char *mime) -{ - static struct { char *mime; char rfc; } cvt[] = { - { "text/plain", 'f' }, - { "application/octet-stream", 'l' }, - { "application/postscript", 'f' }, /* rfc incorrectly has 'o' */ - { "application/x-pr", 'p' }, - { "application/x-cif", 'c' }, - { "application/x-dvi", 'd' }, - { "application/x-fortran", 'r' }, - { "application/x-plot", 'g' }, - { "application/x-ditroff", 'n' }, - { "application/x-troff", 't' }, - { "application/x-raster", 'v' }, - { NULL, 0} - }; - char result = '\0'; - - if (mime != NULL) { - int i; - - for (i = 0; cvt[i].mime != NULL; i++) - if (strcasecmp(cvt[i].mime, mime) == 0) { - result = cvt[i].rfc; - break; - } - } - - return (result); -} - -static papi_status_t -add_lpd_control_line(char **metadata, char code, char *value) -{ - size_t size = 0; - char line[BUFSIZ]; - - if ((metadata == NULL) || (value == NULL)) - return (PAPI_BAD_REQUEST); - - if (*metadata != NULL) - size = strlen(*metadata); - size += strlen(value) + 3; - - if (*metadata == NULL) { - *metadata = (char *)calloc(1, size); - } else { - void *tmp; - tmp = calloc(1, size); - if (tmp) { - strlcpy(tmp, *metadata, size); - free(*metadata); - *metadata = (char *)tmp; - } else - return (PAPI_TEMPORARY_ERROR); - } - - snprintf(line, sizeof (line), "%c%s\n", code, value); - strlcat(*metadata, line, size); - - return (PAPI_OK); -} - -static papi_status_t -add_svr4_control_line(char **metadata, char code, char *value) -{ - - char line[BUFSIZ]; - - if ((metadata == NULL) || (value == NULL)) - return (PAPI_BAD_REQUEST); - - snprintf(line, sizeof (line), "%c%s", code, value); - - return (add_lpd_control_line(metadata, '5', line)); -} - -static papi_status_t -add_hpux_control_line(char **metadata, char *value) -{ - - char line[BUFSIZ]; - - if ((metadata == NULL) || (value == NULL)) - return (PAPI_BAD_REQUEST); - - snprintf(line, sizeof (line), " O%s", value); - - return (add_lpd_control_line(metadata, 'N', line)); -} - -static papi_status_t -add_int_control_line(char **metadata, char code, int value, int flag) -{ - char buf[16]; - - snprintf(buf, sizeof (buf), "%d", value); - - if (flag == LPD_SVR4) - return (add_svr4_control_line(metadata, code, buf)); - else - return (add_lpd_control_line(metadata, code, buf)); -} - -static papi_status_t -lpd_add_rfc1179_attributes(service_t *svc, papi_attribute_t **attributes, - char **metadata, papi_attribute_t ***used) -{ - papi_status_t status = PAPI_OK; - char *s; - int integer; - char bool; - char host[BUFSIZ]; - char *user = "nobody"; - uid_t uid = getuid(); - struct passwd *pw; - char *h1; - - if (svc == NULL) - return (PAPI_BAD_REQUEST); - - /* There is nothing to do */ - if (attributes == NULL) - return (PAPI_OK); - - gethostname(host, sizeof (host)); - if (papiAttributeListGetString(attributes, NULL, - "job-originating-host-name", &h1) == PAPI_OK) { - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "job-host", h1); - } - add_lpd_control_line(metadata, 'H', host); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-originating-host-name", host); - - if ((pw = getpwuid(uid)) != NULL) - user = pw->pw_name; - if (uid == 0) - papiAttributeListGetString(svc->attributes, NULL, "username", - &user); - add_lpd_control_line(metadata, 'P', user); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-originating-user-name", user); - - /* Class for Banner Page */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "rfc-1179-class", &s); - if (s != NULL) { - add_lpd_control_line(metadata, 'C', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "rfc-1179-class", s); - } - - /* Print Banner Page */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "job-sheets", &s); - if ((s != NULL) && (strcmp(s, "standard") == 0)) { - add_lpd_control_line(metadata, 'L', user); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-sheets", s); - } - - /* Jobname */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "job-name", &s); - if (s != NULL) { - add_lpd_control_line(metadata, 'J', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-name", s); - } - - /* User to mail when job is done - lpr -m */ - bool = PAPI_FALSE; - papiAttributeListGetBoolean(attributes, NULL, "rfc-1179-mail", &bool); - if (bool == PAPI_TRUE) { - add_lpd_control_line(metadata, 'M', user); - papiAttributeListAddBoolean(used, PAPI_ATTR_EXCL, - "rfc-1179-mail", bool); - } - - /* Title for pr */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "pr-title", &s); - if (s != NULL) { - add_lpd_control_line(metadata, 'T', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "pr-title", s); - } - - /* Indent - used with pr filter */ - integer = 0; - papiAttributeListGetInteger(attributes, NULL, "pr-indent", &integer); - if (integer >= 1) { - add_int_control_line(metadata, 'I', integer, LPD_RFC); - papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, - "pr-indent", integer); - } - - /* Width - used with pr filter */ - integer = 0; - papiAttributeListGetInteger(attributes, NULL, "pr-width", &integer); - if (integer >= 1) { - add_int_control_line(metadata, 'W', integer, LPD_RFC); - papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, - "pr-width", integer); - } - - /* file with Times Roman font lpr -1 */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "rfc-1179-font-r", &s); - if (s != NULL) { - add_lpd_control_line(metadata, '1', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "rfc-1179-font-r", s); - } - - /* file with Times Roman font lpr -2 */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "rfc-1179-font-i", &s); - if (s != NULL) { - add_lpd_control_line(metadata, '2', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "rfc-1179-font-i", s); - } - - /* file with Times Roman font lpr -3 */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "rfc-1179-font-b", &s); - if (s != NULL) { - add_lpd_control_line(metadata, '3', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "rfc-1179-font-b", s); - } - - /* file with Times Roman font lpr -4 */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "rfc-1179-font-s", &s); - if (s != NULL) { - add_lpd_control_line(metadata, '4', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "rfc-1179-font-s", s); - } - - /* - * The document format needs to be added, but the control line - * should be added when the filenames are figured out. - */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "document-format", &s); - if (s != NULL) { - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "document-format", s); - } - - return (status); -} - -static char * -unused_attributes(papi_attribute_t **list, papi_attribute_t **used) -{ - char *result = NULL; - char **names = NULL; - int i; - - if ((list == NULL) || (used == NULL)) - return (NULL); - - for (i = 0; used[i] != NULL; i++) - list_append(&names, used[i]->name); - - if (names != NULL) { - papi_attribute_t **unused = NULL; - - /* add these to the list of things to ignore */ - list_append(&names, "document-format"); - list_append(&names, "copies"); - - split_and_copy_attributes(names, list, NULL, &unused); - if (unused != NULL) { - size_t size = 0; - - do { - size += 1024; - if (result != NULL) - free(result); - result = calloc(1, size); - } while (papiAttributeListToString(unused, " ", - result, size) != PAPI_OK); - papiAttributeListFree(unused); - } - free(names); - } - - return (result); -} - -/* - * lpd_add_svr4_attributes - * Solaris 2.x LP - BSD protocol extensions - */ -static papi_status_t -lpd_add_svr4_attributes(service_t *svc, papi_attribute_t **attributes, - char **metadata, papi_attribute_t ***used) -{ - papi_attribute_t *tmp[2]; - char *s; - int integer; - - if (svc == NULL) - return (PAPI_BAD_REQUEST); - - /* media */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "media", &s); - if (s != NULL) { - add_svr4_control_line(metadata, 'f', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "media", s); - } - - /* Handling */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "job-hold-until", &s); - if ((s != NULL) && (strcmp(s, "indefinite") == 0)) { - add_svr4_control_line(metadata, 'H', "hold"); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-hold-until", "indefinite"); - } else if ((s != NULL) && (strcmp(s, "no-hold") == 0)) { - add_svr4_control_line(metadata, 'H', "immediate"); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-hold-until", "no-hold"); - } else if (s != NULL) { - add_svr4_control_line(metadata, 'H', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "job-hold-until", s); - } - - /* Pages */ - s = NULL; - memset(tmp, NULL, sizeof (tmp)); - tmp[0] = papiAttributeListFind(attributes, "page-ranges"); - if (tmp[0] != NULL) { - char buf[BUFSIZ]; - - papiAttributeListToString(tmp, " ", buf, sizeof (buf)); - if ((s = strchr(buf, '=')) != NULL) { - add_svr4_control_line(metadata, 'P', ++s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "page-ranges", s); - } - } - - /* Priority : lp -q */ - integer = -1; - papiAttributeListGetInteger(attributes, NULL, "job-priority", &integer); - if (integer != -1) { - integer = 40 - (integer / 2.5); - add_int_control_line(metadata, 'q', integer, LPD_SVR4); - papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, - "job-priority", integer); - } - - /* Charset : lp -S */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "lp-charset", &s); - if (s != NULL) { - add_svr4_control_line(metadata, 'S', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "lp-charset", s); - } - - /* Type : done when adding file */ - - /* Mode : lp -y */ - s = NULL; - papiAttributeListGetString(attributes, NULL, "lp-modes", &s); - if (s != NULL) { - add_svr4_control_line(metadata, 'y', s); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "lp-modes", s); - } - - /* Options lp -o are handled elsewhere */ - if ((s = unused_attributes(attributes, *used)) != NULL) { - add_lpd_control_line(metadata, 'O', s); - free(s); - } - - return (PAPI_OK); -} - -papi_status_t -lpd_add_hpux_attributes(service_t *svc, papi_attribute_t **attributes, - char **metadata, papi_attribute_t ***used) -{ - char *s = NULL; - - /* Options lp -o */ - if ((s = unused_attributes(attributes, *used)) != NULL) { - add_hpux_control_line(metadata, s); - free(s); - } - - return (PAPI_OK); -} - -papi_status_t -lpd_job_add_attributes(service_t *svc, papi_attribute_t **attributes, - char **metadata, papi_attribute_t ***used) -{ - if ((svc == NULL) || (metadata == NULL)) - return (PAPI_BAD_REQUEST); - - lpd_add_rfc1179_attributes(svc, attributes, metadata, used); - - /* add protocol extensions if applicable */ - if (svc->uri->fragment != NULL) { - if ((strcasecmp(svc->uri->fragment, "solaris") == 0) || - (strcasecmp(svc->uri->fragment, "svr4") == 0)) - lpd_add_svr4_attributes(svc, attributes, metadata, - used); - else if (strcasecmp(svc->uri->fragment, "hpux") == 0) - lpd_add_hpux_attributes(svc, attributes, metadata, - used); - /* - * others could be added here: - * lprng, sco, aix, digital unix, xerox, ... - */ - } - - return (PAPI_OK); -} - -papi_status_t -lpd_job_add_files(service_t *svc, papi_attribute_t **attributes, - char **files, char **metadata, papi_attribute_t ***used) -{ - char *format = "text/plain"; - char rfc_fmt = 'l'; - int copies = 1; - char host[BUFSIZ]; - int i; - - if ((svc == NULL) || (attributes == NULL) || (files == NULL) || - (metadata == NULL)) - return (PAPI_BAD_ARGUMENT); - - papiAttributeListGetString(attributes, NULL, "document-format", - &format); - papiAttributeListAddString(used, PAPI_ATTR_EXCL, - "document-format", format); - if ((rfc_fmt = mime_type_to_rfc1179_type(format)) == '\0') { - if ((svc->uri->fragment != NULL) && - ((strcasecmp(svc->uri->fragment, "solaris") == 0) || - (strcasecmp(svc->uri->fragment, "svr4") == 0))) - add_svr4_control_line(metadata, 'T', format); - rfc_fmt = 'l'; - } - - papiAttributeListGetInteger(attributes, NULL, "copies", &copies); - if (copies < 1) - copies = 1; - papiAttributeListAddInteger(used, PAPI_ATTR_EXCL, "copies", copies); - - gethostname(host, sizeof (host)); - - for (i = 0; files[i] != NULL; i++) { - char name[BUFSIZ]; - struct stat statbuf; - char key; - int j; - - if ((strcmp("standard input", files[i]) != 0) && - (access(files[i], R_OK) < 0)) { - detailed_error(svc, gettext("aborting request, %s: %s"), - files[i], strerror(errno)); - return (PAPI_NOT_AUTHORIZED); - } - if (strcmp("standard input", files[i]) != 0) { - if (stat(files[i], &statbuf) < 0) { - detailed_error(svc, - gettext("Cannot access file: %s: %s"), - files[i], strerror(errno)); - return (PAPI_DOCUMENT_ACCESS_ERROR); - } - if (statbuf.st_size == 0) { - detailed_error(svc, - gettext("Zero byte (empty) file: %s"), - files[i]); - return (PAPI_BAD_ARGUMENT); - } - } - - if (i < 26) - key = 'A' + i; - else if (i < 52) - key = 'a' + (i - 26); - else if (i < 62) - key = '0' + (i - 52); - else { - detailed_error(svc, - gettext("too many files, truncated at 62")); - return (PAPI_OK_SUBST); - } - - snprintf(name, sizeof (name), "df%cXXX%s", key, host); - - for (j = 0; j < copies; j++) - add_lpd_control_line(metadata, rfc_fmt, name); - add_lpd_control_line(metadata, 'U', name); - add_lpd_control_line(metadata, 'N', (char *)files[i]); - } - - return (PAPI_OK); -} - -papi_status_t -lpd_submit_job(service_t *svc, char *metadata, papi_attribute_t ***attributes, - int *ofd) -{ - papi_status_t status = PAPI_INTERNAL_ERROR; - int fd; - char path[32]; - char *list[2]; - - if ((svc == NULL) || (metadata == NULL)) - return (PAPI_BAD_ARGUMENT); - - strcpy(path, "/tmp/lpd-job-XXXXXX"); - fd = mkstemp(path); - write(fd, metadata, strlen(metadata)); - close(fd); - - list[0] = path; - list[1] = NULL; - - if (((fd = lpd_open(svc, 's', list, 15)) < 0) && (errno != EBADMSG)) { - switch (errno) { - case ENOSPC: - status = PAPI_TEMPORARY_ERROR; - break; - case EIO: - status = PAPI_TEMPORARY_ERROR; - break; - case ECONNREFUSED: - status = PAPI_SERVICE_UNAVAILABLE; - break; - case ENOENT: - status = PAPI_NOT_ACCEPTING; - break; - case EBADMSG: - case EBADF: - status = PAPI_OK; - break; - default: - status = PAPI_TIMEOUT; - break; - } - } else - status = PAPI_OK; - - if (ofd != NULL) - *ofd = fd; - else - close(fd); - - /* read the ID and add it to to the job */ - if ((fd = open(path, O_RDONLY)) >= 0) { - int job_id = 0; - read(fd, &job_id, sizeof (job_id)); - papiAttributeListAddInteger(attributes, PAPI_ATTR_REPLACE, - "job-id", job_id); - close(fd); - } - - unlink(path); - - return (status); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c b/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c deleted file mode 100644 index 1dc9589d25..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/lpd-misc.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: lpd-misc.c 155 2006-04-26 02:34:54Z ktou $ */ - -#define __EXTENSIONS__ /* for strtok_r() */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <fcntl.h> -#include <stdarg.h> -#include <string.h> -#include <signal.h> -#include <sys/socket.h> -#include <errno.h> -#include <wait.h> -#include <stropts.h> -#include <papi_impl.h> - -#include <config-site.h> - -char * -fdgets(char *buf, size_t len, int fd) -{ - char tmp; - int count = 0; - - memset(buf, 0, len); - while ((count < len) && (read(fd, &tmp, 1) > 0)) - if ((buf[count++] = tmp) == '\n') break; - - if (count != 0) - return (buf); - return (NULL); -} - -char * -queue_name_from_uri(uri_t *uri) -{ - char *result = NULL; - - if ((uri != NULL) && (uri->path != NULL)) { - char *ptr = strrchr(uri->path, '/'); - - if (ptr == NULL) - result = uri->path; - else - result = ++ptr; - } - - return (result); -} - -static int -recvfd(int sockfd) -{ - int fd = -1; -#if defined(sun) && defined(unix) && defined(I_RECVFD) - struct strrecvfd recv_fd; - - memset(&recv_fd, NULL, sizeof (recv_fd)); - if (ioctl(sockfd, I_RECVFD, &recv_fd) == 0) - fd = recv_fd.fd; -#else - struct iovec iov[1]; - struct msghdr msg; - -#ifdef CMSG_DATA - struct cmsghdr cmp[1]; - char buf[24]; /* send/recv 2 byte protocol */ - - memset(buf, 0, sizeof (buf)); - - iov[0].iov_base = buf; - iov[0].iov_len = sizeof (buf); - - msg.msg_control = cmp; - msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); -#else - iov[0].iov_base = NULL; - iov[0].iov_len = 0; - msg.msg_accrights = (caddr_t)&fd; - msg.msg_accrights = sizeof (fd); -#endif - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - - if (recvmsg(sockfd, &msg, 0) < 0) - fd = -1; -#ifdef CMSG_DATA - else - fd = * (int *)CMSG_DATA(cmp); -#endif -#endif - return (fd); -} - -int -lpd_open(service_t *svc, char type, char **args, int timeout) -{ - int ac, rc = -1, fds[2]; - pid_t pid; - char *av[64], *tmp, buf[BUFSIZ]; - - if ((svc == NULL) || (svc->uri == NULL)) - return (-1); - -#ifndef SUID_LPD_PORT -#define SUID_LPD_PORT "/usr/lib/print/lpd-port" -#endif - - av[0] = SUID_LPD_PORT; ac = 1; - - /* server */ - av[ac++] = "-H"; - av[ac++] = svc->uri->host; - - /* timeout */ - if (timeout > 0) { - snprintf(buf, sizeof (buf), "%d", timeout); - av[ac++] = "-t"; - av[ac++] = strdup(buf); - } - - /* operation */ - snprintf(buf, sizeof (buf), "-%c", type); - av[ac++] = buf; - - /* queue */ - if (svc->uri->path == NULL) { - tmp = ""; - } else { - if ((tmp = strrchr(svc->uri->path, '/')) == NULL) - tmp = svc->uri->path; - else - tmp++; - } - av[ac++] = tmp; - - /* args */ - if (args != NULL) - while ((*args != NULL) && (ac < 62)) - av[ac++] = *args++; - - av[ac++] = NULL; - -#if defined(sun) && defined(unix) && defined(I_RECVFD) - pipe(fds); -#else - socketpair(AF_UNIX, SOCK_STREAM, 0, fds); -#endif - - switch (pid = fork()) { - case -1: /* failed */ - break; - case 0: /* child */ - dup2(fds[1], 1); - execv(av[0], &av[0]); - perror("exec"); - exit(1); - break; - default: { /* parent */ - int err, status = 0; - - while ((waitpid(pid, &status, 0) < 0) && (errno == EINTR)); - errno = WEXITSTATUS(status); - - if (errno == 0) - rc = recvfd(fds[0]); - - err = errno; - close(fds[0]); - close(fds[1]); - errno = err; - } - } - - return (rc); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-port.c b/usr/src/lib/print/libpapi-lpd/common/lpd-port.c deleted file mode 100644 index 5c6c2e3ff8..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/lpd-port.c +++ /dev/null @@ -1,823 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: lpd-port.c 155 2006-04-26 02:34:54Z ktou $ */ - -#include <config-site.h> - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdarg.h> -#include <string.h> -#include <signal.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <errno.h> -#include <syslog.h> -#include <values.h> -#include <stropts.h> /* for sendfd */ -#include <sys/uio.h> /* for sendmsg stuff */ -#include <pwd.h> -#include <sys/sendfile.h> -#include <ctype.h> -#ifdef HAVE_PRIV_H -#include <priv.h> -#endif - -#ifndef JOB_ID_FILE -#define JOB_ID_FILE "/var/run/rfc-1179.seq" -#endif /* JOB_ID_FILE */ - -static int -sendfd(int sockfd, int fd) -{ - syslog(LOG_DEBUG, "sendfd(%d, %d)", sockfd, fd); - -#if defined(sun) && defined(unix) && defined(I_SENDFD) - return (ioctl(sockfd, I_SENDFD, fd)); -#else - struct iovec iov[1]; - struct msghdr msg; -#ifdef CMSG_DATA - struct cmsghdr cmp[1]; - char buf[2]; /* send/recv 2 byte protocol */ - - iov[0].iov_base = buf; - iov[0].iov_len = 2; - - cmp[0].cmsg_level = SOL_SOCKET; - cmp[0].cmsg_type = SCM_RIGHTS; - cmp[0].cmsg_len = sizeof (struct cmsghdr) + sizeof (int); - * (int *)CMSG_DATA(cmp) = fd; - - buf[1] = 0; - buf[0] = 0; - msg.msg_control = cmp; - msg.msg_controllen = sizeof (struct cmsghdr) + sizeof (int); -#else - iov[0].iov_base = NULL; - iov[0].iov_len = 0; - msg.msg_accrights = (caddr_t)&fd; - msg.msg_accrights = sizeof (fd); -#endif - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - - return (sendmsg(sockfd, &msg, 0)); -#endif -} - -static void -null(int i) -{ -} - -static int -sock_connect(int sock, char *host, int timeout) -{ - struct hostent *hp; - struct servent *sp; -#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) - struct sockaddr_in6 sin; -#else - struct sockaddr_in sin; -#endif - static void (*old_handler)(); - int err, error_num; - unsigned timo = 1; - - /* - * Get the host address and port number to connect to. - */ - if (host == NULL) { - return (-1); - } - - /* linux style NULL usage */ - (void) memset((char *)&sin, (int)NULL, sizeof (sin)); - -#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) - if ((hp = getipnodebyname(host, AF_INET6, AI_DEFAULT, - &error_num)) == NULL) { - errno = ENOENT; - return (-1); - } - (void) memcpy((caddr_t)&sin.sin6_addr, hp->h_addr, hp->h_length); - sin.sin6_family = hp->h_addrtype; -#else - if ((hp = gethostbyname(host)) == NULL) { - errno = ENOENT; - return (-1); - } - - (void) memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length); - sin.sin_family = hp->h_addrtype; -#endif - - if ((sp = getservbyname("printer", "tcp")) == NULL) { - errno = ENOENT; - return (-1); - } - -#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) - sin.sin6_port = sp->s_port; -#else - sin.sin_port = sp->s_port; -#endif - -retry: - old_handler = signal(SIGALRM, null); - (void) alarm(timeout); - - if (connect(sock, (struct sockaddr *)&sin, sizeof (sin)) < 0) { - (void) alarm(0); - (void) signal(SIGALRM, old_handler); - - if (errno == ECONNREFUSED && timo <= 16) { - (void) sleep(timo); - timo *= 2; - goto retry; - } - - return (-1); - } - - (void) alarm(0); - (void) signal(SIGALRM, old_handler); - return (sock); -} - -static int -next_job_id() -{ - int fd, result = getpid() % 1000; - - /* gain back enough privilege to open the id file */ -#ifdef PRIV_ALLSETS - if ((priv_set(PRIV_ON, PRIV_EFFECTIVE, - PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL)) < 0) { - syslog(LOG_ERR, "lpd_port:next_job_id:priv_set fails: : %m"); - return (-1); - } -#else - seteuid(0); -#endif - - /* open the sequence file */ - if (((fd = open(JOB_ID_FILE, O_RDWR)) < 0) && (errno == ENOENT)) - fd = open(JOB_ID_FILE, O_CREAT|O_EXCL|O_RDWR, 0644); - - syslog(LOG_DEBUG, "sequence file fd: %d", fd); - - /* drop our privilege again */ -#ifdef PRIV_ALLSETS - /* drop file access privilege */ - priv_set(PRIV_OFF, PRIV_PERMITTED, - PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, NULL); -#else - seteuid(getuid()); -#endif - - if (fd >= 0) { - /* wait for a lock on the file */ - if (lockf(fd, F_LOCK, 0) == 0) { - char buf[8]; - int next; - - /* get the current id */ - (void) memset(buf, 0, sizeof (buf)); - if (read(fd, buf, sizeof (buf)) > 0) - result = atoi(buf); - - next = ((result < 999) ? (result + 1) : 0); - - /* store the next id in the file */ - snprintf(buf, sizeof (buf), "%.3d", next); - if ((lseek(fd, 0, SEEK_SET) == 0) && - (ftruncate(fd, 0) == 0)) - write(fd, buf, strlen(buf)); - } - close(fd); - } - syslog(LOG_DEBUG, "next_job_id() is %d", result); - - return (result); -} - -static int -reserved_port() -{ - int result = -1; - int port; - - /* gain back enough privilege to open a reserved port */ -#ifdef PRIV_ALLSETS - if ((priv_set( - PRIV_ON, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, NULL)) != 0) { - syslog(LOG_ERR, "priv_set fails for net_privaddr %m"); - return (-1); - } -#else - seteuid(0); -#endif - -#if defined(HAVE_GETIPNODEBYNAME) && defined(HAVE_RRESVPORT_AF) - port = 0; /* set to 0, rresvport_af() will find us one. */ - result = rresvport_af(&port, AF_INET6); -#else - port = IPPORT_RESERVED - 1; - while (((result = rresvport(&port)) < 0) && (port >= 0)) - port--; -#endif - - /* drop our privilege again */ -#ifdef PRIV_ALLSETS - priv_set(PRIV_OFF, PRIV_PERMITTED, PRIV_NET_PRIVADDR, NULL); -#else - seteuid(getuid()); -#endif - - return (result); -} - -static char * -get_user_name() -{ - static struct passwd *p = NULL; - - if ((p = getpwuid(getuid())) != NULL) - return (p->pw_name); - else - return ("unknown"); -} - -static void -add_args(int ac, char **av, char *buf, size_t len) -{ - while (ac--) { - strlcat(buf, " ", len); - strlcat(buf, *(av++), len); - } -} - -static int -massage_control_data(char *data, int id) -{ - char *line, *iter = NULL; - char *ptr, *mod_ptr, *datacpy; - char host[BUFSIZ]; - int host_present = 0; - - if (gethostname(host, sizeof (host)) != 0) - return (-1); - - if ((datacpy = strdup(data)) == NULL) { - return (-1); - } - - for (ptr = strtok_r(datacpy, "\n", &iter); ptr != NULL; - ptr = strtok_r(NULL, "\n", &iter)) { - - if (ptr[0] == 'H') { - if (strncmp(++ptr, host, strlen(host)) != 0) { - free(datacpy); - return (-1); - } - host_present = 1; - } else if ((ptr[0] == 'P') || (ptr[0] == 'L')) { - /* check the user name */ - uid_t uid = getuid(); - struct passwd *pw; - int len; - - if (uid == 0) { /* let root do what they want */ - continue; - } - if ((pw = getpwuid(uid)) == NULL) { - free(datacpy); - return (-1); /* failed */ - } - len = strlen(pw->pw_name); - if ((strncmp(++ptr, pw->pw_name, len) != 0)) { - free(datacpy); - return (-1); /* failed */ - } - } else if ((islower(ptr[0]) != 0) || (ptr[0] == 'U')) { - /* check/fix df?XXXhostname */ - ptr++; - - if (strlen(ptr) < 6) { - free(datacpy); - return (-1); - } - - /* - * As ptr is a copy of the string (df?XXX...) the code - * needs to work on the original, hence the need for - * mod_ptr. No need to check for a NULL mod_ptr - * because the required string must already exist as - * ptr is a copy of the original data. - */ - - mod_ptr = strstr(data, ptr); - - if ((mod_ptr[0] == 'd') && (mod_ptr[1] == 'f') && - (mod_ptr[3] == 'X') && (mod_ptr[4] == 'X') && - (mod_ptr[5] == 'X')) { - mod_ptr[3] = '0' + (id / 100) % 10; - mod_ptr[4] = '0' + (id / 10) % 10; - mod_ptr[5] = '0' + id % 10; - - if (strncmp(&mod_ptr[6], host, strlen(host)) - != 0) { - free(datacpy); - return (-1); - } - } else { - free(datacpy); - return (-1); - } - } - - } - free(datacpy); - - if (!host_present) { - return (-1); - } - - return (1); -} - -static int -send_lpd_message(int fd, char *fmt, ...) -{ - char buf[BUFSIZ]; - size_t size; - va_list ap; - - va_start(ap, fmt); - size = vsnprintf(buf, sizeof (buf), fmt, ap); - va_end(ap); - if (size == 0) - size = 1; - - syslog(LOG_DEBUG, "lpd_messsage(%d, %s)", fd, buf); - - if (write(fd, buf, size) != size) { - errno = EIO; - return (-1); - } - - if ((read(fd, buf, 1) != 1) || (buf[0] != 0)) - return (-1); - - return (0); -} - -static int -send_data_file(int sock, char *dfname, char *name) -{ - size_t len; - off_t off = 0; - struct stat st; - char buf[32]; - int fd = -1; - - if (strcmp(name, "standard input") != 0) { - if ((fd = open(name, O_RDONLY)) < 0) - return (-1); - - if (fstat(fd, &st) < 0) - return (-1); - } else - st.st_size = MAXINT; /* should be 0 */ - - /* request data file transfer, read ack/nack */ - errno = ENOSPC; - if (send_lpd_message(sock, "\003%d %s\n", st.st_size, dfname) < 0) - return (-1); - - if (fd != -1) { - /* write the data */ - if (sendfile(sock, fd, &off, st.st_size) != st.st_size) - return (-1); - close(fd); - - /* request ack/nack after the data transfer */ - errno = EIO; - if (send_lpd_message(sock, "") < 0) - return (-1); - } - - return (0); -} - -static int -send_control_file(int sock, char *data, int id) -{ - int len; - char buf[BUFSIZ]; - char *ptr, *iter = NULL; - char *datacpy = NULL; - char *host = NULL; - - len = strlen(data); - - if ((datacpy = strdup(data)) == NULL) - return (-1); - - syslog(LOG_DEBUG, "cfA: %s\n", datacpy); - - for (ptr = strtok_r(datacpy, "\n", &iter); ptr != NULL; - ptr = strtok_r(NULL, "\n", &iter)) { - - if (ptr[0] != 'H') - continue; - - ptr++; - host = ptr; - syslog(LOG_DEBUG, "hostname: %s\n", host); - } - - free(datacpy); - - /* request data file transfer, read ack/nack */ - errno = ENOSPC; - if (send_lpd_message(sock, "\002%d cfA%.3d%s\n", len, id, host) < 0) - return (-1); - - /* write the data */ - if (write(sock, data, len) != len) - return (-1); - - /* request ack/nack after the data transfer */ - errno = EIO; - if (send_lpd_message(sock, "") < 0) - return (-1); - - return (0); -} - - -static int -submit_job(int sock, char *printer, int job_id, char *path) -{ - struct stat st; - int current = 0; - off_t off = 0; - char *metadata = NULL; - char *ptr, *iter = NULL; - int fd, err; - int sent_files = 0; - char buf[BUFSIZ]; - size_t len; - - /* open the control file */ - if ((fd = open(path, O_RDONLY)) < 0) { - syslog(LOG_ERR, "submit_job(%d, %s, %d, %s): open(): %m", - sock, printer, job_id, path); - return (-1); - } - - /* get the size of the control file */ - if (fstat(fd, &st) < 0) { - syslog(LOG_ERR, "submit_job(%d, %s, %d, %s): fstat(): %m", - sock, printer, job_id, path); - close(fd); - return (-1); - } - - /* allocate memory for the control file */ - if ((metadata = calloc(1, st.st_size + 1)) == NULL) { - syslog(LOG_ERR, "submit_job(%d, %s, %d, %s): calloc(): %m", - sock, printer, job_id, path); - close(fd); - return (-1); - } - - /* read in the control file */ - if (read(fd, metadata, st.st_size) != st.st_size) { - syslog(LOG_ERR, "submit_job(%d, %s, %d, %s): read(): %m", - sock, printer, job_id, path); - free(metadata); - close(fd); - return (-1); - } - - /* massage the control file */ - if (massage_control_data(metadata, job_id) < 0) { - /* bad control data, dump the job */ - syslog(LOG_ALERT, - "bad control file, possible subversion attempt"); - free(metadata); - errno = EINVAL; - close(fd); - return (-1); - } - - /* request to transfer the job */ - if (send_lpd_message(sock, "\002%s\n", printer) < 0) { - /* no such (or disabled) queue, got to love rfc-1179 */ - errno = ENOENT; - return (-1); - } - - /* send the control data */ - if (send_control_file(sock, metadata, job_id) < 0) { - err = errno; - write(sock, "\001\n", 2); /* abort */ - errno = err; - return (-1); - } - - /* walk the control file sending the data files */ - for (ptr = strtok_r(metadata, "\n", &iter); ptr != NULL; - ptr = strtok_r(NULL, "\n", &iter)) { - char *name = NULL; - - if (ptr[0] != 'U') - continue; - - name = strtok_r(NULL, "\n", &iter); - if (name[0] != 'N') - continue; - - ptr++; - name++; - - if (send_data_file(sock, ptr, name) < 0) { - err = errno; - write(sock, "\001\n", 2); /* abort */ - errno = err; - return (-1); - } - if (strcmp(name, "standard input") != 0) - sent_files++; - } - - /* write back the job-id */ - err = errno; - if ((fd = open(path, O_WRONLY)) >= 0) { - ftruncate(fd, 0); - write(fd, &job_id, sizeof (job_id)); - close(fd); - } - errno = err; - - if (sent_files != 0) { - err = errno; - close(sock); - errno = err; - } - - return (0); -} -static int -query(int fd, char *printer, int ac, char **av) -{ - char buf[BUFSIZ]; - int rc, len; - - /* build the request */ - snprintf(buf, sizeof (buf), "\04%s", printer); - add_args(ac, av, buf, sizeof (buf)); - strlcat(buf, "\n", sizeof (buf)); - len = strlen(buf); - - if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) { - errno = EMSGSIZE; - rc = -1; - } else - rc = 0; - - return (rc); -} - -static int -cancel(int fd, char *printer, int ac, char **av) -{ - char buf[BUFSIZ]; - int rc, len; - - /* build the request */ - snprintf(buf, sizeof (buf), "\05%s %s", printer, get_user_name()); - add_args(ac, av, buf, sizeof (buf)); - strlcat(buf, "\n", sizeof (buf)); - len = strlen(buf); - - if (((rc = write(fd, buf, len)) >= 0) && (rc != len)) { - errno = EMSGSIZE; - rc = -1; - } else - rc = 0; - - return (rc); -} - -static void -usage(char *program) -{ - char *name; - - setreuid(getuid(), getuid()); - - if ((name = strrchr(program, '/')) == NULL) - name = program; - else - name++; - - fprintf(stderr, "usage:\t%s -H host [-t timeout] -s queue control ]\n", - name); - fprintf(stderr, "\t%s -H host [-t timeout] -c queue [user|job ...]\n", - name); - fprintf(stderr, "\t%s -H host [-t timeout] -q queue [user|job ...]\n", - name); - exit(EINVAL); -} - -/* - * The main program temporarily loses privilege while searching the command - * line arguments. It then allocates any resources it need privilege for - * job-id, reserved port. Once it has the resources it needs, it perminently - * drops all elevated privilege. It ghen connects to the remote print service - * based on destination hostname. Doing it this way reduces the potenential - * opportunity for a breakout with elevated privilege, breakout with an - * unconnected reserved port, and exploitation of the remote print service - * by a calling program. - */ -int -main(int ac, char *av[]) -{ - enum { OP_NONE, OP_SUBMIT, OP_QUERY, OP_CANCEL } operation = OP_NONE; - int fd, c, timeout = 0, exit_code = 0; - char *host = NULL, *queue = NULL; - uid_t uid = getuid(); -#ifdef PRIV_ALLSETS - priv_set_t *saveset; -#endif - - openlog("lpd-port", LOG_PID, LOG_LPR); - -#ifdef PRIV_ALLSETS - - /* lose as much as we can perminently and temporarily drop the rest. */ - - if ((saveset = priv_allocset()) == NULL) { - syslog(LOG_ERR, "lpd_port: priv_allocset saveset failed: %m\n"); - return (-1); - } - - priv_basicset(saveset); - (void) priv_addset(saveset, PRIV_NET_PRIVADDR); - (void) priv_addset(saveset, PRIV_FILE_DAC_READ); - (void) priv_addset(saveset, PRIV_FILE_DAC_WRITE); - - if ((setppriv(PRIV_SET, PRIV_PERMITTED, saveset)) < 0) { - syslog(LOG_ERR, "lpd_port:setppriv:priv_set failed: %m"); - return (-1); - } - - priv_freeset(saveset); - - /* - * These privileges permanently dropped in next_job_id() and - * reserved_port() - */ - - if (priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_NET_PRIVADDR, - PRIV_FILE_DAC_READ, PRIV_FILE_DAC_WRITE, (char *)NULL) < 0) { - syslog(LOG_ERR, "lpd_port:priv_set:priv_off failed: %m"); - return (-1); - } - - syslog(LOG_DEBUG, "using privs"); -#else - - syslog(LOG_DEBUG, "no privs"); - seteuid(uid); -#endif - - while ((c = getopt(ac, av, "H:t:c:q:s:")) != EOF) { - switch (c) { - case 'H': - host = optarg; - break; - case 't': - timeout = atoi(optarg); - break; - case 'c': - if (operation != OP_NONE) - usage(av[0]); - operation = OP_CANCEL; - queue = optarg; - break; - case 'q': - if (operation != OP_NONE) - usage(av[0]); - operation = OP_QUERY; - queue = optarg; - break; - case 's': - if (operation != OP_NONE) - usage(av[0]); - operation = OP_SUBMIT; - queue = optarg; - break; - default: - usage(av[0]); - /* does not return */ - } - } - - if ((host == NULL) || (queue == NULL) || (timeout < 0) || - (operation == OP_NONE)) - usage(av[0]); - - if (operation == OP_SUBMIT) /* get a job-id if we need it */ - if ((c = next_job_id()) < 0) { - syslog(LOG_ERR, "lpd_port:main:next_job_id fails"); - return (-1); - } - - if ((fd = reserved_port()) < 0) { - syslog(LOG_ERR, "reserved_port() failed %m"); - return (errno); - } - - /* - * we no longer want or need any elevated privilege, lose it all - * permanently. - */ - - setreuid(uid, uid); - - /* connect to the print service */ - if ((fd = sock_connect(fd, host, timeout)) < 0) - return (errno); - - /* perform the requested operation */ - switch (operation) { - case OP_SUBMIT: /* transfer the job, close the fd */ - if (submit_job(fd, queue, c, av[optind]) < 0) - exit_code = errno; - break; - case OP_QUERY: /* send the query string, return the fd */ - if (query(fd, queue, ac - optind, &av[optind]) < 0) - exit_code = errno; - break; - case OP_CANCEL: /* send the cancel string, return the fd */ - if (cancel(fd, queue, ac - optind, &av[optind]) < 0) - exit_code = errno; - break; - default: /* This should never happen */ - exit_code = EINVAL; - } - - - /* if the operation succeeded, send the fd to our parent */ - if ((exit_code == 0) && (sendfd(1, fd) < 0)) { - char buf[BUFSIZ]; - - exit_code = errno; - - /* sendfd() failed, dump the socket data for the heck of it */ - while ((c = read(fd, buf, sizeof (buf))) > 0) - write(1, buf, c); - } - - syslog(LOG_DEBUG, "exit code: %d", exit_code); - return (exit_code); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/lpd-query.c b/usr/src/lib/print/libpapi-lpd/common/lpd-query.c deleted file mode 100644 index 964023c919..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/lpd-query.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/* $Id: lpd-query.c 155 2006-04-26 02:34:54Z ktou $ */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/fcntl.h> -#include <time.h> -#include <ctype.h> -#include <string.h> -#include <stdarg.h> -#include <regex.h> - -#include <papi_impl.h> - -/* The string is modified by this call */ -static char * -regvalue(regmatch_t match, char *string) -{ - char *result = NULL; - - if (match.rm_so != match.rm_eo) { - result = string + match.rm_so; - *(result + (match.rm_eo - match.rm_so)) = '\0'; - } - - return (result); -} - -/* - * Print job entries start with: - * (user): (rank) [job (number) (...)] - * (user) is the job-owner's user name - * (rank) is the rank in queue. (active, 1st, 2nd, ...) - * (number) is the job number - * (...) is an optional hostname - * some servers will use whitespace a little differently than is displayed - * above. The regular expression below makes whitespace optional in some - * places. - */ -static char *job_expr = "^(.*[[:alnum:]]):[[:space:]]+([[:alnum:]]+)"\ - "[[:space:]]+[[][[:space:]]*job[[:space:]]*([[:digit:]]+)"\ - "[[:space:]]*(.*)]"; -static regex_t job_re; - -/* - * Print job entries for remote windows printer start with: - * Owner Status Jobname Job-Id Size Pages Priority - * e.g: - * Owner Status Jobname Job-Id Size Pages Priority - * ------------------------------------------------------------ - * root (10.3. Waiting /etc/release 2 240 1 4 - * - * Owner is the job-owner's user name - * Status is the job-status (printing, waiting, error) - * Jobname is the name of the job to be printed - * Job-Id is the id of the job queued to be printed - * Size is the size of the job in bytes - * Pages is the number of pages of the job - * Priority is the job-priority - */ -static char *wjob_expr = "^([[:alnum:]]+)[[:space:]]*[(](.*)[)]*[[:space:]]"\ - "+([[:alnum:]]+)[[:space:]]+(.*)([[:alnum:]]+)(.*)[[:space:]]+"\ - "([[:digit:]]+)[[:space:]]+([[:digit:]]+)[[:space:]]+([[:digit:]]+)"\ - "[[:space:]]+([[:digit:]]+)"; -static regex_t wjob_re; - -/* - * Windows job header is in the following format - * Owner Status Jobname Job-Id Size Pages Priority - * -------------------------------------------------------------- - */ -static char *whjob_expr = "Owner Status Jobname Job-Id"\ - " Size Pages Priority"; -static regex_t whjob_re; - -static char *wline_expr = "----------"; -static regex_t wline_re; - -/* - * status line(s) for "processing" printers will contain one of the following: - * ready and printing - * Printing - * processing - */ -static char *proc_expr = "(ready and printing|printing|processing)"; -static regex_t proc_re; - -/* - * status line(s) for "idle" printers will contain one of the following: - * no entries - * (printer) is ready - * idle - */ -static char *idle_expr = "(no entries|is ready| idle)"; -static regex_t idle_re; - -/* - * Printer state reason (For Windows remote printers) - * Paused - */ -static char *state_reason_expr = "(Paused)"; -static regex_t state_reason_re; - -/* - * document line(s) - * (copies) copies of (name) (size) bytes - * (name) (size) bytes - * document lines can be in either format above. - * (copies) is the number of copies of the document to print - * (name) is the name of the document: /etc/motd, ... - * (size) is the number of bytes in the document data - */ -static char *doc1_expr = "[[:space:]]+(([[:digit:]]+) copies of )"\ - "([^[:space:]]+)[[:space:]]*([[:digit:]]+) bytes"; -static char *doc2_expr = "[[:space:]]+()([^[:space:]]+)[[:space:]]*"\ - "([[:digit:]]+) bytes"; -static regex_t doc1_re; -static regex_t doc2_re; - -/* Printer-state for Windows */ -static int win_state = 0x03; /* Idle */ - -static void -parse_lpd_job(service_t *svc, job_t **job, int fd, char *line, int len) -{ - papi_attribute_t **attributes = NULL; - regmatch_t matches[10]; - char *s; - int octets = 0; - int flag = 0; - - /* - * job_re and wjob_re were compiled in the calling function - * first check for solaris jobs - * if there is no-match check for windows jobs - */ - - if (regexec(&job_re, line, (size_t)5, matches, 0) == REG_NOMATCH) { - if (regexec(&wjob_re, line, (size_t)10, matches, 0) - == REG_NOMATCH) - return; - else - flag = 1; - } - - if (flag == 1) { - /* Windows job */ - /* first match is job-id */ - - if ((s = regvalue(matches[1], line)) == NULL) - s = "nobody"; - papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, - "job-originating-user-name", s); - - if ((s = regvalue(matches[4], line)) == NULL) - s = "unknown"; - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "job-name", s); - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "job-file-names", s); - - if ((s = regvalue(matches[7], line)) == NULL) - s = "0"; - papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, - "job-id", atoi(s)); - - if ((s = regvalue(matches[8], line)) == NULL) - s = "0"; - octets = atoi(s); - papiAttributeListAddInteger(&attributes, - PAPI_ATTR_APPEND, "job-file-sizes", atoi(s)); - - /* - * Since a job has been found so the printer state is either - * 'stopped' or 'processing' - * By default it is "processing" - */ - win_state = 0x04; - } else { - /* Solaris job */ - if ((s = regvalue(matches[1], line)) == NULL) - s = "nobody"; - papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, - "job-originating-user-name", s); - - if ((s = regvalue(matches[2], line)) == NULL) - s = "0"; - papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, - "number-of-intervening-jobs", atoi(s) - 1); - - if ((s = regvalue(matches[3], line)) == NULL) - s = "0"; - papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, - "job-id", atoi(s)); - - if ((s = regvalue(matches[4], line)) == NULL) - s = svc->uri->host; - papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, - "job-originating-host-name", s); - } - - while ((fdgets(line, len, fd) != NULL) && - (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && - (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { - int size = 0, copies = 1; - /* process copies/documents */ - - /* doc1_re and doc2_re were compiled in the calling function */ - if ((regexec(&doc1_re, line, (size_t)4, matches, 0) != 0) && - (regexec(&doc2_re, line, (size_t)4, matches, 0) != 0)) - continue; - - if ((s = regvalue(matches[1], line)) == NULL) - s = "1"; - if ((copies = atoi(s)) < 1) - copies = 1; - - if ((s = regvalue(matches[2], line)) == NULL) - s = "unknown"; - papiAttributeListAddString(&attributes, - PAPI_ATTR_APPEND, "job-name", s); - papiAttributeListAddString(&attributes, - PAPI_ATTR_APPEND, "job-file-names", s); - - if ((s = regvalue(matches[3], line)) == NULL) - s = "0"; - size = atoi(s); - - papiAttributeListAddInteger(&attributes, - PAPI_ATTR_APPEND, "job-file-sizes", size); - - octets += (size * copies); - } - - papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, - "job-k-octets", octets/1024); - papiAttributeListAddInteger(&attributes, PAPI_ATTR_APPEND, - "job-octets", octets); - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "printer-name", queue_name_from_uri(svc->uri)); - - if ((*job = (job_t *)calloc(1, sizeof (**job))) != NULL) - (*job)->attributes = attributes; -} - -void -parse_lpd_query(service_t *svc, int fd) -{ - papi_attribute_t **attributes = NULL; - cache_t *cache = NULL; - int state = 0x03; /* idle */ - char line[128]; - char status[1024]; - char *s; - int win_flag = 0; - - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "printer-name", queue_name_from_uri(svc->uri)); - - if (uri_to_string(svc->uri, status, sizeof (status)) == 0) - papiAttributeListAddString(&attributes, PAPI_ATTR_APPEND, - "printer-uri-supported", status); - - /* - * on most systems, status is a single line, but some appear to - * return multi-line status messages. To get the "best" possible - * printer-state-reason, we accumulate the text until we hit the - * first print job entry. - * - * Print job entries start with: - * user: rank [job number ...] - */ - (void) regcomp(&job_re, job_expr, REG_EXTENDED|REG_ICASE); - - /* - * For remote windows printers - * Print job entries start with: - * Owner Status Jobname Job-Id Size Pages Priority - */ - (void) regcomp(&wjob_re, wjob_expr, REG_EXTENDED|REG_ICASE); - (void) regcomp(&whjob_re, whjob_expr, REG_EXTENDED|REG_ICASE); - (void) regcomp(&wline_re, wline_expr, REG_EXTENDED|REG_ICASE); - - status[0] = '\0'; - - while ((fdgets(line, sizeof (line), fd) != NULL) && - (regexec(&job_re, line, (size_t)0, NULL, 0) == REG_NOMATCH) && - (regexec(&wjob_re, line, (size_t)0, NULL, 0) == REG_NOMATCH)) { - /* - * When windows job queue gets queried following header - * should not get printed - * Owner Status Jobname Job-Id Size Pages Priority - * ----------------------------------------------- - */ - if ((regexec(&whjob_re, line, (size_t)0, NULL, 0) - == REG_NOMATCH) && - (regexec(&wline_re, line, (size_t)0, NULL, 0) - == REG_NOMATCH)) - strlcat(status, line, sizeof (status)); - } - - /* chop off trailing whitespace */ - s = status + strlen(status) - 1; - while ((s > status) && (isspace(*s) != 0)) - *s-- = '\0'; - - papiAttributeListAddString(&attributes, PAPI_ATTR_REPLACE, - "printer-state-reasons", status); - - /* Check if this is for Windows remote printers */ - if (strstr(status, "Windows")) { - /* - * It is a remote windows printer - * By default set the status as idle - * Set the printer-state after call to "parse_lpd_job" - */ - win_flag = 1; - (void) regcomp(&state_reason_re, state_reason_expr, - REG_EXTENDED|REG_ICASE); - - if (regexec(&state_reason_re, status, (size_t)0, NULL, 0) == 0) - state = 0x05; /* stopped */ - } else { - (void) regcomp(&proc_re, proc_expr, REG_EXTENDED|REG_ICASE); - (void) regcomp(&idle_re, idle_expr, REG_EXTENDED|REG_ICASE); - - if (regexec(&proc_re, status, (size_t)0, NULL, 0) == 0) - state = 0x04; /* processing */ - else if (regexec(&idle_re, status, (size_t)0, NULL, 0) == 0) - state = 0x03; /* idle */ - else - state = 0x05; /* stopped */ - papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, - "printer-state", state); - } - - if ((cache = (cache_t *)calloc(1, sizeof (*cache))) == NULL) - return; - - if ((cache->printer = (printer_t *)calloc(1, sizeof (*cache->printer))) - == NULL) - return; - - cache->printer->attributes = attributes; - svc->cache = cache; - - (void) regcomp(&doc1_re, doc1_expr, REG_EXTENDED|REG_ICASE); - (void) regcomp(&doc2_re, doc2_expr, REG_EXTENDED|REG_ICASE); - /* process job related entries */ - while (line[0] != '\0') { - job_t *job = NULL; - - parse_lpd_job(svc, &job, fd, line, sizeof (line)); - if (job == NULL) - break; - list_append(&cache->jobs, job); - } - - /* - * For remote windows printer set the printer-state - * after parse_lpd_job - */ - if (win_flag) { - if (state == 0x05) - win_state = state; - - papiAttributeListAddInteger(&attributes, PAPI_ATTR_REPLACE, - "printer-state", win_state); - } - time(&cache->timestamp); -} - -void -cache_update(service_t *svc) -{ - int fd; - - if (svc == NULL) - return; - - if (svc->cache != NULL) { /* this should be time based */ - if (svc->cache->jobs == NULL) { - free(svc->cache); - svc->cache = NULL; - } else - return; - } - - if ((fd = lpd_open(svc, 'q', NULL, 15)) < 0) - return; - - parse_lpd_query(svc, fd); - - close(fd); -} - -papi_status_t -lpd_find_printer_info(service_t *svc, printer_t **printer) -{ - papi_status_t result = PAPI_BAD_ARGUMENT; - - if ((svc == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - cache_update(svc); - - if (svc->cache != NULL) { - *printer = svc->cache->printer; - result = PAPI_OK; - } else - result = PAPI_NOT_FOUND; - - return (result); -} - -papi_status_t -lpd_find_jobs_info(service_t *svc, job_t ***jobs) -{ - papi_status_t result = PAPI_BAD_ARGUMENT; - - if (svc != NULL) { - cache_update(svc); - - if (svc->cache != NULL) { - *jobs = svc->cache->jobs; - result = PAPI_OK; - } - } - - /* - * cache jobs is free()-ed in - * libpapi-dynamic/common/printer.c - - * papiPrinterListJobs() cache printer is - * free()-ed by the caller of - * lpd_find_printer_info Invalidate the - * cache by freeing the cache. - */ - free(svc->cache); - svc->cache = NULL; - - return (result); -} - -papi_status_t -lpd_find_job_info(service_t *svc, int job_id, job_t **job) -{ - papi_status_t result = PAPI_BAD_ARGUMENT; - job_t **jobs; - - if ((lpd_find_jobs_info(svc, &jobs) == PAPI_OK) && (jobs != NULL)) { - int i; - - *job = NULL; - for (i = 0; ((*job == NULL) && (jobs[i] != NULL)); i++) { - int id = -1; - - papiAttributeListGetInteger(jobs[i]->attributes, NULL, - "job-id", &id); - if (id == job_id) - *job = jobs[i]; - } - - if (*job != NULL) - result = PAPI_OK; - } - - return (result); -} - -void -cache_free(cache_t *item) -{ - if (item != NULL) { - if (item->printer != NULL) - papiPrinterFree((papi_printer_t *)item->printer); - if (item->jobs != NULL) - papiJobListFree((papi_job_t *)item->jobs); - free(item); - } -} diff --git a/usr/src/lib/print/libpapi-lpd/common/mapfile b/usr/src/lib/print/libpapi-lpd/common/mapfile deleted file mode 100644 index 2ad5020f15..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/mapfile +++ /dev/null @@ -1,322 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# $Id: mapfile.in,v 1.2 2006/03/02 06:31:36 njacobs Exp $ -# - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -# -# Common interfaces that are most likely to be shared amongst the various -# PAPI implementations. -# - -SYMBOL_VERSION SUNW_1.0 { - global: - # PAPI Attribute Calls - papiAttributeListAddValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListAddString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListDelete { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetValue { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetNext { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFind { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetBoolean { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetCollection { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetDatetime { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetInteger { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetMetadata { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetRange { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetResolution { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListGetString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFromString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListToString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListFree { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # PAPI Service Calls - papiServiceCreate ; - papiServiceDestroy ; - papiServiceSetUserName ; - papiServiceSetPassword ; - papiServiceSetEncryption ; - papiServiceSetAuthCB ; - papiServiceSetAppData ; - papiServiceGetUserName ; - papiServiceGetPassword ; - papiServiceGetEncryption ; - papiServiceGetAppData ; - papiServiceGetServiceName ; - papiServiceGetAttributeList ; - papiServiceGetStatusMessage ; - - # PAPI Printer Calls - papiPrintersList { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiPrinterQuery ; - papiPrinterAdd { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiPrinterModify { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiPrinterRemove { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiPrinterDisable ; - papiPrinterEnable ; - papiPrinterPause ; - papiPrinterResume ; - papiPrinterPurgeJobs ; - papiPrinterListJobs ; - papiPrinterGetAttributeList ; - papiPrinterFree ; - papiPrinterListFree ; - - # PAPI Job Calls - papiJobSubmit ; - papiJobSubmitByReference ; - papiJobValidate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobStreamOpen ; - papiJobStreamWrite ; - papiJobStreamClose ; - papiJobQuery ; - papiJobModify { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobMove { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobCancel ; - papiJobHold { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobRelease { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobRestart { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobPromote { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobGetAttributeList ; - papiJobGetPrinterName ; - papiJobGetId ; - papiJobGetJobTicket { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobFree ; - papiJobListFree ; - - # Misc. PAPI Calls - papiStatusString { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiLibrarySupportedCall ; - papiLibrarySupportedCalls ; -} ; - -SYMBOL_VERSION SUNWprivate_1.0 { - global: - papiServiceSetPeer { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobCreate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobStreamAdd { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiJobCommit { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # Misc. supporting calls - # URI - uri_from_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_to_string { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - uri_free { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # list - list_remove { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_append { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - list_concatenate { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - # NS - getprinterbyname { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - is_localhost { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - # extra Attribute Calls - copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - split_and_copy_attributes { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - papiAttributeListPrint { - TYPE = FUNCTION; - FILTER = libpapi-common.so; - } ; - - local: - * ; -} ; diff --git a/usr/src/lib/print/libpapi-lpd/common/papi_impl.h b/usr/src/lib/print/libpapi-lpd/common/papi_impl.h deleted file mode 100644 index 82d955b3cb..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/papi_impl.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -#ifndef _PAPI_IMPL_H -#define _PAPI_IMPL_H - -/* $Id: papi_impl.h 161 2006-05-03 04:32:59Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <papi.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#include <time.h> -#include <sys/types.h> -#include <stdarg.h> -#include <uri.h> - -typedef struct { - papi_attribute_t **attributes; -} printer_t; - -typedef struct job { - papi_attribute_t **attributes; -} job_t; - -typedef struct stream { - job_t *job; /* describes current job */ - int fd; /* the fd to write to */ - char *metadata; /* the converted metadata */ - char *dfname; /* the stream data (if we can't stream) */ - -} stream_t; - -typedef struct { /* used for query operations only */ - time_t timestamp; - printer_t *printer; - job_t **jobs; -} cache_t; - -typedef struct { - papi_attribute_t **attributes; /* extra info */ - uri_t *uri; /* printer uri */ - cache_t *cache; /* printer/job cache */ - int (*authCB)(papi_service_t svc, void *app_data); /* unused */ - void *app_data; /* unused */ -} service_t; - - -extern papi_status_t service_fill_in(service_t *svc, char *name); -extern void detailed_error(service_t *svc, char *fmt, ...); -extern char *queue_name_from_uri(uri_t *uri); -extern char *fdgets(char *buf, size_t len, int fd); - - -/* lpd operations */ - /* open a connection to remote print service */ -extern int lpd_open(service_t *svc, char type, char **args, - int timeout); - /* job cancelation */ -extern papi_status_t lpd_purge_jobs(service_t *svc, job_t ***jobs); -extern papi_status_t lpd_cancel_job(service_t *svc, int job_id); - /* job submission */ -extern papi_status_t lpd_submit_job(service_t *svc, char *metadata, - papi_attribute_t ***attributes, int *fd); -extern papi_status_t lpd_job_add_attributes(service_t *svc, - papi_attribute_t **attributes, - char **metadata, - papi_attribute_t ***used_attributes); -extern papi_status_t lpd_job_add_files(service_t *svc, - papi_attribute_t **attributes, char **files, - char **metadata, - papi_attribute_t ***used_attributes); - /* query cache lookup routines */ -extern papi_status_t lpd_find_printer_info(service_t *svc, printer_t **result); -extern papi_status_t lpd_find_job_info(service_t *svc, int job_id, job_t **job); -extern papi_status_t lpd_find_jobs_info(service_t *svc, job_t ***jobs); - - -#ifdef __cplusplus -} -#endif - -#endif /* _PAPI_IMPL_H */ diff --git a/usr/src/lib/print/libpapi-lpd/common/printer.c b/usr/src/lib/print/libpapi-lpd/common/printer.c deleted file mode 100644 index 308d9c9443..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/printer.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: printer.c 149 2006-04-25 16:55:01Z njacobs $ */ - -#include <stdlib.h> -#include <strings.h> -#include <papi_impl.h> -#include <libintl.h> - -static int -contains(char *value, char **list) -{ - int i; - - if ((value == NULL) || (list == NULL)) - return (1); - - for (i = 0; list[i] != NULL; i++) - if (strcasecmp(value, list[i]) == 0) - return (1); - - return (0); -} - -papi_status_t -papiPrinterQuery(papi_service_t handle, char *name, - char **requested_attrs, - papi_attribute_t **job_attributes, - papi_printer_t *printer) -{ - papi_status_t status; - service_t *svc = handle; - printer_t *p = NULL; - - if ((svc == NULL) || (name == NULL) || (printer == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((status = service_fill_in(svc, name)) == PAPI_OK) { - *printer = NULL; - - if ((contains("printer-state", requested_attrs) == 1) || - (contains("printer-state-reasons", requested_attrs) == 1)) - status = lpd_find_printer_info(svc, - (printer_t **)printer); - - if ((status == PAPI_OK) && (*printer == NULL)) { - char buf[BUFSIZ]; - - *printer = p = calloc(1, sizeof (*p)); - - papiAttributeListAddString(&(p->attributes), - PAPI_ATTR_APPEND, "printer-name", - queue_name_from_uri(svc->uri)); - - if (uri_to_string(svc->uri, buf, sizeof (buf)) == 0) - papiAttributeListAddString(&(p->attributes), - PAPI_ATTR_APPEND, - "printer-uri-supported", buf); - } - /* Set printer accepting: mimic prepapi behavior */ - if ((p = *printer) != NULL) - papiAttributeListAddBoolean(&(p->attributes), - PAPI_ATTR_REPLACE, - "printer-is-accepting-jobs", PAPI_TRUE); - - } - - return (status); -} - -papi_status_t -papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) -{ - papi_status_t status; - service_t *svc = handle; - - if ((svc == NULL) || (name == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((status = service_fill_in(svc, name)) == PAPI_OK) - status = lpd_purge_jobs(svc, (job_t ***)jobs); - - return (status); -} - -papi_status_t -papiPrinterListJobs(papi_service_t handle, char *name, - char **requested_attrs, int type_mask, - int max_num_jobs, papi_job_t **jobs) -{ - papi_status_t status; - service_t *svc = handle; - - if ((svc == NULL) || (name == NULL) || (jobs == NULL)) - return (PAPI_BAD_ARGUMENT); - - if ((status = service_fill_in(svc, name)) == PAPI_OK) - status = lpd_find_jobs_info(svc, (job_t ***)jobs); - - return (status); -} - -papi_attribute_t ** -papiPrinterGetAttributeList(papi_printer_t printer) -{ - printer_t *p = printer; - - if (p == NULL) - return (NULL); - - return (p->attributes); -} - -void -papiPrinterFree(papi_printer_t printer) -{ - printer_t *p = printer; - - if (p != NULL) { - if (p->attributes != NULL) - papiAttributeListFree(p->attributes); - free(p); - } -} - -void -papiPrinterListFree(papi_printer_t *printers) -{ - if (printers != NULL) { - int i; - - for (i = 0; printers[i] != NULL; i++) - papiPrinterFree(printers[i]); - free(printers); - } -} - - -papi_status_t -papiPrinterDisable(papi_service_t handle, char *name, char *message) -{ - service_t *svc = handle; - papi_status_t status; - - if ((status = service_fill_in(svc, name)) == PAPI_OK) { - detailed_error(svc, - gettext("Warning: %s is remote, disable has no meaning."), - queue_name_from_uri(svc->uri)); - } - return (PAPI_OPERATION_NOT_SUPPORTED); -} - -papi_status_t -papiPrinterEnable(papi_service_t handle, char *name) -{ - service_t *svc = handle; - papi_status_t status; - - if ((status = service_fill_in(svc, name)) == PAPI_OK) { - detailed_error(svc, - gettext("Warning: %s is remote, enable has no meaning."), - queue_name_from_uri(svc->uri)); - } - return (PAPI_OPERATION_NOT_SUPPORTED); -} - - -papi_status_t -papiPrinterResume(papi_service_t handle, char *name) -{ - service_t *svc = handle; - papi_status_t status; - - if ((status = service_fill_in(svc, name)) == PAPI_OK) { - detailed_error(svc, - gettext("Warning: %s is remote, accept has no meaning."), - queue_name_from_uri(svc->uri)); - } - return (PAPI_OPERATION_NOT_SUPPORTED); -} - - -papi_status_t -papiPrinterPause(papi_service_t handle, char *name, char *message) -{ - service_t *svc = handle; - papi_status_t status; - - if ((status = service_fill_in(svc, name)) == PAPI_OK) { - detailed_error(svc, - gettext("Warning: %s is remote, reject has no meaning."), - queue_name_from_uri(svc->uri)); - } - return (PAPI_OPERATION_NOT_SUPPORTED); -} diff --git a/usr/src/lib/print/libpapi-lpd/common/service.c b/usr/src/lib/print/libpapi-lpd/common/service.c deleted file mode 100644 index c39ea0cbb5..0000000000 --- a/usr/src/lib/print/libpapi-lpd/common/service.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: service.c 163 2006-05-09 15:07:45Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <alloca.h> -#include <uri.h> -#include <papi_impl.h> - -papi_status_t -service_fill_in(service_t *svc, char *name) -{ - papi_status_t status = PAPI_OK; - uri_t *uri = NULL; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - if (name == NULL) - return (PAPI_OK); - - /* - * valid URIs are in the form: - * lpd://server[:port]/.../queue[#extensions] - * rfc-1179://server[:port]/.../queue[#extensions] - * any authentication information supplied the URI is ignored. - */ - if (uri_from_string((char *)name, &uri) != -1) { - if ((strcasecmp(uri->scheme, "lpd") == 0) || - (strcasecmp(uri->scheme, "rfc-1179") == 0)) { - if (svc->uri != NULL) - uri_free(svc->uri); - svc->uri = uri; - } else { - uri_free(uri); - status = PAPI_URI_SCHEME; - } - } - - return (status); -} - -papi_status_t -papiServiceCreate(papi_service_t *handle, char *service_name, - char *user_name, char *password, - int (*authCB)(papi_service_t svc, void *app_data), - papi_encryption_t encryption, void *app_data) -{ - papi_status_t status; - service_t *svc = NULL; - - if (handle == NULL) - return (PAPI_BAD_ARGUMENT); - - if ((*handle = svc = (service_t *)calloc(1, sizeof (*svc))) == NULL) - return (PAPI_TEMPORARY_ERROR); - - if (service_name != NULL) - papiAttributeListAddString(&svc->attributes, PAPI_ATTR_EXCL, - "service-name", service_name); - - (void) papiServiceSetUserName(svc, user_name); - (void) papiServiceSetPassword(svc, password); - (void) papiServiceSetAuthCB(svc, authCB); - (void) papiServiceSetAppData(svc, app_data); - (void) papiServiceSetEncryption(svc, encryption); - - status = service_fill_in(svc, service_name); - - return (status); -} - -void -papiServiceDestroy(papi_service_t handle) -{ - if (handle != NULL) { - service_t *svc = handle; - -#ifdef DEADBEEF - if (svc->cache != NULL) - cache_free(svc->cache); -#endif - if (svc->uri != NULL) - uri_free(svc->uri); - if (svc->attributes != NULL) - papiAttributeListFree(svc->attributes); - free(svc); - } -} - -papi_status_t -papiServiceSetUserName(papi_service_t handle, char *user_name) -{ - service_t *svc = handle; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - return (papiAttributeListAddString(&svc->attributes, PAPI_ATTR_REPLACE, - "user-name", user_name)); -} - -papi_status_t -papiServiceSetPassword(papi_service_t handle, char *password) -{ - service_t *svc = handle; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - return (papiAttributeListAddString(&svc->attributes, - PAPI_ATTR_REPLACE, "password", password)); -} - -papi_status_t -papiServiceSetEncryption(papi_service_t handle, - papi_encryption_t encryption) -{ - service_t *svc = handle; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - return (papiAttributeListAddInteger(&svc->attributes, PAPI_ATTR_REPLACE, - "encryption", (int)encryption)); -} - -papi_status_t -papiServiceSetAuthCB(papi_service_t handle, - int (*authCB)(papi_service_t svc, void *app_data)) -{ - service_t *svc = handle; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - svc->authCB = (int (*)(papi_service_t svc, void *))authCB; - - return (PAPI_OK); -} - -papi_status_t -papiServiceSetAppData(papi_service_t handle, void *app_data) -{ - service_t *svc = handle; - - if (svc == NULL) - return (PAPI_BAD_ARGUMENT); - - svc->app_data = (void *)app_data; - - return (PAPI_OK); -} - -char * -papiServiceGetServiceName(papi_service_t handle) -{ - service_t *svc = handle; - char *result = NULL; - - if (svc != NULL) - papiAttributeListGetString(svc->attributes, NULL, - "service-name", &result); - - return (result); -} - -char * -papiServiceGetUserName(papi_service_t handle) -{ - service_t *svc = handle; - char *result = NULL; - - if (svc != NULL) - papiAttributeListGetString(svc->attributes, NULL, - "user-name", &result); - - return (result); - -} - -char * -papiServiceGetPassword(papi_service_t handle) -{ - service_t *svc = handle; - char *result = NULL; - - if (svc != NULL) - papiAttributeListGetString(svc->attributes, NULL, - "password", &result); - - return (result); -} - -papi_encryption_t -papiServiceGetEncryption(papi_service_t handle) -{ - service_t *svc = handle; - papi_encryption_t result = PAPI_ENCRYPT_NEVER; - - if (svc != NULL) - papiAttributeListGetInteger(svc->attributes, NULL, - "encryption", (int *)&result); - - return (result); -} - -void * -papiServiceGetAppData(papi_service_t handle) -{ - service_t *svc = handle; - void *result = NULL; - - if (svc != NULL) { - result = svc->app_data; - } - - return (result); - -} - -papi_attribute_t ** -papiServiceGetAttributeList(papi_service_t handle) -{ - service_t *svc = handle; - papi_attribute_t **result = NULL; - - if (svc != NULL) - result = svc->attributes; - - return (result); -} - -char * -papiServiceGetStatusMessage(papi_service_t handle) -{ - service_t *svc = handle; - char *result = NULL; - - if (svc != NULL) { - papiAttributeListGetString(svc->attributes, NULL, - "detailed-status-message", &result); - } - - return (result); -} - -void -detailed_error(service_t *svc, char *fmt, ...) -{ - if ((svc != NULL) && (fmt != NULL)) { - va_list ap; - size_t size; - char *message = alloca(BUFSIZ); - - va_start(ap, fmt); - /* - * fill in the message. If the buffer is too small, allocate - * one that is large enough and fill it in. - */ - if ((size = vsnprintf(message, BUFSIZ, fmt, ap)) >= BUFSIZ) - if ((message = alloca(size)) != NULL) - vsnprintf(message, size, fmt, ap); - va_end(ap); - - papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, - "detailed-status-message", message); - } -} diff --git a/usr/src/lib/print/libpapi-lpd/i386/Makefile b/usr/src/lib/print/libpapi-lpd/i386/Makefile deleted file mode 100644 index 362f811e03..0000000000 --- a/usr/src/lib/print/libpapi-lpd/i386/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \ - $(ROOTLIBPRINTPROG) diff --git a/usr/src/lib/print/libpapi-lpd/sparc/Makefile b/usr/src/lib/print/libpapi-lpd/sparc/Makefile deleted file mode 100644 index 362f811e03..0000000000 --- a/usr/src/lib/print/libpapi-lpd/sparc/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBDIR) $(ROOTLIBS) $(ROOTLINKS) $(EXTRALINKS) \ - $(ROOTLIBPRINTPROG) diff --git a/usr/src/lib/print/libprint/Makefile.com b/usr/src/lib/print/libprint/Makefile.com deleted file mode 100644 index 88fbb532b0..0000000000 --- a/usr/src/lib/print/libprint/Makefile.com +++ /dev/null @@ -1,58 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -LIBRARY = libprint.a -VERS = .2 -OBJECTS = \ - list.o ns.o ns_bsd_addr.o ns_cmn_kvp.o \ - ns_cmn_printer.o nss_convert.o nss_ldap.o nss_printer.o nss_write.o - -include ../../../Makefile.lib -include ../../../Makefile.rootfs - -SRCDIR = ../common - -ROOTLIBDIR= $(ROOT)/usr/lib - -LIBS = $(DYNLIB) - -$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC) - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I$(SRCDIR) -CPPFLAGS += -I../../head -D_REENTRANT - -LDLIBS += -lnsl -lsocket -lc -lldap - - -.KEEP_STATE: - -all: $(LIBS) - -lint: lintcheck - -include ../../../Makefile.targ diff --git a/usr/src/lib/print/libprint/common/list.c b/usr/src/lib/print/libprint/common/list.c deleted file mode 100644 index fd90e58130..0000000000 --- a/usr/src/lib/print/libprint/common/list.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <stdarg.h> -#include <syslog.h> -#include <stdlib.h> -#include <strings.h> - -#include <list.h> - - -static int _list_increment = 64; /* just so It can be tuned with adb(1) */ -/* - * list_append() takes in a list (type **) and a pointer to an item to add - * to the list and returns a new list with the new item appended on the - * end. The list is NULL terminated. If there was an error, NULL is - * returned. For reasonable efficiency, the list will be allocated - * in blocks of size _list_increment. - */ -void ** -list_append(void **list, void *item) -{ -#ifdef DEBUG - syslog(LOG_DEBUG, "list_append(0x%x, 0x%x)", list, item); -#endif - if (item == NULL) - return (list); - - if (list == NULL) { - list = (void **)calloc(_list_increment, sizeof (void *)); - (void) memset(list, NULL, (_list_increment * sizeof (void *))); - list[0] = item; - } else { - int count; - - for (count = 0; list[count] != NULL; count++); - - if ((count + 1) % _list_increment == 0) { /* increase size */ - void **new_list = NULL; - int new_size = (((count + 1) / _list_increment) + 1) * - _list_increment; - - new_list = (void **)calloc(new_size, - sizeof (void *)); - (void) memset(new_list, NULL, - (new_size * sizeof (void *))); - for (count = 0; list[count] != NULL; count++) - new_list[count] = list[count]; - free(list); - list = new_list; - } - list[count] = item; - } - return (list); -} - - -void ** -list_append_unique(void **list, void *item, int (*cmp)(void *, void*)) -{ - if (list_locate(list, cmp, item)) - return (list); - - list = list_append(list, item); - return (list); -} - - -/* - * list_locate() iterates through the list passed in and uses the comparison - * routine and element passed in to find an element in the list. It - * returns the first element matched, or NULL if none exists - */ -void * -list_locate(void **list, int (*compair)(void *, void *), void *element) -{ - int current = 0; - -#ifdef DEBUG - syslog(LOG_DEBUG, "list_locate()"); -#endif - if (list != NULL) - for (current = 0; list[current] != NULL; current++) - if ((compair)(list[current], element) == 0) - return (list[current]); - return (NULL); -} - - -/* - * list_concatenate() takes in two NULL terminated lists of items (type **) - * and creates a new list with items from list2 appended on the end of - * the list of items from list1. The result is a list (type **). If - * there is a failure, NULL is returned. - */ -void ** -list_concatenate(void **list1, void **list2) -{ - void **list = NULL; - int size1 = 0, - size2 = 0, - new_size = 0; -#ifdef DEBUG - syslog(LOG_DEBUG, "list_concatenate(0x%x, 0x%x)", list1, list2); -#endif - if ((list1 == NULL) || (list2 == NULL)) - return ((list1 != NULL) ? list1 : list2); - - for (size1 = 0; list1[size1] != NULL; size1++); - for (size2 = 0; list2[size2] != NULL; size2++); - - /* list1 + list2 padded to a multiple of _list_increment */ - new_size = ((size1 + size2)/_list_increment + 2) * _list_increment; - - if ((list = (void **)calloc((new_size), sizeof (void *))) - != NULL) { - int count = 0; - - (void) memset(list, NULL, (new_size * sizeof (void *))); - - for (size1 = 0; list1[size1] != NULL; size1++) - list[count++] = list1[size1]; - for (size2 = 0; list2[size2] != NULL; size2++) - list[count++] = list2[size2]; - free(list1); - } - return (list); -} - - -/* - * list_iterate() take in a list, pointer to a function, and variable number - * of arguements following. list_iterate() will iterate through the list - * calling the functions passed in with the first argument being a pointer - * to the current item in the list and the second argument being a va_list - * containing the rest of arguments used to call list_iterate(). The - * calling fuction should be declared: int func(type *, va_list). The - * return results are all added together and the sum is returned from - * list_iterate(). - */ -int -list_iterate(void **list, int (*vfunc)(void *, va_list), ...) -{ - int current = 0, - rc = 0; - -#ifdef DEBUG - syslog(LOG_DEBUG, "list_iterate(0x%x, 0x%x)", list, vfunc); -#endif - if (list != NULL) - while (list[current] != NULL) { - va_list ap; - - va_start(ap, (vfunc)); - rc += (vfunc)(list[current++], ap); - va_end(ap); - } - return (rc); -} diff --git a/usr/src/lib/print/libprint/common/llib-lprint b/usr/src/lib/print/libprint/common/llib-lprint deleted file mode 100644 index c52143e527..0000000000 --- a/usr/src/lib/print/libprint/common/llib-lprint +++ /dev/null @@ -1,141 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* LINTLIBRARY */ -/* PROTOLIB1 */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <arpa/inet.h> -#include <dirent.h> -#include <dlfcn.h> -#include <errno.h> -#include <fcntl.h> -#include <libintl.h> -#include <netdb.h> -#include <netinet/in.h> -#include <pwd.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#include <signal.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/mman.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/systeminfo.h> -#include <sys/types.h> -#include <syslog.h> -#include <unistd.h> - -void **list_append(void **, void *); -void **list_append_unique(void **, void *, int (*)(void *, void*)); -void **list_concatenate(void **, void **); -void * list_locate(void **, int (*)(void *, void *), void *); -int list_iterate(void **, int (*)(void *, __va_list), ...); - -void *dynamic_function(const char *, const char *); - -struct ns_bsd_addr { - char *server; /* server name */ - char *printer; /* printer name or NULL */ - char *extension; /* RFC-1179 conformance */ - char *pname; /* Local printer name */ -}; -typedef struct ns_bsd_addr ns_bsd_addr_t; - -/* Key/Value pair structure */ -struct ns_kvp { - char *key; /* key */ - char *value; /* value string */ -}; -typedef struct ns_kvp ns_kvp_t; - -/* Printer Object structure */ -struct ns_printer { - char *name; /* primary name of printer */ - char **aliases; /* aliases for printer */ - char *source; /* name service derived from */ - ns_kvp_t **attributes; /* key/value pairs. */ -}; -typedef struct ns_printer ns_printer_t; - -/* functions to get/put printer objects */ -ns_printer_t *ns_printer_create(char *, char **, char *, ns_kvp_t **); -ns_printer_t *ns_printer_get_name(const char *, const char *); -ns_printer_t **ns_printer_get_list(const char *); -int ns_printer_put(const ns_printer_t *); -void ns_printer_destroy(ns_printer_t *); - -/* functions to manipulate key/value pairs */ -void *ns_get_value(const char *, const ns_printer_t *); -char *ns_get_value_string(const char *, const ns_printer_t *); -int ns_set_value(const char *, const void *, ns_printer_t *); -int ns_set_value_from_string(const char *, const char *, - ns_printer_t *); -ns_kvp_t *ns_kvp_create(const char *, const char *); - -/* for BSD bindings only */ -ns_bsd_addr_t *ns_bsd_addr_get_default(void); -ns_bsd_addr_t *ns_bsd_addr_get_name(char *name); -ns_bsd_addr_t **ns_bsd_addr_get_all(int); -ns_bsd_addr_t **ns_bsd_addr_get_list(int); - -/* others */ -ns_printer_t *posix_name(const char *); -int ns_printer_match_name(ns_printer_t *, const char *); -char *ns_printer_name_list(const ns_printer_t *); -char *value_to_string(const char *, void *); -void *string_to_value(const char *, char *); - - -ns_printer_t *_cvt_pconf_entry_to_printer(char *, char *); -char *_cvt_printer_to_pconf_entry(ns_printer_t *); - -ns_printer_t *_cvt_user_string_to_printer(char *, char *); -char *_cvt_printer_to_user_string(ns_printer_t *); - - -ns_printer_t *_file_get_name(const char *, const char *, - ns_printer_t *(*)(char *, char *), char *); - -ns_printer_t **_file_get_list(const char *, - ns_printer_t *(*)(char *, char *), char *); - -int _file_put_printer(const char *, const ns_printer_t *, - ns_printer_t *(*)(char *, char *), char *, char *(*)(ns_printer_t *)); - - -ns_printer_t *_nis_get_name(const char *, const char *, - ns_printer_t *(*)(char *, char *), char *); - -ns_printer_t **_nis_get_list(const char *, - ns_printer_t *(*)(char *, char *), char *); - -int _nis_put_printer(const char *, const ns_printer_t *, - ns_printer_t *(*)(char *, char *), char *, char *(*)(ns_printer_t *)); diff --git a/usr/src/lib/print/libprint/common/mapfile-vers b/usr/src/lib/print/libprint/common/mapfile-vers deleted file mode 100644 index 776e97beca..0000000000 --- a/usr/src/lib/print/libprint/common/mapfile-vers +++ /dev/null @@ -1,86 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. -# - -# -# MAPFILE HEADER START -# -# WARNING: STOP NOW. DO NOT MODIFY THIS FILE. -# Object versioning must comply with the rules detailed in -# -# usr/src/lib/README.mapfiles -# -# You should not be making modifications here until you've read the most current -# copy of that file. If you need help, contact a gatekeeper for guidance. -# -# MAPFILE HEADER END -# - -$mapfile_version 2 - -# -# Generic interface definition for usr/src/lib/print. -# - -SYMBOL_VERSION SUNWprivate_2.1 { - global: - getprinterbyname; # NSS support - getprinterentry; - setprinterentry; - endprinterentry; - - ns_printer_create; # Old NS support - ns_printer_get_name; - ns_printer_get_list; - ns_printer_put; - ns_printer_destroy; - ns_get_value; - ns_get_value_string; - ns_set_value; - ns_set_value_from_string; - ns_kvp_create; - ns_bsd_addr_get_default; - ns_bsd_addr_get_name; - ns_bsd_addr_get_all; - ns_bsd_addr_get_list; - string_to_bsd_addr; - bsd_addr_create; - ns_printer_match_name; - ns_printer_name_list; - value_to_string; - string_to_value; - normalize_ns_name; - - list_append; # list support - list_append_unique; - list_concatenate; - list_locate; - list_iterate; - - files_put_printer; # required for ns_put_printer() - nis_put_printer; - ldap_put_printer; - - local: - *; -}; diff --git a/usr/src/lib/print/libprint/common/ns.c b/usr/src/lib/print/libprint/common/ns.c deleted file mode 100644 index 943be31e95..0000000000 --- a/usr/src/lib/print/libprint/common/ns.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <string.h> -#include <stdarg.h> -#include <dlfcn.h> -#include <nss_dbdefs.h> -#include <syslog.h> - -#include <ns.h> -#include <list.h> - - -/* - * because legacy code can use a variety of values for various name - * services, this routine is needed to "normalize" them. - */ -char * -normalize_ns_name(char *ns) -{ - if (ns == NULL) - return (NULL); - else if ((strcasecmp(ns, "files") == 0) || - (strcasecmp(ns, "system") == 0) || - (strcasecmp(ns, "etc") == 0)) - return ("files"); - else if (strcasecmp(ns, "nis") == 0) - return ("nis"); - else if (strcasecmp(ns, "ldap") == 0) - return ("ldap"); - else - return (ns); -} - - -/* - * FUNCTION: - * void ns_printer_destroy(ns_printer_t *printer) - * INPUT: - * ns_printer_t *printer - a pointer to the printer "object" to destroy - * DESCRIPTION: - * This function will free all of the memory associated with a printer - * object. It does this by walking the structure ad freeing everything - * underneath it, with the exception of the object source field. This - * field is not filled in with newly allocated space when it is - * generated - */ -void -ns_printer_destroy(ns_printer_t *printer) -{ - if (printer != NULL) { - if (printer->attributes != NULL) { /* attributes */ - extern void ns_kvp_destroy(ns_kvp_t *); - - list_iterate((void **)printer->attributes, - (VFUNC_T)ns_kvp_destroy); - free(printer->attributes); - } - if (printer->aliases != NULL) { /* aliases */ - free(printer->aliases); - } - if (printer->name != NULL) /* primary name */ - free(printer->name); - free(printer); - } -} - - -/* - * FUNCTION: - * ns_printer_t **ns_printer_get_list() - * OUTPUT: - * ns_printer_t ** (return value) - an array of pointers to printer - * objects. - * DESCRIPTION: - * This function will return a list of all printer objects found in every - * configuration interface. - */ -ns_printer_t ** -ns_printer_get_list(const char *ns) -{ - char buf[NSS_LINELEN_PRINTERS]; - ns_printer_t **printer_list = NULL; - - (void) setprinterentry(0, (char *)ns); - - ns = normalize_ns_name((char *)ns); - while (getprinterentry(buf, sizeof (buf), (char *)ns) == 0) { - ns_printer_t *printer = - (ns_printer_t *)_cvt_nss_entry_to_printer(buf, NULL); - - printer_list = (ns_printer_t **)list_append( - (void **)printer_list, - (void *)printer); - } - - (void) endprinterentry(); - - return (printer_list); -} - - -/* - * This function looks for the named printer in the supplied - * name service (ns), or the name services configured under - * the nsswitch. - */ -ns_printer_t * -ns_printer_get_name(const char *name, const char *ns) -{ - ns_printer_t *result = NULL; - char buf[NSS_LINELEN_PRINTERS]; - - /* - * Reset printer entries to the start so we know we will always - * pick up the correct entry - */ - endprinterentry(); - - if ((result = (ns_printer_t *)posix_name(name)) != NULL) - return (result); - - ns = normalize_ns_name((char *)ns); - if (getprinterbyname((char *)name, buf, sizeof (buf), (char *)ns) == 0) - result = (ns_printer_t *)_cvt_nss_entry_to_printer(buf, NULL); - - return (result); -} - - -/* - * FUNCTION: - * int ns_printer_put(const ns_printer_t *printer) - * INPUT: - * const ns_printer_t *printer - a printer object - * DESCRIPTION: - * This function attempts to put the data in the printer object back - * to the "name service" specified in the source field of the object. - */ -int -ns_printer_put(const ns_printer_t *printer) -{ - char func[32]; - int (*fpt)(); - - if ((printer == NULL) || (printer->source == NULL)) - return (-1); - - if (snprintf(func, sizeof (func), "%s_put_printer", - normalize_ns_name(printer->source)) >= sizeof (func)) { - syslog(LOG_ERR, "ns_printer_put: buffer overflow"); - return (-1); - } - - if ((fpt = (int (*)())dlsym(RTLD_DEFAULT, func)) != NULL) - return ((*fpt)(printer)); - - return (-1); -} diff --git a/usr/src/lib/print/libprint/common/ns.h b/usr/src/lib/print/libprint/common/ns.h deleted file mode 100644 index 84d16f7ceb..0000000000 --- a/usr/src/lib/print/libprint/common/ns.h +++ /dev/null @@ -1,202 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _NS_H -#define _NS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Name Service Common Keys/types for lookup - */ -#define NS_KEY_BSDADDR "bsdaddr" -#define NS_KEY_USE "use" -#define NS_KEY_ALL "all" -#define NS_KEY_GROUP "group" -#define NS_KEY_LIST "list" - -#define NS_KEY_PRINTER_TYPE "printer-type" -#define NS_KEY_DESCRIPTION "description" - -/* - * Name Service reserved names for lookup - */ -#define NS_NAME_DEFAULT "_default" -#define NS_NAME_ALL "_all" - -/* - * Name Services supported - */ -#define NS_SVC_USER "user" -#define NS_SVC_PRINTCAP "printcap" -#define NS_SVC_ETC "etc" -#define NS_SVC_NIS "nis" -#define NS_SVC_LDAP "ldap" - -/* - * Known Protocol Extensions - */ -#define NS_EXT_SOLARIS "solaris" -#define NS_EXT_GENERIC "extensions" /* same as SOLARIS */ -#define NS_EXT_HPUX "hpux" -#define NS_EXT_DEC "dec" - -/* - * get unique or full list of printer bindings - */ -#define NOTUNIQUE 0 -#define UNIQUE 1 -#define LOCAL_UNIQUE 2 /* include alias names */ - -/* BSD binding address structure */ -struct ns_bsd_addr { - char *server; /* server name */ - char *printer; /* printer name or NULL */ - char *extension; /* RFC-1179 conformance */ - char *pname; /* Local printer name */ -}; -typedef struct ns_bsd_addr ns_bsd_addr_t; - -/* Key/Value pair structure */ -struct ns_kvp { - char *key; /* key */ - char *value; /* value string */ -}; -typedef struct ns_kvp ns_kvp_t; - - -/* LDAP specific result codes */ - -typedef enum NSL_RESULT -{ - NSL_OK = 0, /* Operation successful */ - NSL_ERR_INTERNAL = 1, /* Internal coding Error */ - NSL_ERR_ADD_FAILED = 2, /* LDAP add failed */ - NSL_ERR_MOD_FAILED = 3, /* LDAP modify failed */ - NSL_ERR_DEL_FAILED = 4, /* LDAP delete failed */ - NSL_ERR_UNKNOWN_PRINTER = 5, /* Unknown Printer object */ - NSL_ERR_CREDENTIALS = 6, /* LDAP credentials invalid */ - NSL_ERR_CONNECT = 7, /* LDAP server connect failed */ - NSL_ERR_BIND = 8, /* LDAP bind failed */ - NSL_ERR_RENAME = 9, /* Object rename is not allowed */ - NSL_ERR_KVP = 10, /* sun-printer-kvp not allowed */ - NSL_ERR_BSDADDR = 11, /* sun-printer-bsdaddr not allowed */ - NSL_ERR_PNAME = 12, /* printer-name not allowed */ - NSL_ERR_MEMORY = 13, /* memory allocation failed */ - NSL_ERR_MULTIOP = 14, /* Replace and delete operation */ - NSL_ERR_NOTALLOWED = 15, /* KVP attribute not allowed */ - NSL_ERROR = -1 /* General error */ -} NSL_RESULT; - - -/* LDAP bind password security type */ - -typedef enum NS_PASSWD_TYPE { - NS_PW_INSECURE = 0, - NS_PW_SECURE = 1 -} NS_PASSWD_TYPE; - - -/* - * Information needed to update a name service. - * Currently only used for ldap. - */ -struct ns_cred { - char *binddn; - char *passwd; - char *host; - int port; /* LDAP port, 0 = default */ - NS_PASSWD_TYPE passwdType; /* password security type */ - uchar_t *domainDN; /* NS domain DN */ -}; -typedef struct ns_cred ns_cred_t; - -/* LDAP specific NS Data */ - -typedef struct NS_LDAPDATA { - char **attrList; /* list of user defined Key Value Pairs */ -} NS_LDAPDATA; - -/* Printer Object structure */ -struct ns_printer { - char *name; /* primary name of printer */ - char **aliases; /* aliases for printer */ - char *source; /* name service derived from */ - ns_kvp_t **attributes; /* key/value pairs. */ - ns_cred_t *cred; /* info to update name service */ - void *nsdata; /* name service specific data */ -}; -typedef struct ns_printer ns_printer_t; - -/* functions to get/put printer objects */ -extern ns_printer_t *ns_printer_create(char *, char **, char *, ns_kvp_t **); -extern ns_printer_t *ns_printer_get_name(const char *, const char *); -extern ns_printer_t **ns_printer_get_list(const char *); -extern int ns_printer_put(const ns_printer_t *); -extern void ns_printer_destroy(ns_printer_t *); - -extern int setprinterentry(int, char *); -extern int endprinterentry(); -extern int getprinterentry(char *, int, char *); -extern int getprinterbyname(char *, char *, int, char *); - -extern char *_cvt_printer_to_entry(ns_printer_t *, char *, int); - -extern ns_printer_t *_cvt_nss_entry_to_printer(char *, char *); -extern ns_printer_t *posix_name(const char *); - - - -/* functions to manipulate key/value pairs */ -extern void *ns_get_value(const char *, const ns_printer_t *); -extern char *ns_get_value_string(const char *, const ns_printer_t *); -extern int ns_set_value(const char *, const void *, ns_printer_t *); -extern int ns_set_value_from_string(const char *, const char *, - ns_printer_t *); -extern ns_kvp_t *ns_kvp_create(const char *, const char *); - -/* for BSD bindings only */ -extern ns_bsd_addr_t *ns_bsd_addr_get_default(); -extern ns_bsd_addr_t *ns_bsd_addr_get_name(char *name); -extern ns_bsd_addr_t **ns_bsd_addr_get_all(int); -extern ns_bsd_addr_t **ns_bsd_addr_get_list(int); - -/* others */ -extern int ns_printer_match_name(ns_printer_t *, const char *); -extern char *ns_printer_name_list(const ns_printer_t *); -extern char *value_to_string(const char *, void *); -extern void *string_to_value(const char *, char *); -extern char *normalize_ns_name(char *); -extern char *strncat_escaped(char *, char *, int, char *); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _NS_H */ diff --git a/usr/src/lib/print/libprint/common/ns_bsd_addr.c b/usr/src/lib/print/libprint/common/ns_bsd_addr.c deleted file mode 100644 index ba142bb8a1..0000000000 --- a/usr/src/lib/print/libprint/common/ns_bsd_addr.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <stdarg.h> -#include <string.h> -#include <syslog.h> - -#include <ns.h> -#include <list.h> - -static char ** -strsplit(char *string, char *seperators) -{ - char **list = NULL; - char *where = NULL; - char *element; - - for (element = strtok_r(string, seperators, &where); element != NULL; - element = strtok_r(NULL, seperators, &where)) - list = (char **)list_append((void **)list, element); - - return (list); -} - -/* - * Manipulate bsd_addr structures - */ -ns_bsd_addr_t * -bsd_addr_create(const char *server, const char *printer, const char *extension) -{ - ns_bsd_addr_t *addr = NULL; - - if ((server != NULL) && - ((addr = calloc(1, sizeof (*addr))) != NULL)) { - addr->printer = (char *)printer; - addr->server = (char *)server; - addr->extension = (char *)extension; - } - - return (addr); -} - -static char * -bsd_addr_to_string(const ns_bsd_addr_t *addr) -{ - char buf[BUFSIZ]; - - if ((addr == NULL) || (addr->server == NULL)) - return (NULL); - - if (snprintf(buf, sizeof (buf), "%s", addr->server) >= sizeof (buf)) { - syslog(LOG_ERR, "bsd_addr_to_string: buffer overflow"); - return (NULL); - } - - if ((addr->printer != NULL) || (addr->extension != NULL)) - (void) strlcat(buf, ",", sizeof (buf)); - if (addr->printer != NULL) - if (strlcat(buf, addr->printer, sizeof (buf)) >= sizeof (buf)) { - syslog(LOG_ERR, "bsd_addr_to_string: buffer overflow"); - return (NULL); - } - if (addr->extension != NULL) { - (void) strlcat(buf, ",", sizeof (buf)); - if (strlcat(buf, addr->extension, sizeof (buf)) - >= sizeof (buf)) { - syslog(LOG_ERR, "bsd_addr_to_string: buffer overflow"); - return (NULL); - } - } - - return (strdup(buf)); -} - -ns_bsd_addr_t * -string_to_bsd_addr(const char *string) -{ - char **list, *tmp, *printer = NULL, *extension = NULL; - - if (string == NULL) - return (NULL); - - tmp = strdup(string); - list = strsplit(tmp, ","); - - if (list[1] != NULL) { - printer = list[1]; - if (list[2] != NULL) - extension = list[2]; - } - - return (bsd_addr_create(list[0], printer, extension)); -} - -static char * -list_to_string(const char **list) -{ - char buf[BUFSIZ]; - - if ((list == NULL) || (*list == NULL)) - return (NULL); - - if (snprintf(buf, sizeof (buf), "%s", *list) >= sizeof (buf)) { - syslog(LOG_ERR, "list_to_string: buffer overflow"); - return (NULL); - } - - while (*++list != NULL) { - (void) strlcat(buf, ",", sizeof (buf)); - if (strlcat(buf, *list, sizeof (buf)) >= sizeof (buf)) { - syslog(LOG_ERR, "list_to_string: buffer overflow"); - return (NULL); - } - } - - return (strdup(buf)); -} - -static char * -internal_list_to_string(const ns_printer_t **list) -{ - char buf[BUFSIZ]; - - if ((list == NULL) || (*list == NULL)) - return (NULL); - - if (snprintf(buf, sizeof (buf), "%s", (*list)->name) >= sizeof (buf)) { - syslog(LOG_ERR, "internal_list_to_string:buffer overflow"); - return (NULL); - } - - while (*++list != NULL) { - (void) strlcat(buf, ",", sizeof (buf)); - if (strlcat(buf, (*list)->name, sizeof (buf)) >= sizeof (buf)) { - syslog(LOG_ERR, - "internal_list_to_string:buffer overflow"); - return (NULL); - } - } - - return (strdup(buf)); -} - - -char * -value_to_string(const char *key, void *value) -{ - char *string = NULL; - - if ((key != NULL) && (value != NULL)) { - if (strcmp(key, NS_KEY_BSDADDR) == 0) { - string = bsd_addr_to_string(value); - } else if ((strcmp(key, NS_KEY_ALL) == 0) || - (strcmp(key, NS_KEY_GROUP) == 0)) { - string = list_to_string(value); - } else if (strcmp(key, NS_KEY_LIST) == 0) { - string = internal_list_to_string(value); - } else { - string = strdup((char *)value); - } - } - - return (string); -} - - -void * -string_to_value(const char *key, char *string) -{ - void *value = NULL; - - if ((key != NULL) && (string != NULL) && (string[0] != NULL)) { - if (strcmp(key, NS_KEY_BSDADDR) == 0) { - value = (void *)string_to_bsd_addr(string); - } else if ((strcmp(key, NS_KEY_ALL) == 0) || - (strcmp(key, NS_KEY_GROUP) == 0)) { - value = (void *)strsplit(string, ","); - } else { - value = (void *)string; - } - } - - return (value); -} - -static void -split_name(char *name, const char *delimiter, char **p1, char **p2, char **p3) -{ - char *tmp, *junk = NULL; - - if (p1 != NULL) - *p1 = NULL; - if (p2 != NULL) - *p2 = NULL; - if (p3 != NULL) - *p3 = NULL; - - if ((name == NULL) || (delimiter == NULL)) { - syslog(LOG_DEBUG, "split_name(): name/delimter invalid\n"); - return; - } - - for (tmp = (char *)strtok_r(name, delimiter, &junk); tmp != NULL; - tmp = (char *)strtok_r(NULL, delimiter, &junk)) - if ((p1 != NULL) && (*p1 == NULL)) - *p1 = tmp; - else if ((p2 != NULL) && (*p2 == NULL)) { - *p2 = tmp; - if (p3 == NULL) - break; - } else if ((p3 != NULL) && (*p3 == NULL)) { - *p3 = tmp; - break; - } -} - -/* - * This implements support for printer names that are fully resolvable - * on their own. These "complete" names are converted into a ns_printer_t - * structure containing an appropriate "bsdaddr" attribute. The supported - * formats are as follows: - * POSIX style (server:printer[:conformance]). - * This format is an adaptation of the format originally - * described in POSIX 1387.4. The POSIX draft has since been - * squashed, but this particular component lives on. The - * conformace field has been added to allow further identification - * of the the server. - */ -ns_printer_t * -posix_name(const char *name) -{ - ns_printer_t *printer = NULL; - char *tmp = NULL; - - if ((name != NULL) && ((tmp = strpbrk(name, ":")) != NULL)) { - char *server = NULL; - char *queue = NULL; - char *extension = NULL; - char *addr = strdup(name); - char buf[BUFSIZ]; - - if (*tmp == ':') - split_name(addr, ": \t", &server, &queue, &extension); - - memset(buf, 0, sizeof (buf)); - if ((server != NULL) && (queue != NULL)) - snprintf(buf, sizeof (buf), "%s,%s%s%s", server, - queue, (extension != NULL ? "," : ""), - (extension != NULL ? extension : "")); - - /* build the structure here */ - if (buf[0] != NULL) { - ns_kvp_t **list, *kvp; - - kvp = ns_kvp_create(NS_KEY_BSDADDR, buf); - list = (ns_kvp_t **)list_append(NULL, kvp); - if (list != NULL) - printer = ns_printer_create(strdup(name), NULL, - "posix", list); - } - } - - return (printer); -} - -/* - * FUNCTION: - * int ns_bsd_addr_cmp(ns_bsd_addr_t *at, ns_bsd_addr_t *a2) - * INPUTS: - * ns_bsd_addr_t *a1 - a bsd addr - * ns_bsd_addr_t *21 - another bsd addr - * DESCRIPTION: - * This functions compare 2 bsd_addr structures to determine if the - * information in them is the same. - */ -static int -ns_bsd_addr_cmp(ns_bsd_addr_t *a1, ns_bsd_addr_t *a2) -{ - int rc; - - if ((a1 == NULL) || (a2 == NULL)) - return (1); - - if ((rc = strcmp(a1->server, a2->server)) != 0) - return (rc); - - if ((a1->printer == NULL) || (a2->printer == NULL)) - return (a1->printer != a2->printer); - - return (strcmp(a1->printer, a2->printer)); -} - - - - -/* - * FUNCTION: ns_bsd_addr_cmp_local() - * - * DESCRIPTION: This function compares 2 bsd_addr structures to determine if - * the information in them is the same. It destinquishes between - * real printer names and alias names while doing the compare. - * - * INPUTS: ns_bsd_addr_t *a1 - a bsd addr - * ns_bsd_addr_t *21 - another bsd addr - */ - -static int -ns_bsd_addr_cmp_local(ns_bsd_addr_t *a1, ns_bsd_addr_t *a2) - -{ - int rc; - - if ((a1 == NULL) || (a2 == NULL)) - { - return (1); - } - - if ((rc = strcmp(a1->server, a2->server)) != 0) - { - return (rc); - } - - if ((a1->printer == NULL) || (a2->printer == NULL)) - { - return (a1->printer != a2->printer); - } - - rc = strcmp(a1->printer, a2->printer); - if (rc == 0) - { - /* - * The printer's real names are the same, but now check if - * their local names (alias) are the same. - */ - rc = strcmp(a1->pname, a2->pname); - } - - return (rc); -} /* ns_bsd_addr_cmp_local */ - - - -/* - * FUNCTION: - * ns_bsd_addr_t *ns_bsd_addr_get_name(char *name) - * INPUTS: - * char *name - name of printer to get address for - * OUTPUTS: - * ns_bsd_addr_t *(return) - the address of the printer - * DESCRIPTION: - * This function will get the BSD address of the printer specified. - * it fills in the printer name if none is specified in the "name service" - * as a convenience to calling functions. - */ -ns_bsd_addr_t * -ns_bsd_addr_get_name(char *name) -{ - ns_printer_t *printer; - ns_bsd_addr_t *addr = NULL; - - endprinterentry(); - if ((printer = ns_printer_get_name(name, NULL)) != NULL) { - addr = ns_get_value(NS_KEY_BSDADDR, printer); - - if (addr != NULL && addr->printer == NULL) - addr->printer = strdup(printer->name); - if (addr != NULL) { - /* - * if the name given is not the same as that in the - * this is an alias/remote name so put that into the - * pname field otherwise duplicate the real printer - * name - */ - if (strcmp(name, printer->name) != 0) { - addr->pname = strdup(name); - } else { - addr->pname = strdup(printer->name); - } - } - } - - return (addr); -} - - -/* - * FUNCTION: - * ns_bsd_addr_t **ns_bsd_addr_get_list() - * OUTPUT: - * ns_bsd_addr_t **(return) - a list of bsd addresses for all printers - * in all "name services" - * DESCRIPTION: - * This function will gather a list of all printer addresses in all - * of the "name services". All redundancy is removed. - */ -ns_bsd_addr_t ** -ns_bsd_addr_get_list(int unique) - -{ - ns_printer_t **printers; - ns_bsd_addr_t **list = NULL; - char **aliases = NULL; - - for (printers = ns_printer_get_list(NULL); - printers != NULL && *printers != NULL; printers++) { - ns_bsd_addr_t *addr; - - if (strcmp(NS_NAME_ALL, (*printers)->name) == 0) - continue; - - if ((addr = ns_get_value(NS_KEY_BSDADDR, *printers)) != NULL) { - if (addr->printer == NULL) - addr->printer = strdup((*printers)->name); - addr->pname = strdup((*printers)->name); - } - - if (unique == UNIQUE) - list = - (ns_bsd_addr_t **)list_append_unique((void **)list, - (void *)addr, (COMP_T)ns_bsd_addr_cmp); - else - if (unique == LOCAL_UNIQUE) - list = - (ns_bsd_addr_t **)list_append_unique((void **)list, - (void *)addr, (COMP_T)ns_bsd_addr_cmp_local); - else - list = (ns_bsd_addr_t **)list_append((void **)list, - (void *)addr); - - for (aliases = (*printers)->aliases; - (aliases != NULL) && (*aliases != NULL); aliases++) - { - /* - * Include any alias names that belong to the printer - */ - - if ((addr = - ns_get_value(NS_KEY_BSDADDR, *printers)) != NULL) - { - if (addr->printer == NULL) - { - addr->printer = strdup(*aliases); - } - addr->pname = strdup(*aliases); - } - - if (unique == UNIQUE) - { - list = (ns_bsd_addr_t **) - list_append_unique((void **)list, - (void *)addr, (COMP_T)ns_bsd_addr_cmp); - } - else - if (unique == LOCAL_UNIQUE) - { - list = (ns_bsd_addr_t **) - list_append_unique((void **)list, - (void *)addr, - (COMP_T)ns_bsd_addr_cmp_local); - } - else - { - list = (ns_bsd_addr_t **) - list_append((void **)list, (void *)addr); - } - } - } - - return (list); -} - - - - -/* - * FUNCTION: - * ns_bsd_addr_t **ns_bsd_addr_get_list() - * OUTPUT: - * ns_bsd_addr_t **(return) - a list of bsd addresses for "_all" printers - * in the "name service" - * DESCRIPTION: - * This function will use the "_all" entry to find a list of printers and - * addresses. The "default" printer is also added to the list. - * All redundancy is removed. - */ -ns_bsd_addr_t ** -ns_bsd_addr_get_all(int unique) -{ - ns_printer_t *printer; - ns_bsd_addr_t **list = NULL; - char **printers; - char *def = NULL; - - if (((def = (char *)getenv("PRINTER")) == NULL) && - ((def = (char *)getenv("LPDEST")) == NULL)) - def = NS_NAME_DEFAULT; - - list = (ns_bsd_addr_t **)list_append((void **)list, - (void *)ns_bsd_addr_get_name(def)); - - endprinterentry(); - if ((printer = ns_printer_get_name(NS_NAME_ALL, NULL)) == NULL) - return (ns_bsd_addr_get_list(unique)); - - for (printers = (char **)ns_get_value(NS_KEY_ALL, printer); - printers != NULL && *printers != NULL; printers++) { - ns_bsd_addr_t *addr; - - addr = ns_bsd_addr_get_name(*printers); - if (addr != NULL) - addr->pname = *printers; - if (unique == UNIQUE) - list = - (ns_bsd_addr_t **)list_append_unique((void **)list, - (void *)addr, (COMP_T)ns_bsd_addr_cmp); - else - list = (ns_bsd_addr_t **)list_append((void **)list, - (void *)addr); - } - - return (list); -} - -ns_bsd_addr_t * -ns_bsd_addr_get_default() -{ - char *def = NULL; - ns_bsd_addr_t *addr; - - if (((def = (char *)getenv("PRINTER")) == NULL) && - ((def = (char *)getenv("LPDEST")) == NULL)) { - def = NS_NAME_DEFAULT; - addr = ns_bsd_addr_get_name(def); - if (addr != NULL) { - addr->pname = def; - return (addr); - } - } - - return (NULL); -} diff --git a/usr/src/lib/print/libprint/common/ns_cmn_kvp.c b/usr/src/lib/print/libprint/common/ns_cmn_kvp.c deleted file mode 100644 index 3fdacd7e5d..0000000000 --- a/usr/src/lib/print/libprint/common/ns_cmn_kvp.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <stdarg.h> -#include <string.h> - -#include <ns.h> -#include <list.h> - -/* - * Commonly Used routines... - */ - -/* - * FUNCTION: - * kvp_create(const char *key, const void *value) - * INPUT(S): - * const char *key - * - key for key/value pair - * const void *value - * - value for key/value pair - * OUTPUT(S): - * ns_kvp_t * (return value) - * - pointer to structure containing the key/value pair - * DESCRIPTION: - */ -ns_kvp_t * -ns_kvp_create(const char *key, const char *value) -{ - ns_kvp_t *kvp; - - if ((kvp = calloc(1, sizeof (*kvp))) != NULL) { - kvp->key = strdup(key); - kvp->value = (char *)value; - } - return (kvp); -} - -void -ns_kvp_destroy(ns_kvp_t *kvp) -{ - if (kvp != NULL) { - if (kvp->key != NULL) - free(kvp->key); - if (kvp->value != NULL) - free(kvp->value); - free(kvp); - } -} - - - - -/* - * FUNCTION: - * ns_kvp_match_key(const ns_kvp_t *kvp, const char *key) - * INPUT(S): - * const ns_kvp_t *kvp - * - key/value pair to check - * const char *key - * - key for matching - * OUTPUT(S): - * int (return value) - * - 0 if matched - * DESCRIPTION: - */ -static int -ns_kvp_match_key(const ns_kvp_t *kvp, char *key) -{ - if ((kvp != NULL) && (kvp->key != NULL) && (key != NULL)) - return (strcmp(kvp->key, key)); - return (-1); -} - - -/* - * FUNCTION: - * ns_r_get_value(const char *key, const ns_printer_t *printer) - * INPUT(S): - * const char *key - * - key for matching - * const ns_printer_t *printer - * - printer to glean this from - * OUTPUT(S): - * char * (return value) - * - NULL, if not matched - * DESCRIPTION: - */ -static void * -ns_r_get_value(const char *key, const ns_printer_t *printer, int level) -{ - ns_kvp_t *kvp, **attrs; - - if ((key == NULL) || (printer == NULL) || - (printer->attributes == NULL)) - return (NULL); - - if (level++ == 16) - return (NULL); - - /* find it right here */ - if ((kvp = list_locate((void **)printer->attributes, - (COMP_T)ns_kvp_match_key, (void *)key)) != NULL) { - void *value = string_to_value(key, kvp->value); - - /* fill in an empty printer for a bsdaddr */ - if (strcmp(key, NS_KEY_BSDADDR) == 0) { - ns_bsd_addr_t *addr = value; - - if (addr->printer == NULL) - addr->printer = strdup(printer->name); - } - return (value); - } - - /* find it in a child */ - for (attrs = printer->attributes; attrs != NULL && *attrs != NULL; - attrs++) { - void *value = NULL; - - if ((strcmp((*attrs)->key, NS_KEY_ALL) == 0) || - (strcmp((*attrs)->key, NS_KEY_GROUP) == 0)) { - char **printers; - - for (printers = string_to_value((*attrs)->key, - (*attrs)->value); - printers != NULL && *printers != NULL; printers++) { - ns_printer_t *printer = - ns_printer_get_name(*printers, NULL); - - if ((value = ns_r_get_value(key, printer, - level)) != NULL) - return (value); - ns_printer_destroy(printer); - } - } else if (strcmp((*attrs)->key, NS_KEY_LIST) == 0) { - ns_printer_t **printers; - - for (printers = string_to_value((*attrs)->key, - (*attrs)->value); - printers != NULL && *printers != NULL; printers++) { - if ((value = ns_r_get_value(key, *printers, - level)) != NULL) - return (value); - } - } else if (strcmp((*attrs)->key, NS_KEY_USE) == 0) { - char *string = NULL; - ns_printer_t *printer = - ns_printer_get_name((*attrs)->value, NULL); - if ((value = ns_r_get_value(key, printer, - level)) != NULL) - string = value_to_string(string, value); - if (string != NULL) - value = string_to_value(key, string); - ns_printer_destroy(printer); - } - - if (value != NULL) - return (value); - } - - return (NULL); -} - - -/* - * ns_get_value() gets the value of the passed in attribute from the passed - * in printer structure. The value is returned in a converted format. - */ -void * -ns_get_value(const char *key, const ns_printer_t *printer) -{ - return (ns_r_get_value(key, printer, 0)); -} - - -/* - * ns_get_value_string() gets the value of the key passed in from the - * printer structure passed in. The results is an ascii string. - */ -char * -ns_get_value_string(const char *key, const ns_printer_t *printer) -{ - return ((char *)value_to_string(key, ns_get_value(key, printer))); -} - - -/* - * ns_set_value() sets the passed in kvp in the passed in printer structure, - * This is done by converting the value to a string first. - */ -int -ns_set_value(const char *key, const void *value, ns_printer_t *printer) -{ - return (ns_set_value_from_string(key, - value_to_string(key, (void *)value), printer)); -} - - -/* - * ns_set_value_from_string() sets the passed in kvp in the passed in printer - * structure. - */ -int -ns_set_value_from_string(const char *key, const char *string, - ns_printer_t *printer) -{ - if (printer == NULL) - return (-1); - - if (key == NULL) - list_iterate((void **)printer->attributes, - (VFUNC_T)ns_kvp_destroy); - else { - ns_kvp_t *kvp; - - if (((kvp = list_locate((void **)printer->attributes, - (COMP_T)ns_kvp_match_key, - (void *)key)) == NULL) && - ((kvp = calloc(1, sizeof (*kvp))) != NULL)) { - kvp->key = strdup(key); - printer->attributes = (ns_kvp_t **) - list_append((void **)printer->attributes, kvp); - } - if (string != NULL) - kvp->value = strdup(string); - else - kvp->value = NULL; - } - - return (0); -} diff --git a/usr/src/lib/print/libprint/common/ns_cmn_printer.c b/usr/src/lib/print/libprint/common/ns_cmn_printer.c deleted file mode 100644 index 25e344b3c4..0000000000 --- a/usr/src/lib/print/libprint/common/ns_cmn_printer.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/*LINTLIBRARY*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <stdarg.h> -#include <string.h> -#include <syslog.h> - -#include <ns.h> -#include <list.h> - -extern void ns_kvp_destroy(ns_kvp_t *); - -/* - * Commonly Used routines... - */ - -/* - * FUNCTION: - * printer_create(char *name, char **aliases, char *source, - * ns_kvp_t **attributes) - * INPUT(S): - * char *name - * - primary name of printer - * char **aliases - * - aliases for printer - * char *source - * - name service derived from - * ks_kvp_t **attributes - * - key/value pairs - * OUTPUT(S): - * ns_printer_t * (return value) - * - pointer to printer object structure - * DESCRIPTION: - */ -ns_printer_t * -ns_printer_create(char *name, char **aliases, char *source, - ns_kvp_t **attributes) -{ - ns_printer_t *printer; - - if ((printer = (ns_printer_t *)calloc(1, sizeof (*printer))) != NULL) { - printer->name = (char *)name; - printer->aliases = (char **)aliases; - printer->source = (char *)source; - printer->attributes = (ns_kvp_t **)attributes; - } - return (printer); -} - - -static int -ns_strcmp(char *s1, char *s2) -{ - return (strcmp(s1, s2) != 0); -} - - -/* - * FUNCTION: - * ns_printer_match_name(const ns_printer_t *printer, const char *name) - * INPUT(S): - * const ns_printer_t *printer - * - key/value pair to check - * const char *key - * - key for matching - * OUTPUT(S): - * int (return value) - * - 0 if matched - * DESCRIPTION: - */ -int -ns_printer_match_name(ns_printer_t *printer, const char *name) -{ - if ((printer == NULL) || (printer->name == NULL) || (name == NULL)) - return (-1); - - if ((strcmp(printer->name, name) == 0) || - (list_locate((void **)printer->aliases, - (COMP_T)ns_strcmp, (void *)name) != NULL)) - return (0); - - return (-1); -} - - -static void -_ns_append_printer_name(const char *name, va_list ap) -{ - char *buf = va_arg(ap, char *); - int bufsize = va_arg(ap, int); - - if (name == NULL) - return; - - (void) strlcat(buf, name, bufsize); - (void) strlcat(buf, "|", bufsize); -} - -/* - * FUNCTION: - * char *ns_printer_name_list(const ns_printer_t *printer) - * INPUT: - * const ns_printer_t *printer - printer object to generate list from - * OUTPUT: - * char * (return) - a newly allocated string containing the names of - * the printer - */ -char * -ns_printer_name_list(const ns_printer_t *printer) -{ - char buf[BUFSIZ]; - - if ((printer == NULL) || (printer->name == NULL)) - return (NULL); - - if (snprintf(buf, sizeof (buf), "%s|", printer->name) >= sizeof (buf)) { - syslog(LOG_ERR, "ns_printer_name:buffer overflow"); - return (NULL); - } - - list_iterate((void **)printer->aliases, - (VFUNC_T)_ns_append_printer_name, buf, sizeof (buf)); - - buf[strlen(buf) - 1] = (char)NULL; - - return (strdup(buf)); -} diff --git a/usr/src/lib/print/libprint/common/nss_convert.c b/usr/src/lib/print/libprint/common/nss_convert.c deleted file mode 100644 index eaee6df5b2..0000000000 --- a/usr/src/lib/print/libprint/common/nss_convert.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This file contains routines necessary to convert a string buffer into - * a printer object. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <string.h> -#include <stdarg.h> -#include <syslog.h> - -#include <ns.h> -#include <list.h> - -#define ESCAPE_CHARS "\\\n=:" /* \, \n, =, : */ - -/* - * Just like strncat(3C), but escapes the supplied characters. - * This allows the escape character '\' and seperators to be part of the - * keys or values. - */ -char * -strncat_escaped(char *d, char *s, int len, char *escape) -{ - char *t = d; - - while ((*t != NULL) && (len > 0)) - len--, t++; - - if (escape == NULL) - escape = "\\"; - - while ((*s != NULL) && (len > 0)) { - if (strchr(escape, *s) != NULL) - len--, *t++ = '\\'; - len--, *t++ = *s++; - } - *t = NULL; - - return (d); -} - - - -char * -_cvt_printer_to_entry(ns_printer_t *printer, char *buf, int buflen) -{ - int i, len; - int bufferok = 1; - - (void) memset(buf, NULL, buflen); - - if ((printer == NULL) || (printer->attributes == NULL)) - return (NULL); - - if (snprintf(buf, buflen, "%s", printer->name) >= buflen) { - (void) memset(buf, NULL, buflen); - syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); - return (NULL); - } - - if ((printer->aliases != NULL) && (printer->aliases[0] != NULL)) { - char **alias = printer->aliases; - - while (*alias != NULL) { - (void) strlcat(buf, "|", buflen); - (void) strncat_escaped(buf, *alias++, buflen, - ESCAPE_CHARS); - } - } - - if (strlcat(buf, ":", buflen) >= buflen) { - (void) memset(buf, NULL, buflen); - syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); - return (NULL); - } - - len = strlen(buf); - - for (i = 0; printer->attributes[i] != NULL && bufferok; i++) { - ns_kvp_t *kvp = printer->attributes[i]; - - if (kvp->value == NULL) - continue; - (void) strlcat(buf, "\\\n\t:", buflen); - (void) strncat_escaped(buf, kvp->key, buflen, ESCAPE_CHARS); - (void) strlcat(buf, "=", buflen); - (void) strncat_escaped(buf, kvp->value, buflen, ESCAPE_CHARS); - if (strlcat(buf, ":", buflen) >= buflen) { - bufferok = 0; - } - } - - if (!bufferok) { - (void) memset(buf, NULL, buflen); - syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); - return (NULL); - } - - if (strlen(buf) == len) { /* there were no attributes */ - (void) memset(buf, NULL, buflen); - buf = NULL; - } - - return (buf); -} - - -ns_printer_t * -_cvt_nss_entry_to_printer(char *entry, char *ns) -{ - char *name = NULL, - *key = NULL, - **aliases = NULL, - *cp, - buf[BUFSIZ]; - int in_namelist = 1, buf_pos = 0; - ns_printer_t *printer = NULL; - - if (entry == NULL) - return (NULL); - - (void) memset(buf, NULL, sizeof (buf)); - for (cp = entry; *cp != NULL; cp++) { - switch (*cp) { - case ':': /* end of kvp */ - if (in_namelist != 0) { - if (name == NULL) - name = strdup(buf); - else - aliases = (char **)list_append( - (void **)aliases, - (void *)strdup(buf)); - printer = (ns_printer_t *)ns_printer_create( - name, aliases, ns, NULL); - in_namelist = 0; - } else if (key != NULL) - (void) ns_set_value_from_string(key, buf, - printer); - (void) memset(buf, NULL, sizeof (buf)); - buf_pos = 0; - key = NULL; - break; - case '=': /* kvp seperator */ - if (key == NULL) { - key = strdup(buf); - (void) memset(buf, NULL, sizeof (buf)); - buf_pos = 0; - } else - buf[buf_pos++] = *cp; - break; - case '|': /* namelist seperator */ - if (in_namelist != 0) { - if (name == NULL) - name = strdup(buf); - else - aliases = (char **)list_append( - (void **)aliases, - (void *)strdup(buf)); - (void) memset(buf, NULL, sizeof (buf)); - buf_pos = 0; - } else /* add it to the buffer */ - buf[buf_pos++] = *cp; - break; - case '\\': /* escape char */ - buf[buf_pos++] = *(++cp); - break; - default: - buf[buf_pos++] = *cp; - } - - } - - if (key != NULL) - (void) ns_set_value_from_string(key, buf, printer); - - return (printer); -} diff --git a/usr/src/lib/print/libprint/common/nss_ldap.c b/usr/src/lib/print/libprint/common/nss_ldap.c deleted file mode 100644 index c2140d5048..0000000000 --- a/usr/src/lib/print/libprint/common/nss_ldap.c +++ /dev/null @@ -1,2477 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <stdarg.h> -#include <fcntl.h> -#include <syslog.h> -#include <errno.h> -#include <pwd.h> -#include <libintl.h> -#include <netdb.h> /* for rcmd() */ - -#include <ns.h> -#include <list.h> - -#define LDAP_REFERRALS -#include <lber.h> -#include <ldap.h> -#include <sys/systeminfo.h> - - -/* - * This modules contains the code required to manipulate printer objects in - * a LDAP directory for the Naming Service (NS) switch. - * It can "add", "modify" and "delete" the objects on the given ldap server - * and in the given NS domain DN, eg. "dc=mkg,dc=sun,dc=com". - * Note: printers known to the naming service are contained in the RDN - * "ou=printers" under the NS domain DN - */ - -#define PCONTAINER "ou=printers" - -/* attribute keywords */ -#define ATTR_DN "dn" -#define ATTR_OCLASS "objectClass" -#define ATTR_URI "printer-uri" -#define ATTR_PNAME "printer-name" -#define ATTR_XRISUP "printer-xri-supported" -#define ATTR_BSDADDR "sun-printer-bsdaddr" -#define ATTR_KVP "sun-printer-kvp" - -/* objectClass values */ -#define OCV_TOP "top" -#define OCV_PSERVICE "printerService" -#define OCV_SUNPRT "sunPrinter" -#define OCV_PABSTRACT "printerAbstract" - -/* xri-supported attribute value */ -#define AV_UNKNOWN "unknown" - - -/* - * LDAP objectclass atributes that the user can explicity change - */ - -static const char *nsl_attr_printerService[] = { - "printer-uri", - "printer-xri-supported", - /* Not allowed "printer-name", */ - "printer-natural-language-configured", - "printer-location", - "printer-info", - "printer-more-info", - "printer-make-and-model", - "printer-charset-configured", - "printer-charset-supported", - "printer-generated-natural-language-supported", - "printer-document-format-supported", - "printer-color-supported", - "printer-compression-supported", - "printer-pages-per-minute", - "printer-pages-per-minute-color", - "printer-finishings-supported", - "printer-number-up-supported", - "printer-sides-supported", - "printer-media-supported", - "printer-media-local-supported", - "printer-resolution-supported", - "printer-print-quality-supported", - "printer-job-priority-supported", - "printer-copies-supported", - "printer-job-k-octets-supported", - "printer-current-operator", - "printer-service-person", - "printer-delivery-orientation-supported", - "printer-stacking-order-supported", - "printer-output-features-supported", - (char *)NULL -}; - - -static const char *nsl_attr_printerIPP[] = { - "printer-ipp-versions-supported", - "printer-multiple-document-jobs-supported", - (char *)NULL -}; - -static const char *nsl_attr_sunPrinter[] = { - /* Not allowed "sun-printer-bsdaddr", */ - /* Not allowed "sun-printer-kvp", */ - (char *)NULL -}; - - -/* - * List of LDAP attributes that user is not allowed to explicitly change - */ -static const char *nsl_attr_notAllowed[] = { - ATTR_DN, - ATTR_OCLASS, /* objectclass */ - ATTR_PNAME, /* printer-name */ - ATTR_BSDADDR, - ATTR_KVP, - (char *)NULL -}; - - -static NSL_RESULT _connectToLDAP(ns_cred_t *cred, LDAP **ld); -static uchar_t *_constructPrinterDN(uchar_t *printerName, - uchar_t *domainDN, char **attrList); -static NSL_RESULT _checkPrinterExists(LDAP *ld, uchar_t *printerName, - uchar_t *domainDN, uchar_t **printerDN); -static NSL_RESULT _checkPrinterDNExists(LDAP *ld, uchar_t *objectDN); -static NSL_RESULT _checkSunPrinter(LDAP *ld, uchar_t *printerDN); -static NSL_RESULT _addNewPrinterObject(LDAP *ld, uchar_t *printerName, - uchar_t *domainDN, char **attrList); -static NSL_RESULT _modifyPrinterObject(LDAP *ld, uchar_t *printerDN, - uchar_t *printerName, uchar_t *domainDN, char **attrList); -static NSL_RESULT _checkAttributes(char **list); -static NSL_RESULT _addLDAPmodValue(LDAPMod ***attrs, char *type, char *value); -static NSL_RESULT _modLDAPmodValue(LDAPMod ***attrs, char *type, char *value); -static NSL_RESULT _constructAddLDAPMod(uchar_t *printerName, - char **attrList, LDAPMod ***attrs); -static NSL_RESULT _constructModLDAPMod(uchar_t *printerName, int sunPrinter, - char **attrList, char ***oldKVPList, LDAPMod ***attrs); -static NSL_RESULT _compareURIinDNs(uchar_t *dn1, uchar_t *dn2); -static uchar_t *_getThisNSDomainDN(void); -static int _popen(char *cmd, char *results, int size); -static int _attrInList(char *attr, const char **list); -static int _attrInLDAPList(char *attr); -static NSL_RESULT _getCurrentKVPValues(LDAP *ld, - uchar_t *objectDN, char ***list); -static void _freeList(char ***list); -static NSL_RESULT _modAttrKVP(char *value, char ***kvpList); -static NSL_RESULT _attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists); -static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp, - int *methodp, int freeit); - -/* - * ***************************************************************************** - * - * Function: ldap_put_printer() - * - * Description: Action the request to change a printer object in the LDAP - * directory DIT. The object is either added, modified or deleted - * depending on the request's attribute list. A null list indicates - * the request is a delete. - * The object's DN is constructed from the supplied domain DN and - * a check is done to see if the object exists already, if it - * doesn't exist then this is a request to add a new object - * If a URI is given in the attribute list and it is different to - * the existing printing object's DN then the request will be - * rejected. - * - * - * Parameters: - * Input: const ns_printer_t *printer - * - this structure contains the following : - * char *printerName - name of the printer - * ns_cred_t *cred - structure containing the ldap host and - * port, user, password and NS domain DN for the - * directory server to be updated. - * char **attrList - pointer to a list of attribute key values - * for the printer object. If the object does - * not already exist then this list contains the - * values for the new object, otherwise this list - * is a list of attributes to modify. For modify - * a null attribute value is a attribute delete - * request. A NULL ptr = delete the object. - * Output: None - * - * Returns: int - 0 = request actioned okay - * !0 = error - see NSL_RESULT codes - * - * ***************************************************************************** - */ - -int -ldap_put_printer(const ns_printer_t *printer) - -{ - NSL_RESULT result = NSL_OK; - NSL_RESULT printerExists = NSL_ERR_UNKNOWN_PRINTER; - LDAP *ld = NULL; - uchar_t *printerDN = NULL; - uchar_t *domainDN = NULL; - char *printerName = NULL; - ns_cred_t *cred = NULL; - char **attrList = NULL; - - /* -------- */ - - /* - * Note: the "attributes" list should be null for ldap as the attribute - * values are passed in the nsdata field - */ - - if ((printer != NULL) && - (printer->attributes == NULL) && (printer->name != NULL)) - { - /* extract required pointer values from structure */ - - printerName = printer->name; - cred = printer->cred; - if (printer->nsdata != NULL) - { - attrList = ((NS_LDAPDATA *)(printer->nsdata))->attrList; - } - - /* connect and bind to the ldap directory server */ - - result = _connectToLDAP(cred, &ld); - if ((result == NSL_OK) && (ld != NULL)) - { - /* - * check if the NS domain DN was given, if not use the - * current NS domain - */ - - if (cred->domainDN != NULL) - { - domainDN = (uchar_t *) - strdup((char *)cred->domainDN); - } - else - { - /* get DN of current domain */ - domainDN = _getThisNSDomainDN(); - } - - printerExists = - _checkPrinterExists(ld, (uchar_t *)printerName, - domainDN, &printerDN); - if (printerExists != LDAP_SUCCESS) - { - /* - * could not find the printer by printer-name, - * but there could be a non sunPrinter object - * so if the printer-uri was given check if - * an object for that exists - */ - printerDN = - _constructPrinterDN(NULL, - domainDN, attrList); - if (printerDN != NULL) - { - printerExists = _checkPrinterDNExists( - ld, printerDN); - } - } -#ifdef DEBUG -if (printerExists == NSL_OK) -{ -printf("DN found = '%s' for '%s'\n", printerDN, printerName); -} -#endif - - if (attrList == NULL) - { - /* - * a null list indicates that this is a DELETE - * object request, so if object exists delete - * it, otherwise report an error. - */ - if (printerExists == LDAP_SUCCESS) - { - result = ldap_delete_s(ld, - (char *)printerDN); - if (result != LDAP_SUCCESS) - { - result = NSL_ERR_DEL_FAILED; -#ifdef DEBUG -ldap_perror(ld, "ldap_delete_s failed"); -#endif - } - } - else - { - result = NSL_ERR_UNKNOWN_PRINTER; - } - } - else - { - /* - * if object exists then this is a - * modify request otherwise is is an add request - */ - - if (printerExists == LDAP_SUCCESS) - { - /* - * Modify the printer object to - * give it the new attribute values - * specified by the user - */ - result = - _modifyPrinterObject(ld, printerDN, - (uchar_t *)printerName, - domainDN, attrList); - } - else - { - /* - * add new printer object into the - * ldap directory with the user - * specified attribute values - */ - result = - _addNewPrinterObject(ld, - (uchar_t *)printerName, - domainDN, attrList); - } - } - - if (printerDN != NULL) - { - free(printerDN); - } - if (domainDN != NULL) - { - free(domainDN); - } - - /* disconnect from LDAP server */ - - (void) ldap_unbind(ld); - } - } - - else - { - /* no printerName given */ - result = NSL_ERR_INTERNAL; - } - - return ((int)result); -} /* ldap_put_printer */ - - - - -/* - * ***************************************************************************** - * - * Function: _connectToLDAP() - * - * Description: Setup the connection and bind to the LDAP directory server. - * The function returns the ldap connection descriptor - * - * Note: Currently the native ldap functions do not support secure - * passwords, when this is supported this function will require - * updating to allow the type passed in cred->passwdType to - * be used with the ldap_simple_bind() - * - * Parameters: - * Input: ns_cred_t *cred - structure containing the credentials (host, - * port, user and password) required to bind - * to the directory server to be updated. - * char *printerName - printer name used only for error messages - * Output: LDAP** - ldap connection descriptor pointer. NULL = failed - * - * Returns: NSL_RESULT - NSL_OK = connected okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_connectToLDAP(ns_cred_t *cred, LDAP **ld) - -{ - NSL_RESULT result = NSL_OK; - int lresult = 0; - int ldapPort = LDAP_PORT; /* default LDAP port number */ - int protoVersion = LDAP_VERSION3; - int derefOption = LDAP_DEREF_NEVER; - int referrals = 1; - char hostname[MAXHOSTNAMELEN]; - int tmpMethod = LDAP_AUTH_SIMPLE; /* temp - until its passed in */ - - /* -------- */ - - if ((ld == NULL) || (cred == NULL) || - ((cred->passwd == NULL) || (cred->binddn == NULL))) - { - result = NSL_ERR_CREDENTIALS; - } - - else - { - *ld = NULL; - - /* if host was not given then bind to local host */ - - if (cred->host != NULL) - { - (void) strlcpy(hostname, cred->host, sizeof (hostname)); - } - else - { - (void) sysinfo(SI_HOSTNAME, - hostname, sizeof (hostname)); - } - - /* initialise the connection to the ldap server */ - - if (cred->port != 0) - { - ldapPort = cred->port; - } - *ld = ldap_init(hostname, ldapPort); - if (*ld == NULL) - { - /* connection setup failed */ - result = NSL_ERR_CONNECT; -#ifdef DEBUG -(void) perror("ldap_init"); -#endif - } - else - { - /* set ldap options */ - - (void) ldap_set_option(*ld, LDAP_OPT_DEREF, - &derefOption); - (void) ldap_set_option(*ld, LDAP_OPT_PROTOCOL_VERSION, - &protoVersion); - (void) ldap_set_option(*ld, LDAP_OPT_REFERRALS, - &referrals); - - /* bind to the user DN in the directory */ - - /* cred->passwdType is currently not supported */ - - lresult = ldap_simple_bind_s(*ld, - cred->binddn, cred->passwd); - - /* - * before doing anything else, set up the function to - * call to get authentication details if the - * ldap update function calls (eg. ldap_add_s()) get a - * "referral" (to another ldap server) from the - * original ldap server, eg. if we are trying to do - * a update on a LDAP replica server. - */ - (void) _manageReferralCredentials(*ld, - &(cred->binddn), &(cred->passwd), - &tmpMethod, -1); - ldap_set_rebind_proc(*ld, - (LDAP_REBINDPROC_CALLBACK *) - _manageReferralCredentials, NULL); - - if (lresult != LDAP_SUCCESS) - { - result = NSL_ERR_BIND; - *ld = NULL; -#ifdef DEBUG -(void) ldap_perror(*ld, "ldap_simple_bind_s"); -#endif - } - } - } - - return (result); -} /* _connectToLDAP */ - - - - - -/* - * ***************************************************************************** - * - * Function: _constructPrinterDN() - * - * Description: Construct the DN for the printer object from its name and NS - * domain DN. If the printer-uri is given in the attrList then - * that is used instead of the printerName. - * - * Parameters: - * Input: uchar_t *printerName - * uchar_t *domainDN - * char **attrList - this list is searched for printer-uri - * Output: None - * - * Returns: uchar_t* - pointer to the DN, this memory is malloced so - * must be freed using free() when finished with. - * - * ***************************************************************************** - */ - -static uchar_t * -_constructPrinterDN(uchar_t *printerName, uchar_t *domainDN, char **attrList) - -{ - uchar_t *dn = NULL; - uchar_t *uri = NULL; - char **p = NULL; - int len = 0; - - /* ------- */ - - /* first search for printer-uri in the attribute list */ - - for (p = attrList; (p != NULL) && (*p != NULL) && (uri == NULL); p++) - { - /* get length of this key word */ - - for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); - - if ((strncasecmp(*p, ATTR_URI, len) == 0) && - (strlen(*p) > len+1)) - { - uri = (uchar_t *)&((*p)[len+1]); - } - } - - - if (domainDN != NULL) { - size_t size; - - /* malloc memory for the DN and then construct it */ - - if ((uri == NULL) && (printerName != NULL)) - { - /* use the printerName for the RDN */ - - size = strlen(ATTR_URI) + - strlen((char *)printerName) + - strlen((char *)domainDN) + - strlen(PCONTAINER) + - 10; /* plus a few extra */ - - if ((dn = malloc(size)) != NULL) - (void) snprintf((char *)dn, size, "%s=%s,%s,%s", - ATTR_URI, printerName, PCONTAINER, domainDN); - } - else - if (uri != NULL) - { - /* use the URI for the RDN */ - - size = strlen(ATTR_URI) + - strlen((char *)uri) + - strlen((char *)domainDN) + - strlen(PCONTAINER) + - 10; /* plus a few extra */ - - if ((dn = malloc(size)) != NULL) - (void) snprintf((char *)dn, size, "%s=%s,%s,%s", - ATTR_URI, uri, PCONTAINER, domainDN); - } - - /* - * else - * { - * printName not given so return null - * } - */ - - } - - return (dn); /* caller must free this memory */ -} /* _constructPrinterDN */ - - - -/* - * ***************************************************************************** - * - * Function: _checkPrinterExists() - * - * Description: Check that the printer object for the printerName exists in the - * directory DIT and then extract the object's DN - * The function uses an exiting ldap connection and does a - * search for the printerName in the supplied domain DN. - * - * Parameters: - * Input: LDAP *ld - existing ldap connection descriptor - * uchar_t *printerName - printer name - * uchar_t *domainDN - DN of domain to search in - * Output: uchar_t **printerDN - DN of the printer - the caller should - * free this memory using free() - * - * Result: NSL_RESULT - NSL_OK = object exists - * - * ***************************************************************************** - */ - -static NSL_RESULT -_checkPrinterExists(LDAP *ld, uchar_t *printerName, uchar_t *domainDN, - uchar_t **printerDN) - -{ - NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; - int sresult = LDAP_NO_SUCH_OBJECT; - LDAPMessage *ldapMsg = NULL; - char *requiredAttrs[2] = { ATTR_PNAME, NULL }; - LDAPMessage *ldapEntry = NULL; - uchar_t *filter = NULL; - uchar_t *baseDN = NULL; - - /* ---------- */ - - if ((printerName != NULL) && (domainDN != NULL) && (printerDN != NULL)) - { - size_t size; - - if (printerDN != NULL) - { - *printerDN = NULL; - } - - /* search for this Printer in the directory */ - - size = (3 + strlen((char *)printerName) + strlen(ATTR_PNAME) + - 2); - - if ((filter = malloc(size)) != NULL) - (void) snprintf((char *)filter, size, "(%s=%s)", - ATTR_PNAME, (char *)printerName); - - size = (strlen((char *)domainDN) + strlen(PCONTAINER) + 5); - - if ((baseDN = malloc(size)) != NULL) - (void) snprintf((char *)baseDN, size, "%s,%s", - PCONTAINER, (char *)domainDN); - - sresult = ldap_search_s(ld, (char *)baseDN, LDAP_SCOPE_SUBTREE, - (char *)filter, requiredAttrs, 0, &ldapMsg); - if (sresult == LDAP_SUCCESS) - { - /* check that the object exists and extract its DN */ - - ldapEntry = ldap_first_entry(ld, ldapMsg); - if (ldapEntry != NULL) - { - /* object found - there should only be one */ - result = NSL_OK; - - if (printerDN != NULL) - { - *printerDN = (uchar_t *) - ldap_get_dn(ld, ldapEntry); - } - } - - (void) ldap_msgfree(ldapMsg); - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _checkPrinterExists */ - - - - -/* - * ***************************************************************************** - * - * Function: _checkPrinterDNExists() - * - * Description: Check that the printer object for the DN exists in the - * directory DIT. - * The function uses an exiting ldap connection and does a - * search for the DN supplied. - * - * Parameters: LDAP *ld - existing ldap connection descriptor - * char *objectDN - DN to search for - * - * Result: NSL_RESULT - NSL_OK = object exists - * - * ***************************************************************************** - */ - -static NSL_RESULT -_checkPrinterDNExists(LDAP *ld, uchar_t *objectDN) - -{ - NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; - int sresult = LDAP_NO_SUCH_OBJECT; - LDAPMessage *ldapMsg; - char *requiredAttrs[2] = { ATTR_PNAME, NULL }; - LDAPMessage *ldapEntry; - - /* ---------- */ - - if ((ld != NULL) && (objectDN != NULL)) - { - /* search for this Printer in the directory */ - - sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE, - "(objectclass=*)", requiredAttrs, 0, &ldapMsg); - if (sresult == LDAP_SUCCESS) - { - /* check that the object exists */ - ldapEntry = ldap_first_entry(ld, ldapMsg); - if (ldapEntry != NULL) - { - /* object found */ - result = NSL_OK; - } - - (void) ldap_msgfree(ldapMsg); - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _checkPrinterDNExists */ - - - - - -/* - * ***************************************************************************** - * - * Function: _checkSunPrinter() - * - * Description: Check that the printer object for the printerDN is a sunPrinter - * ie. it has the required objectclass attribute value. - * - * Parameters: - * Input: LDAP *ld - existing ldap connection descriptor - * Output: uchar_t *printerDN - DN of the printer - * - * Result: NSL_RESULT - NSL_OK = object exists and is a sunPrinter - * - * ***************************************************************************** - */ - -static NSL_RESULT -_checkSunPrinter(LDAP *ld, uchar_t *printerDN) - -{ - NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; - int sresult = LDAP_NO_SUCH_OBJECT; - char *requiredAttrs[2] = { ATTR_PNAME, NULL }; - LDAPMessage *ldapMsg = NULL; - LDAPMessage *ldapEntry = NULL; - char *filter = NULL; - - /* ---------- */ - - if ((ld != NULL) && (printerDN != NULL)) - { - size_t size; - - /* search for this Printer in the directory */ - - size = (3 + strlen(OCV_SUNPRT) + strlen(ATTR_OCLASS) + 2); - if ((filter = malloc(size)) != NULL) - (void) snprintf(filter, size, "(%s=%s)", - ATTR_OCLASS, OCV_SUNPRT); - - sresult = ldap_search_s(ld, (char *)printerDN, - LDAP_SCOPE_SUBTREE, filter, - requiredAttrs, 0, &ldapMsg); - if (sresult == LDAP_SUCCESS) - { - /* check that the printer object exists */ - - ldapEntry = ldap_first_entry(ld, ldapMsg); - if (ldapEntry != NULL) - { - /* object is a sunPrinter */ - result = NSL_OK; - } - - (void) ldap_msgfree(ldapMsg); - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _checkSunPrinter */ - - - - - -/* - * ***************************************************************************** - * - * Function: _addNewPrinterObject() - * - * Description: For the given printerName add a printer object into the - * LDAP directory NS domain. The object is created with the - * supplied attribute values. Note: if the printer's uri is - * given that is used as the RDN otherwise the printer's - * name is used as the RDN - * - * Parameters: - * Input: LDAP *ld - existing ldap connection descriptor - * uchar_t *printerName - Name of printer to be added - * uchar_t *domainDN - DN of the domain to add the printer - * char **attrList - user specified attribute values list - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = request actioned okay - * !NSL_OK = error - * - * ***************************************************************************** - */ - -static NSL_RESULT -_addNewPrinterObject(LDAP *ld, uchar_t *printerName, - uchar_t *domainDN, char **attrList) - -{ - NSL_RESULT result = NSL_ERR_ADD_FAILED; - int lresult = 0; - uchar_t *printerDN = NULL; - LDAPMod **attrs = NULL; - - /* ---------- */ - - if ((ld != NULL) && (printerName != NULL) && (domainDN != NULL) && - (attrList != NULL) && (attrList[0] != NULL)) - { - result = _checkAttributes(attrList); - - if (result == NSL_OK) - { - /* - * construct a DN for the printer from the - * printerName and printer-uri if given. - */ - printerDN = _constructPrinterDN(printerName, - domainDN, attrList); - if (printerDN != NULL) - { - /* - * setup attribute values in an LDAPMod - * structure and then add the object - */ - result = _constructAddLDAPMod(printerName, - attrList, &attrs); - if (result == NSL_OK) - { - lresult = ldap_add_s(ld, - (char *)printerDN, attrs); - if (lresult == LDAP_SUCCESS) - { - result = NSL_OK; - } - else - { - result = NSL_ERR_ADD_FAILED; -#ifdef DEBUG -(void) ldap_perror(ld, "ldap_add_s"); -#endif - } - - (void) ldap_mods_free(attrs, 1); - } - free(printerDN); - } - - else - { - result = NSL_ERR_INTERNAL; - } - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _addNewPrinterObject */ - - - - - - -/* - * ***************************************************************************** - * - * Function: _modifyPrinterObject() - * - * Description: Modify the given LDAP printer object to set the new attributes - * in the attribute list. If the printer's URI (specified in the - * attrList) changes the URI of the object the request is rejected. - * - * Parameters: - * Input: LDAP *ld - existing ldap connection descriptor - * uchar_t *printerDN - DN of printer object to modify - * uchar_t *printerName - Name of printer to be modified - * uchar_t *domainDN - DN of the domain the printer is in - * char **attrList - user specified attribute values list - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = object modified okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_modifyPrinterObject(LDAP *ld, uchar_t *printerDN, - uchar_t *printerName, uchar_t *domainDN, char **attrList) - -{ - NSL_RESULT result = NSL_ERR_INTERNAL; - int lresult = 0; - int sunPrinter = 0; - uchar_t *uriDN = NULL; - LDAPMod **attrs = NULL; - char **kvpList = NULL; - - /* ---------- */ - - if ((ld != NULL) && (printerDN != NULL) && (printerName != NULL) && - (domainDN != NULL) && (attrList != NULL) && (attrList[0] != NULL)) - { - result = _checkAttributes(attrList); - - if (result == NSL_OK) - { - /* - * The user may have requested that the printer object - * be given a new URI RDN, so construct a DN for the - * printer from the printerName or the printer-uri (if - * given). - */ - uriDN = _constructPrinterDN(NULL, domainDN, attrList); - - /* - * compare the 2 DNs to see if the URI has changed, - * if uriDN is null then the DN hasn't changed - */ - if ((uriDN == NULL) || ((uriDN != NULL) && - (_compareURIinDNs(printerDN, uriDN) == NSL_OK))) - { - /* - * setup the modify object LDAPMod - * structure and then do the modify - */ - - if (_checkSunPrinter(ld, printerDN) == NSL_OK) - { - sunPrinter = 1; - } - - (void) _getCurrentKVPValues(ld, - printerDN, &kvpList); - - result = _constructModLDAPMod(printerName, - sunPrinter, attrList, - &kvpList, &attrs); - _freeList(&kvpList); - - if ((result == NSL_OK) && (attrs != NULL)) - { - lresult = ldap_modify_s( - ld, (char *)printerDN, attrs); - if (lresult == LDAP_SUCCESS) - { - result = NSL_OK; - } - else - { - result = NSL_ERR_MOD_FAILED; -#ifdef DEBUG -(void) ldap_perror(ld, "ldap_modify_s"); -#endif - } - - (void) ldap_mods_free(attrs, 1); - } - } - else - { - /* - * printer-uri name change has been requested - * this is NOT allowed as it requires that - * a new printer object is created - */ - result = NSL_ERR_RENAME; /* NOT ALLOWED */ - } - - if (uriDN != NULL) - { - free(uriDN); - } - } - } - - return (result); -} /* _modifyPrinterObject */ - - - - -/* - * ***************************************************************************** - * - * Function: _checkAttributes() - * - * Description: Check that the given attribute lists does not contain any - * key words that are not allowed. - * - * Parameters: - * Input: char **list - attribute list to check - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = checked okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_checkAttributes(char **list) - -{ - NSL_RESULT result = NSL_OK; - int len = 0; - char *attr = NULL; - char **p = NULL; - - /* ------ */ - - for (p = list; (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) - { - /* get length of this key word */ - - for (len = 0; ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); - - /* check if the key word is allowed */ - - if (strncasecmp(*p, ATTR_KVP, len) == 0) - { - /* not supported through this interface */ - result = NSL_ERR_KVP; - } - else - if (strncasecmp(*p, ATTR_BSDADDR, len) == 0) - { - /* not supported through this interface */ - result = NSL_ERR_BSDADDR; - } - else - if (strncasecmp(*p, ATTR_PNAME, len) == 0) - { - /* not supported through this interface */ - result = NSL_ERR_PNAME; - } - else - { - /* check for any others */ - - attr = strdup(*p); - attr[len] = '\0'; /* terminate the key */ - - if (_attrInList(attr, nsl_attr_notAllowed)) - { - result = NSL_ERR_NOTALLOWED; - } - } - - } - - return (result); -} /* _checkAttributes */ - - - - -/* - * ***************************************************************************** - * - * Function: _addLDAPmodValue() - * - * Description: Add the given attribute and its value to the LDAPMod array. - * If this is the first entry in the array then create it. - * - * Parameters: - * Input: LDAPMod ***attrs - array to update - * char *type - attribute to add into array - * char *value - attribute value - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = added okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_addLDAPmodValue(LDAPMod ***attrs, char *type, char *value) - -{ - int i = 0; - int j = 0; - NSL_RESULT result = NSL_OK; - - /* ---------- */ - - if ((attrs != NULL) && (type != NULL) && (value != NULL)) - { -#ifdef DEBUG -printf("_addLDAPmodValue() type='%s', value='%s'\n", type, value); -#endif - /* search the existing LDAPMod array for the attribute */ - - for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++) - { - if (strcasecmp((*attrs)[i]->mod_type, type) == 0) - { - break; - } - } - - if (*attrs == NULL) - { - /* array empty so create it */ - - *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *)); - if (*attrs != NULL) - { - i = 0; - } - else - { - result = NSL_ERR_MEMORY; - } - - } - else - if ((*attrs)[i] == NULL) - { - *attrs = (LDAPMod **) - realloc(*attrs, (i+2) * sizeof (LDAPMod *)); - if (*attrs == NULL) - { - result = NSL_ERR_MEMORY; - } - } - } - else - { - result = NSL_ERR_INTERNAL; - } - - if (result == NSL_OK) - { - if ((*attrs)[i] == NULL) - { - /* We've got a new slot. Create the new mod. */ - - (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod)); - if ((*attrs)[i] != NULL) - { - (*attrs)[i]->mod_op = LDAP_MOD_ADD; - (*attrs)[i]->mod_type = strdup(type); - (*attrs)[i]->mod_values = (char **) - malloc(2 * sizeof (char *)); - if ((*attrs)[i]->mod_values != NULL) - { - (*attrs)[i]->mod_values[0] = - strdup(value); - (*attrs)[i]->mod_values[1] = NULL; - (*attrs)[i+1] = NULL; - } - else - { - result = NSL_ERR_MEMORY; - } - } - else - { - result = NSL_ERR_MEMORY; - } - } - - else - { - /* Found an existing entry so add value to it */ - - for (j = 0; (*attrs)[i]->mod_values[j] != NULL; j++); - - (*attrs)[i]->mod_values = - (char **)realloc((*attrs)[i]->mod_values, - (j + 2) * sizeof (char *)); - if ((*attrs)[i]->mod_values != NULL) - { - (*attrs)[i]->mod_values[j] = strdup(value); - (*attrs)[i]->mod_values[j+1] = NULL; - } - else - { - result = NSL_ERR_MEMORY; - } - } - } - - return (result); -} /* _addLDAPmodValue */ - - - - -/* - * ***************************************************************************** - * - * Function: _modLDAPmodValue() - * - * Description: Add the given attribute modify operation and its value into - * the LDAPMod array. This will either be a "replace" or a - * "delete"; value = null implies a "delete". - * If this is the first entry in the array then create it. - * - * Parameters: - * Input: LDAPMod ***attrs - array to update - * char *type - attribute to modify - * char *value - attribute value, null implies "delete" - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = added okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_modLDAPmodValue(LDAPMod ***attrs, char *type, char *value) - -{ - int i = 0; - int j = 0; - NSL_RESULT result = NSL_OK; - - /* ---------- */ - - if ((attrs != NULL) && (type != NULL)) - { -#ifdef DEBUG -if (value != NULL) -printf("_modLDAPmodValue() REPLACE type='%s', value='%s'\n", type, value); -else -printf("_modLDAPmodValue() DELETE type='%s'\n", type); -#endif - /* search the existing LDAPMod array for the attribute */ - - for (i = 0; *attrs != NULL && (*attrs)[i] != NULL; i++) - { - if (strcasecmp((*attrs)[i]->mod_type, type) == 0) - { - break; - } - } - - if (*attrs == NULL) - { - /* array empty so create it */ - - *attrs = (LDAPMod **)calloc(1, 2 * sizeof (LDAPMod *)); - if (*attrs != NULL) - { - i = 0; - } - else - { - result = NSL_ERR_MEMORY; - } - - } - else - if ((*attrs)[i] == NULL) - { - /* attribute not found in array so add slot for it */ - - *attrs = (LDAPMod **) - realloc(*attrs, (i+2) * sizeof (LDAPMod *)); - if (*attrs == NULL) - { - result = NSL_ERR_MEMORY; - } - } - } - else - { - result = NSL_ERR_INTERNAL; - } - - if (result == NSL_OK) - { - if ((*attrs)[i] == NULL) - { - /* We've got a new slot. Create the new mod entry */ - - (*attrs)[i] = (LDAPMod *) malloc(sizeof (LDAPMod)); - if (((*attrs)[i] != NULL) && (value != NULL)) - { - /* Do an attribute replace */ - - (*attrs)[i]->mod_op = LDAP_MOD_REPLACE; - (*attrs)[i]->mod_type = strdup(type); - (*attrs)[i]->mod_values = (char **) - malloc(2 * sizeof (char *)); - if ((*attrs)[i]->mod_values != NULL) - { - (*attrs)[i]->mod_values[0] = - strdup(value); - (*attrs)[i]->mod_values[1] = NULL; - (*attrs)[i+1] = NULL; - } - else - { - result = NSL_ERR_MEMORY; - } - } - else - if ((*attrs)[i] != NULL) - { - /* value is null so do an attribute delete */ - - (*attrs)[i]->mod_op = LDAP_MOD_DELETE; - (*attrs)[i]->mod_type = strdup(type); - (*attrs)[i]->mod_values = NULL; - (*attrs)[i+1] = NULL; - } - else - { - result = NSL_ERR_MEMORY; /* malloc failed */ - } - } - - else - { - /* Found an existing entry so add value to it */ - - if (value != NULL) - { - /* add value to attribute's replace list */ - - if ((*attrs)[i]->mod_op == LDAP_MOD_REPLACE) - { - for (j = 0; - (*attrs)[i]->mod_values[j] != NULL; j++); - - (*attrs)[i]->mod_values = - (char **)realloc((*attrs)[i]->mod_values, - (j + 2) * sizeof (char *)); - if ((*attrs)[i]->mod_values != NULL) - { - (*attrs)[i]->mod_values[j] = - strdup(value); - (*attrs)[i]->mod_values[j+1] = NULL; - } - else - { - result = NSL_ERR_MEMORY; - } - } - else - { - /* Delete and replace not allowed */ - result = NSL_ERR_MULTIOP; - } - } - - else - { - /* - * attribute delete - so free any existing - * entries in the value array - */ - - (*attrs)[i]->mod_op = LDAP_MOD_DELETE; - - if ((*attrs)[i]->mod_values != NULL) - { - for (j = 0; - (*attrs)[i]->mod_values[j] != NULL; - j++) - { - free((*attrs)[i]->mod_values[j]); - } - - free((*attrs)[i]->mod_values); - (*attrs)[i]->mod_values = NULL; - } - } - } - } - - return (result); -} /* _modLDAPmodValue */ - - - - - -/* - * ***************************************************************************** - * - * Function: _constructAddLDAPMod() - * - * Description: For the given attribute list construct an - * LDAPMod array for the printer object to be added. Default - * attribute values are included. - * - * Parameters: - * Input: - * uchar_t *printerName - Name of printer to be added - * char **attrList - user specified attribute values list - * Output: LDAPMod ***attrs - pointer to the constructed array - * - * Returns: NSL_RESULT - NSL_OK = constructed okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_constructAddLDAPMod(uchar_t *printerName, char **attrList, LDAPMod ***attrs) - -{ - NSL_RESULT result = NSL_ERROR; - int len = 0; - char **p = NULL; - char *value = NULL; - char *attr = NULL; - - /* ---------- */ - - if ((printerName != NULL) && - ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL)) - { - *attrs = NULL; - - /* - * setup printer object attribute values in an LDAPMod structure - */ - result = _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_TOP); - if (result == NSL_OK) - { - /* Structural Objectclass */ - result = - _addLDAPmodValue(attrs, ATTR_OCLASS, OCV_PSERVICE); - } - if (result == NSL_OK) - { - result = _addLDAPmodValue(attrs, - ATTR_OCLASS, OCV_PABSTRACT); - } - if (result == NSL_OK) - { - result = _addLDAPmodValue(attrs, - ATTR_OCLASS, OCV_SUNPRT); - } - if (result == NSL_OK) - { - result = _addLDAPmodValue(attrs, - ATTR_PNAME, (char *)printerName); - } - - /* - * Now work through the user supplied attribute - * values list and add them into the LDAPMod array - */ - - for (p = attrList; - (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) - { - /* get length of this key word */ - - for (len = 0; - ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); - - if ((strlen(*p) > len+1)) - { - attr = strdup(*p); - attr[len] = '\0'; - value = strdup(&attr[len+1]); - - /* handle specific Key Value Pairs (KVP) */ - - if (strcasecmp(attr, NS_KEY_BSDADDR) == 0) - { - /* use LDAP attribute name */ - free(attr); - attr = strdup(ATTR_BSDADDR); - } - else - if (_attrInLDAPList(attr) == 0) - { - /* - * Non-LDAP attribute so use LDAP - * KVP attribute and the given KVP - * as the value, ie. - * sun-printer-kvp=description=printer - */ - free(attr); - attr = strdup(ATTR_KVP); - value = strdup(*p); - } - - /* add it into the LDAPMod array */ - - result = _addLDAPmodValue(attrs, attr, value); - - free(attr); - free(value); - } - } /* for */ - - if ((result != NSL_OK) && (*attrs != NULL)) - { - (void) ldap_mods_free(*attrs, 1); - attrs = NULL; - } - } - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _constructAddLDAPMod */ - - - - - - - -/* - * ***************************************************************************** - * - * Function: _constructModLDAPMod() - * - * Description: For the given modify attribute list, construct an - * LDAPMod array for the printer object to be modified - * - * Parameters: - * Input: uchar_t *printerName - name of printer to be modified - * int sunPrinter - Boolean; object is a sunPrinter - * char **attrList - user specified attribute values list - * char ***oldKVPList - current list of KVP values on object - * Output: LDAPMod ***attrs - pointer to the constructed array - * - * Returns: NSL_RESULT - NSL_OK = constructed okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_constructModLDAPMod(uchar_t *printerName, int sunPrinter, char **attrList, - char ***oldKVPList, LDAPMod ***attrs) - -{ - NSL_RESULT result = NSL_OK; - int len = 0; - int kvpUpdated = 0; - int kvpExists = 0; - char **p = NULL; - char *value = NULL; - char *attr = NULL; - - /* ---------- */ - - if ((printerName != NULL) && - ((attrList != NULL) && (attrList[0] != NULL)) && (attrs != NULL)) - { - *attrs = NULL; - - if ((oldKVPList != NULL) && (*oldKVPList != NULL)) - { - kvpExists = 1; - } - - if (!sunPrinter) - { - /* - * The object was previously not a sunPrinter, so - * add the required objectclass attribute value, and - * ensure it has the printername attribute. - */ - result = _addLDAPmodValue(attrs, - ATTR_OCLASS, OCV_SUNPRT); - if (result == NSL_OK) - { - result = _modLDAPmodValue(attrs, - ATTR_PNAME, (char *)printerName); - } - } - - /* - * work through the user supplied attribute - * values list and add them into the LDAPMod array depending - * on if they are a replace or delete attribute operation, - * a "null value" means delete. - */ - - for (p = attrList; - (p != NULL) && (*p != NULL) && (result == NSL_OK); p++) - { - /* get length of this key word */ - - for (len = 0; - ((*p)[len] != '=') && ((*p)[len] != '\0'); len++); - - if ((strlen(*p) > len+1)) - { - attr = strdup(*p); - attr[len] = '\0'; - value = strdup(&attr[len+1]); - - /* handle specific Key Value Pairs (KVP) */ - - if ((_attrInLDAPList(attr) == 0) && - (strcasecmp(attr, NS_KEY_BSDADDR) != 0)) - { - /* - * Non-LDAP attribute so use LDAP - * KVP attribute and the given KVP as - * the value, ie. - * sun-printer-kvp=description=printer - */ - result = _modAttrKVP(*p, oldKVPList); - kvpUpdated = 1; - } - - else - { - if (strcasecmp(attr, NS_KEY_BSDADDR) == - 0) - { - /* - * use LDAP bsdaddr attribute - * name - */ - free(attr); - attr = strdup(ATTR_BSDADDR); - } - - /* - * else - * use the supplied attribute name - */ - - /* add it into the LDAPMod array */ - - result = _modLDAPmodValue(attrs, - attr, value); - } - - free(attr); - free(value); - } - - else - if (strlen(*p) >= 1) - { - /* handle attribute DELETE request */ - - attr = strdup(*p); - if (attr[len] == '=') - { - /* terminate "attribute=" */ - attr[len] = '\0'; - } - - /* handle specific Key Value Pairs (KVP) */ - - if (strcasecmp(attr, NS_KEY_BSDADDR) == 0) - { - /* use LDAP bsdaddr attribute name */ - result = _modLDAPmodValue(attrs, - ATTR_BSDADDR, NULL); - } - else - if (_attrInLDAPList(attr) == 0) - { - /* - * Non-LDAP kvp, so sort items - * in the kvp list - */ - result = _modAttrKVP(*p, oldKVPList); - kvpUpdated = 1; - } - else - { - result = _modLDAPmodValue(attrs, - attr, NULL); - } - - free(attr); - } - } /* for */ - - if ((result == NSL_OK) && (kvpUpdated)) - { - result = _attrAddKVP(attrs, *oldKVPList, kvpExists); - } - - if ((result != NSL_OK) && (*attrs != NULL)) - { - (void) ldap_mods_free(*attrs, 1); - *attrs = NULL; - } - } - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _constructModLDAPMod */ - - - - - - -/* - * ***************************************************************************** - * - * Function: _compareURIinDNs() - * - * Description: For the 2 given printer object DNs compare the naming part - * part of the DN (printer-uri) to see if they are the same. - * - * Note: This function only returns "compare failed" if their URI don't - * compare. Problems with the dn etc., return a good compare - * because I don't want us to create a new object for these - * - * Parameters: - * Input: uchar_t *dn1 - * uchar_t *dn2 - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = URIs are the same - * - * ***************************************************************************** - */ - -static NSL_RESULT -_compareURIinDNs(uchar_t *dn1, uchar_t *dn2) - -{ - NSL_RESULT result = NSL_OK; - uchar_t *DN1 = NULL; - uchar_t *DN2 = NULL; - char *p1 = NULL; - char *p2 = NULL; - - /* --------- */ - - if ((dn1 != NULL) && (dn2 != NULL)) - { - DN1 = (uchar_t *)strdup((char *)dn1); - DN2 = (uchar_t *)strdup((char *)dn2); - - /* terminate each string after the printer-uri */ - - p1 = strstr((char *)DN1, PCONTAINER); - /* move back to the comma */ - while ((p1 != NULL) && (*p1 != ',') && (p1 >= (char *)DN1)) - { - p1--; - } - - p2 = strstr((char *)DN2, PCONTAINER); - /* move back to the comma */ - while ((p2 != NULL) && (*p2 != ',') && (p2 >= (char *)DN2)) - { - p2--; - } - - if ((*p1 == ',') && (*p2 == ',')) - { - *p1 = '\0'; /* re-terminate it */ - *p2 = '\0'; /* re-terminate it */ - - /* do the compare */ - - /* - * Note: SHOULD really normalise the 2 DNs before - * doing the compare - */ -#ifdef DEBUG -printf("_compareURIinDNs() @1 (%s) (%s)\n", DN1, DN2); -#endif - if (strcasecmp((char *)DN1, (char *)DN2) != 0) - { - result = NSL_ERROR; - } - - } - - free(DN1); - free(DN2); - } - - return (result); -} /* _compareURIinDNs */ - - - - - - - -/* - * ***************************************************************************** - * - * Function: _getThisNSDomainDN() - * - * Description: Get the current Name Service Domain DN - * This is extracted from the result of executing ldaplist. - * - * Note: Do it this way until the NS LDAP library interface is - * made public. - * - * Parameters: - * Input: None - * Output: None - * - * Returns: uchar_t* - pointer to NS Domain DN (The caller should free this - * returned memory). - * - * ***************************************************************************** - */ - -#define LDAPLIST_D "/usr/bin/ldaplist -d 2>&1" -#define DNID "dn: " - -static uchar_t * -_getThisNSDomainDN(void) - -{ - uchar_t *domainDN = NULL; - char *cp = NULL; - char buf[BUFSIZ] = ""; - - /* --------- */ - - if (_popen(LDAPLIST_D, buf, sizeof (buf)) == 0) - { - if ((cp = strstr(buf, DNID)) != NULL) - { - cp += strlen(DNID); /* increment past "dn: " label */ - domainDN = (uchar_t *)strdup(cp); - - if ((cp = strchr((char *)domainDN, '\n')) != NULL) - { - *cp = '\0'; /* terminate it */ - } - } - } - - return (domainDN); -} /* _getThisNSDomainDN */ - - - - - -/* - * ***************************************************************************** - * - * Function: _popen() - * - * Description: General popen function. The caller should always use a full - * path cmd. - * - * Parameters: - * Input: char *cmd - command line to execute - * char *buffer - ptr to buffer to put result in - * int size - size of result buffer - * Output: None - * - * Returns: int - 0 = opened okay - * - * ***************************************************************************** - */ - -static int -_popen(char *cmd, char *buffer, int size) - -{ - int result = -1; - int rsize = 0; - FILE *fptr; - char safe_cmd[BUFSIZ]; - char linebuf[BUFSIZ]; - - /* -------- */ - - if ((cmd != NULL) && (buffer != NULL) && (size != 0)) - { - (void) strcpy(buffer, ""); - (void) strcpy(linebuf, ""); - (void) snprintf(safe_cmd, BUFSIZ, "IFS=' \t'; %s", cmd); - - if ((fptr = popen(safe_cmd, "r")) != NULL) - { - while ((fgets(linebuf, BUFSIZ, fptr) != NULL) && - (rsize < size)) - { - rsize = strlcat(buffer, linebuf, size); - if (rsize >= size) - { - /* result is too long */ - (void) memset(buffer, '\0', size); - } - } - - if (strlen(buffer) > 0) - { - result = 0; - } - - (void) pclose(fptr); - } - } - - return (result); -} /* popen */ - - -/* - * ***************************************************************************** - * - * Function: _attrInList() - * - * Description: For the given list check if the attribute is it - * - * Parameters: - * Input: char *attr - attribute to check - * char **list - list of attributes to check against - * Output: None - * - * Returns: int - TRUE = attr found in list - * - * ***************************************************************************** - */ - -static int -_attrInList(char *attr, const char **list) - -{ - int result = 0; - int j; - - /* ------- */ - - if ((attr != NULL) && (list != NULL)) - { - for (j = 0; (list[j] != NULL) && (result != 1); j++) - { - if (strcasecmp(list[j], attr) == 0) - { - result = 1; /* found */ - } - } - } - - return (result); -} /* _attrInList */ - - - - -/* - * ***************************************************************************** - * - * Function: _attrInLDAPList() - * - * Description: Checks to see if the given attribute is an LDAP printing - * attribute, ie. is either in an IPP objectclass or the - * sun printer objectclass. Note: some attributes are handled - * specifically outside this function, so are excluded from - * the lists that are checked. - * - * Parameters: - * Input: char *attr - attribute to check - * Output: None - * - * Returns: int - TRUE = attr found in list - * - * ***************************************************************************** - */ - -static int -_attrInLDAPList(char *attr) - -{ - int result = 0; - - /* ------- */ - - if (_attrInList(attr, nsl_attr_printerService)) - { - result = 1; /* in list */ - } - else - if (_attrInList(attr, nsl_attr_printerIPP)) - { - result = 1; /* in list */ - } - else - if (_attrInList(attr, nsl_attr_sunPrinter)) - { - result = 1; /* in list */ - } - - return (result); -} /* _attrInLDAPList */ - - - - -/* - * ***************************************************************************** - * - * Function: _getCurrentKVPValues() - * - * Description: For the given printer object read the current set of values - * the object has for the sun-printer-kvp (Key Value pair) - * - * Parameters: - * Input: LDAP *ld - existing ldap connection descriptor - * char *objectDN - DN to search for - * Output: char ***list - returned set of kvp values - * - * Result: NSL_RESULT - NSL_OK = object exists - * - * ***************************************************************************** - */ - -static NSL_RESULT -_getCurrentKVPValues(LDAP *ld, uchar_t *objectDN, char ***list) - -{ - NSL_RESULT result = NSL_ERR_UNKNOWN_PRINTER; - int sresult = LDAP_NO_SUCH_OBJECT; - int i = 0; - LDAPMessage *ldapMsg; - char *requiredAttrs[2] = { ATTR_KVP, NULL }; - LDAPMessage *ldapEntry = NULL; - char *entryAttrib = NULL; - char **attribValues = NULL; - BerElement *berElement = NULL; - - /* ---------- */ - - if ((list != NULL) && (ld != NULL) && (objectDN != NULL)) - { - /* search for this Printer in the directory */ - - sresult = ldap_search_s(ld, (char *)objectDN, LDAP_SCOPE_BASE, - "(objectclass=*)", requiredAttrs, 0, &ldapMsg); - if (sresult == LDAP_SUCCESS) - { - /* - * check that the object exists and extract its - * KVP attribute values - */ - ldapEntry = ldap_first_entry(ld, ldapMsg); - if (ldapEntry != NULL) - { - entryAttrib = ldap_first_attribute(ld, - ldapEntry, &berElement); - if ((entryAttrib != NULL) && - (strcasecmp(entryAttrib, ATTR_KVP) == 0)) - - { -#ifdef DEBUG -printf("Attribute: %s, its values are:\n", entryAttrib); -#endif - /* - * add each KVP value to the list - * that we will return - */ - attribValues = ldap_get_values( - ld, ldapEntry, entryAttrib); - for (i = 0; - attribValues[i] != NULL; i++) - { - *list = (char **) - list_append((void **)*list, - strdup(attribValues[i])); -#ifdef DEBUG -printf("\t%s\n", attribValues[i]); -#endif - } - (void) ldap_value_free(attribValues); - } - - if ((entryAttrib != NULL) && - (berElement != NULL)) - { - ber_free(berElement, 0); - } - - - /* object found */ - result = NSL_OK; - } - - (void) ldap_msgfree(ldapMsg); - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _getCurrentKVPValues */ - - - -/* - * ***************************************************************************** - * - * Function: _freeList() - * - * Description: Free the list created by list_append() where the items in - * the list have been strdup'ed. - * - * Parameters: - * Input: char ***list - returned set of kvp values - * - * Result: void - * - * ***************************************************************************** - */ - -static void -_freeList(char ***list) - -{ - int i = 0; - - /* ------ */ - - if (list != NULL) - { - if (*list != NULL) - { - for (i = 0; (*list)[i] != NULL; i++) - { - free((*list)[i]); - } - free(*list); - } - - *list = NULL; - } -} /* _freeList */ - - - -/* - * ***************************************************************************** - * - * Function: _modAttrKVP() - * - * Description: Sort out the KVP attribute value list, such that this new - * value takes precidence over any existing value in the list. - * The current list is updated to remove this key, and the new - * key "value" is added to the list, eg. for - * value: bbb=ddddd - * and kvpList: - * aaa=yyyy - * bbb=zzzz - * ccc=xxxx - * the resulting kvpList is: - * aaa=yyyy - * ccc=xxxx - * bbb=ddddd - * - * Note: When all new values have been handled the function _attrAddKVP() - * must be called to add the "new list" values into the - * LDAPMod array. - * - * Parameters: - * Input: char *value - Key Value Pair to process, - * eg. aaaaa=hhhhh, where aaaaa is the key - * char ***kvpList - list of current KVP values - * Output: char ***kvpList - updated list of KVP values - * - * Returns: NSL_RESULT - NSL_OK = done okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_modAttrKVP(char *value, char ***kvpList) - -{ - NSL_RESULT result = NSL_ERR_INTERNAL; - int i = 0; - int inList = 0; - int keyDelete = 0; - char *key = NULL; - char **p = NULL; - char **newList = NULL; - - /* ------- */ - - if ((value != NULL) && (kvpList != NULL)) - { - result = NSL_OK; - - /* extract "key" from value */ - - key = strdup(value); - - for (i = 0; ((key)[i] != '=') && ((key)[i] != '\0'); i++); - key[i] = '\0'; /* terminate the key */ - - /* Is this a request to delete a "key" value */ - - if ((value[i] == '\0') || (value[i+1] == '\0')) - { - /* this is a request to delete the key */ - keyDelete = 1; - } - - if ((*kvpList != NULL) && (**kvpList != NULL)) - { - /* - * for each item in the list remove it if the keys match - */ - for (p = *kvpList; *p != NULL; p++) - { - for (i = 0; - ((*p)[i] != '=') && ((*p)[i] != '\0'); i++); - - if ((strlen(key) == i) && - (strncasecmp(*p, key, i) == 0)) - { - inList = 1; - } - else - { - /* no match so add value to new list */ - newList = (char **)list_append( - (void **)newList, - strdup(*p)); - } - } - } - - /* - * if it was not a DELETE request add the new key value into - * the newList, otherwise we have already removed the key - */ - - if (!keyDelete) - { - newList = (char **)list_append((void **)newList, - strdup(value)); - } - - if ((newList != NULL) || (inList)) - { - /* replace old list with the newList */ - _freeList(kvpList); - *kvpList = newList; - } - - free(key); - } - - return (result); -} /* modAttrKVP */ - - - - -/* - * ***************************************************************************** - * - * Function: _attrAddKVP() - * - * Description: Process KVP items in the kvpList adding them to the - * LDAPMod modify array. If the list is empty but there were - * previously LDAP KVP values delete them. - * - * Note: This function should only be called when all the new KVP - * items have been processed by _modAttrKVP() - * - * Parameters: - * Input: LDAPMod ***attrs - array to update - * char **kvpList - list KVP values - * int kvpExists - object currently has LDAP KVP values - * Output: None - * - * Returns: NSL_RESULT - NSL_OK = done okay - * - * ***************************************************************************** - */ - -static NSL_RESULT -_attrAddKVP(LDAPMod ***attrs, char **kvpList, int kvpExists) - -{ - NSL_RESULT result = NSL_OK; - - /* ------- */ - - if (attrs != NULL) - { - if (kvpList != NULL) - { - while ((kvpList != NULL) && (*kvpList != NULL)) - { - /* add item to LDAPMod array */ - - result = - _modLDAPmodValue(attrs, ATTR_KVP, *kvpList); - - kvpList++; - } - } - else - if (kvpExists) - { - /* - * We now have no LDAP KVP values but there were - * some previously, so delete them - */ - result = _modLDAPmodValue(attrs, ATTR_KVP, NULL); - } - } - - else - { - result = NSL_ERR_INTERNAL; - } - - return (result); -} /* _attrAddKVP */ - - - - -/* - * ***************************************************************************** - * - * Function: _manageReferralCredentials() - * - * Description: This function is called if a referral request is returned by - * the origonal LDAP server during the ldap update request call, - * eg. ldap_add_s(), ldap_modify_s() or ldap_delete_s(). - * Parameters: - * Input: LDAP *ld - LDAP descriptor - * int freeit - 0 = first call to get details - * - 1 = second call to free details - * - -1 = initial store of authentication details - * Input/Output: char **dn - returns DN to bind to on master - * char **credp - returns password for DN - * int *methodp - returns authentication type, eg. simple - * - * Returns: int - 0 = okay - * - * ***************************************************************************** - */ -static int _manageReferralCredentials(LDAP *ld, char **dn, char **credp, - int *methodp, int freeit) - -{ - int result = 0; - static char *sDN = NULL; - static char *sPasswd = NULL; - static int sMethod = LDAP_AUTH_SIMPLE; - - /* -------- */ - - if (freeit == 1) - { - /* second call - free memory */ - - if ((dn != NULL) && (*dn != NULL)) - { - free(*dn); - } - - if ((credp != NULL) && (*credp != NULL)) - { - free(*credp); - } - } - - else - if ((ld != NULL) && - (dn != NULL) && (credp != NULL) && (methodp != NULL)) - { - if ((freeit == 0) && (sDN != NULL) && (sPasswd != NULL)) - { - /* first call - get the saved bind credentials */ - - *dn = strdup(sDN); - *credp = strdup(sPasswd); - *methodp = sMethod; - } - else - if (freeit == -1) - { - /* initial call - save the saved bind credentials */ - - sDN = *dn; - sPasswd = *credp; - sMethod = *methodp; - } - else - { - result = 1; /* error */ - } - } - else - { - result = 1; /* error */ - } - - return (result); -} /* _manageReferralCredentials */ diff --git a/usr/src/lib/print/libprint/common/nss_printer.c b/usr/src/lib/print/libprint/common/nss_printer.c deleted file mode 100644 index 149ddadd5c..0000000000 --- a/usr/src/lib/print/libprint/common/nss_printer.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <sys/types.h> -#include <nss_dbdefs.h> -#include <syslog.h> -#include <ns.h> - -#ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ -#define NSS_DBNAM__PRINTERS "_printers" -#endif - -static DEFINE_NSS_DB_ROOT(db_root); -static DEFINE_NSS_GETENT(context); - -static int printers_stayopen; -static char *private_ns = NULL; - -static void -_nss_initf_printers(p) - nss_db_params_t *p; -{ - if (private_ns != NULL) { - /* - * because we need to support a legacy interface that allows - * us to select a specific name service, we need to dummy up - * the parameters to use a private nsswitch database and set - * the * default_config entry to the name service we are - * looking into. - */ - p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ - p->default_config = normalize_ns_name(private_ns); - } else { - /* regular behaviour */ - p->name = NSS_DBNAM_PRINTERS; /* "printers" */ - p->default_config = NSS_DEFCONF_PRINTERS; - } - syslog(LOG_DEBUG, "database: %s, default: %s", - (p->name ? p->name : "NULL"), - (p->default_config ? p->default_config : "NULL")); -} - -/* - * Return values: 0 = success, 1 = parse error, 2 = erange ... - * The structure pointer passed in is a structure in the caller's space - * wherein the field pointers would be set to areas in the buffer if - * need be. instring and buffer should be separate areas. - */ -/* ARGSUSED */ -static int -str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) -{ - if (lenstr + 1 > buflen) - return (NSS_STR_PARSE_ERANGE); - - /* skip entries that begin with '#' */ - if (instr[0] == '#') - return (NSS_STR_PARSE_PARSE); - - /* - * We copy the input string into the output buffer - */ - (void) memcpy(buffer, instr, lenstr); - buffer[lenstr] = '\0'; - - return (NSS_STR_PARSE_SUCCESS); -} - - -int -setprinterentry(int stayopen, char *ns) -{ - printers_stayopen |= stayopen; - private_ns = ns; - nss_setent(&db_root, _nss_initf_printers, &context); - private_ns = NULL; - return (0); -} - - -int -endprinterentry() -{ - printers_stayopen = 0; - nss_endent(&db_root, _nss_initf_printers, &context); - nss_delete(&db_root); - private_ns = NULL; - return (0); -} - - -/* ARGSUSED2 */ -int -getprinterentry(char *linebuf, int linelen, char *ns) -{ - nss_XbyY_args_t arg; - nss_status_t res; - - private_ns = ns; - NSS_XbyY_INIT(&arg, linebuf, linebuf, linelen, str2printer); - res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); - (void) NSS_XbyY_FINI(&arg); - private_ns = NULL; - - return (arg.status = res); -} - - -int -getprinterbyname(char *name, char *linebuf, int linelen, char *ns) -{ - nss_XbyY_args_t arg; - nss_status_t res; - - private_ns = ns; - NSS_XbyY_INIT(&arg, linebuf, linebuf, linelen, str2printer); - arg.key.name = name; - res = nss_search(&db_root, _nss_initf_printers, - NSS_DBOP_PRINTERS_BYNAME, &arg); - (void) NSS_XbyY_FINI(&arg); - private_ns = NULL; - - return (arg.status = res); -} diff --git a/usr/src/lib/print/libprint/common/nss_write.c b/usr/src/lib/print/libprint/common/nss_write.c deleted file mode 100644 index c617f0d0a5..0000000000 --- a/usr/src/lib/print/libprint/common/nss_write.c +++ /dev/null @@ -1,325 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <stdarg.h> -#include <fcntl.h> -#include <syslog.h> -#include <errno.h> -#include <pwd.h> -#include <libintl.h> -#include <netdb.h> /* for rcmd() */ - -#include <ns.h> -#include <list.h> - -/* escaped chars include delimiters and shell meta characters */ -#define ESCAPE_CHARS "\\\n=: `&;|>^$()<*?[" - -/* - * This modules contains all of the code nedessary to write back to each - * printing configuration data repository. The support is intended to - * introduce the least number of dependencies in the library, so it doesn't - * always perform it's operations in the cleanest fashion. - */ - - -/* - * Generic Files support begins here. - */ -static char * -freadline(FILE *fp, char *buf, int buflen) -{ - char *s = buf; - - while (fgets(s, buflen, fp)) { - if ((s == buf) && ((*s == '#') || (*s == '\n'))) { - continue; - } else { - if ((*s == '#') || (*s == '\n')) { - *s = NULL; - break; - } - - buflen -= strlen(s); - s += strlen(s); - - if (*(s - 2) != '\\') - break; -#ifdef STRIP_CONTINUATION - buflen -= 2; - s -= 2; -#endif - } - } - - if (s == buf) - return (NULL); - else - return (buf); -} - - -static int -_file_put_printer(const char *file, const ns_printer_t *printer) -{ - FILE *ifp, - *ofp; - char *tmpfile; - int fd; - int exit_status = 0; - int size; - - size = strlen(file) + 1 + 20; - if ((tmpfile = malloc(size)) == NULL) - return (-1); - - if (snprintf(tmpfile, size, "%sXXXXXX", file) >= size) { - syslog(LOG_ERR, "_file_put_printer:buffer overflow:tmpfile"); - return (-1); - } - - /* LINTED */ - while (1) { /* syncronize writes */ - fd = open(file, O_RDWR|O_CREAT|O_EXCL, 0644); - if ((fd < 0) && (errno == EEXIST)) - fd = open(file, O_RDWR); - if (fd < 0) { - if (errno == EAGAIN) - continue; - free(tmpfile); - return (-1); - } - if (lockf(fd, F_TLOCK, 0) == 0) - break; - (void) close(fd); - } - - if ((ifp = fdopen(fd, "r")) == NULL) { - (void) close(fd); - free(tmpfile); - return (-1); - } - - if ((fd = mkstemp(tmpfile)) < 0) { - (void) fclose(ifp); - free(tmpfile); - return (-1); - } - - (void) fchmod(fd, 0644); - if ((ofp = fdopen(fd, "wb+")) != NULL) { - char buf[4096]; - - (void) fprintf(ofp, - "#\n#\tIf you hand edit this file, comments and structure may change.\n" - "#\tThe preferred method of modifying this file is through the use of\n" - "#\tlpset(1M)\n#\n"); - - /* - * Handle the special case of lpset -x all - * This deletes all entries in the file - * In this case, just don't write any entries to the tmpfile - */ - - if (!((strcmp(printer->name, "all") == 0) && - (printer->attributes == NULL))) { - char *t, *entry, *pentry; - - (void) _cvt_printer_to_entry((ns_printer_t *)printer, - buf, sizeof (buf)); - t = pentry = strdup(buf); - - while (freadline(ifp, buf, sizeof (buf)) != NULL) { - ns_printer_t *tmp = (ns_printer_t *) - _cvt_nss_entry_to_printer(buf, ""); - - if (ns_printer_match_name(tmp, printer->name) - == 0) { - entry = pentry; - pentry = NULL; - } else - entry = buf; - - (void) fprintf(ofp, "%s\n", entry); - } - - if (pentry != NULL) - (void) fprintf(ofp, "%s\n", pentry); - free(t); - } - - (void) fclose(ofp); - (void) rename(tmpfile, file); - } else { - (void) close(fd); - (void) unlink(tmpfile); - exit_status = -1; - } - - (void) fclose(ifp); /* releases the lock, after rename on purpose */ - (void) free(tmpfile); - return (exit_status); -} - - -/* - * Support for writing a printer into the FILES /etc/printers.conf - * file. - */ -int -files_put_printer(const ns_printer_t *printer) -{ - static char *file = "/etc/printers.conf"; - - return (_file_put_printer(file, printer)); -} - -/* - * Support for writing a printer into the NIS printers.conf.byname - * map. - */ - -#include <rpc/rpc.h> -#include <rpcsvc/ypclnt.h> -#include <rpcsvc/yp_prot.h> - -/* - * Run the remote command. We aren't interested in any io, Only the - * return code. - */ -static int -remote_command(char *command, char *host) -{ - struct passwd *pw; - - if ((pw = getpwuid(getuid())) != NULL) { - int fd; - - if ((fd = rcmd_af(&host, htons(514), pw->pw_name, "root", - command, NULL, AF_INET6)) < 0) - return (-1); - (void) close(fd); - return (0); - } else - return (-1); -} - - -/* - * This isn't all that pretty, but you can update NIS if the machine this - * runs on is in the /.rhosts or /etc/hosts.equiv on the NIS master. - * copy it local, update it, copy it remote - */ -#define TMP_PRINTERS_FILE "/tmp/printers.NIS" -#define NIS_MAKEFILE "/var/yp/Makefile" -#define MAKE_EXCERPT "/usr/lib/print/Makefile.yp" -/*ARGSUSED*/ -int -nis_put_printer(const ns_printer_t *printer) -{ - static char *domain = NULL; - char *map = "printers.conf.byname"; - char *tmp = NULL; - char *host = NULL; - char lfile[BUFSIZ]; - char rfile[BUFSIZ]; - char cmd[BUFSIZ]; - - if (domain == NULL) - (void) yp_get_default_domain(&domain); - - if ((yp_master(domain, (char *)map, &host) != 0) && - (yp_master(domain, "passwd.byname", &host) != 0)) - return (-1); - - if (snprintf(lfile, sizeof (lfile), "/tmp/%s", map) >= - sizeof (lfile)) { - syslog(LOG_ERR, "nis_put_printer:lfile buffer overflow"); - return (-1); - } - if (snprintf(rfile, sizeof (rfile), "root@%s:/etc/%s", host, map) >= - sizeof (rfile)) { - syslog(LOG_ERR, "nis_put_printer:rfile buffer overflow"); - return (-1); - } - - if (((tmp = strrchr(rfile, '.')) != NULL) && - (strcmp(tmp, ".byname") == 0)) - *tmp = NULL; /* strip the .byname */ - - /* copy it local */ - if (snprintf(cmd, sizeof (cmd), "rcp %s %s >/dev/null 2>&1", - rfile, lfile) >= sizeof (cmd)) { - syslog(LOG_ERR, - "nis_put_printer:buffer overflow building cmd"); - return (-1); - } - (void) system(cmd); /* could fail because it doesn't exist */ - - - /* update it */ - if (_file_put_printer(lfile, printer) != 0) - return (-1); - - /* copy it back */ - if (snprintf(cmd, sizeof (cmd), "rcp %s %s >/dev/null 2>&1", - lfile, rfile) >= sizeof (cmd)) { - syslog(LOG_ERR, - "nis_put_printer:buffer overflow building cmd"); - return (-1); - } - if (system(cmd) != 0) - return (-1); - - /* copy the Makefile excerpt */ - if (snprintf(cmd, sizeof (cmd), - "rcp %s root@%s:%s.print >/dev/null 2>&1", - MAKE_EXCERPT, host, NIS_MAKEFILE) >= sizeof (cmd)) { - syslog(LOG_ERR, - "nis_put_printer:buffer overflow building cmd"); - return (-1); - } - - if (system(cmd) != 0) - return (-1); - - /* run the make */ - if (snprintf(cmd, sizeof (cmd), - "/bin/sh -c 'PATH=/usr/ccs/bin:/bin:/usr/bin:$PATH " - "make -f %s -f %s.print printers.conf >/dev/null 2>&1'", - NIS_MAKEFILE, NIS_MAKEFILE) >= sizeof (cmd)) { - syslog(LOG_ERR, - "nis_put_printer:buffer overflow on make"); - return (-1); - } - - return (remote_command(cmd, host)); -} diff --git a/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt deleted file mode 100644 index 0cac14ae95..0000000000 --- a/usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt +++ /dev/null @@ -1,64 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2001 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -# IPP Draft 4 schema and Sun Printer Schema - -attribute printer-uri 1.3.18.0.2.4.1140 cis single -attribute printer-xri-supported 1.3.18.0.2.4.1107 cis -attribute printer-name 1.3.18.0.2.4.1135 cis single -attribute printer-natural-language-configured 1.3.18.0.2.4.1119 cis single -attribute printer-location 1.3.18.0.2.4.1136 cis single -attribute printer-info 1.3.18.0.2.4.1139 cis single -attribute printer-more-info 1.3.18.0.2.4.1134 cis single -attribute printer-make-and-model 1.3.18.0.2.4.1138 cis single -attribute printer-ipp-versions-supported 1.3.18.0.2.4.1133 cis -attribute printer-multiple-document-jobs-supported 1.3.18.0.2.4.1132 bin single -attribute printer-charset-configured 1.3.18.0.2.4.1109 cis single -attribute printer-charset-supported 1.3.18.0.2.4.1131 cis -attribute printer-generated-natural-language-supported 1.3.18.0.2.4.1137 cis -attribute printer-document-format-supported 1.3.18.0.2.4.1130 cis -attribute printer-color-supported 1.3.18.0.2.4.1129 bin single -attribute printer-compression-supported 1.3.18.0.2.4.1128 cis -attribute printer-pages-per-minute 1.3.18.0.2.4.1127 bin single -attribute printer-pages-per-minute-color 1.3.18.0.2.4.1126 bin single -attribute printer-finishings-supported 1.3.18.0.2.4.1125 cis -attribute printer-number-up-supported 1.3.18.0.2.4.1124 bin -attribute printer-sides-supported 1.3.18.0.2.4.1123 cis -attribute printer-media-supported 1.3.18.0.2.4.1122 cis -attribute printer-media-local-supported 1.3.18.0.2.4.1117 cis -attribute printer-resolution-supported 1.3.18.0.2.4.1121 cis -attribute printer-print-quality-supported 1.3.18.0.2.4.1120 cis -attribute printer-job-priority-supported 1.3.18.0.2.4.1110 bin single -attribute printer-copies-supported 1.3.18.0.2.4.1118 bin single -attribute printer-job-k-octets-supported 1.3.18.0.2.4.1111 bin single -attribute printer-current-operator 1.3.18.0.2.4.1112 cis single -attribute printer-service-person 1.3.18.0.2.4.1113 cis single -attribute printer-delivery-orientation-supported 1.3.18.0.2.4.1114 cis -attribute printer-stacking-order-supported 1.3.18.0.2.4.1115 cis -attribute printer-output-features-supported 1.3.18.0.2.4.1116 cis -attribute printer-aliases 1.3.18.0.2.4.1108 cis -attribute sun-printer-bsdaddr 1.3.6.1.4.1.42.2.27.5.1.63 cis single -attribute sun-printer-kvp 1.3.6.1.4.1.42.2.27.5.1.64 cis diff --git a/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt b/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt deleted file mode 100644 index 77f365819d..0000000000 --- a/usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt +++ /dev/null @@ -1,116 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# Copyright 2001 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" - -# IPP Schema Draft 4 and Sun Printer Schema - -objectclass slpService - oid 1.3.18.0.2.6.2549 - superior - top - -objectclass slpServicePrinter - oid 1.3.18.0.2.6.254 - superior - slpService - -objectclass printerAbstract - oid 1.3.18.0.2.6.258 - superior - top - allows - printer-charset-configured, - printer-charset-supported, - printer-color-supported, - printer-compression-supported, - printer-copies-supported, - printer-current-operator, - printer-delivery-orientation-supported, - printer-document-format-supported, - printer-finishings-supported, - printer-generated-natural-language-supported, - printer-info, - printer-job-k-octets-supported, - printer-job-priority-supported, - printer-location, - printer-make-and-model, - printer-media-local-supported, - printer-media-supported, - printer-more-info, - printer-multiple-document-jobs-supported, - printer-name, - printer-natural-language-configured, - printer-number-up-supported, - printer-output-features-supported, - printer-pages-per-minute, - printer-pages-per-minute-color, - printer-print-quality-supported, - printer-resolution-supported, - printer-service-person, - printer-sides-supported, - printer-stacking-order-supported - -objectclass printerService - oid 1.3.18.0.2.6.255 - superior - printerAbstract - allows - printer-uri, - printer-xri-supported - -objectclass printerServiceAuxClass - oid 1.3.18.0.2.6.257 - superior - printerAbstract - allows - printer-uri, - printer-xri-supported - -objectclass printerIPP - oid 1.3.18.0.2.6.256 - superior - top - allows - printer-ipp-versions-supported, - printer-multiple-document-jobs-supported - -objectclass printerLPR - oid 1.3.18.0.2.6.253 - superior - top - requires - printer-name - allows - printer-aliases - -objectclass sunPrinter - oid 1.3.6.1.4.1.42.2.27.5.2.14 - superior - top - requires - printer-name - allows - sun-printer-bsdaddr, - sun-printer-kvp diff --git a/usr/src/lib/print/libprint/i386/Makefile b/usr/src/lib/print/libprint/i386/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libprint/i386/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/libprint/sparc/Makefile b/usr/src/lib/print/libprint/sparc/Makefile deleted file mode 100644 index 3b985583a4..0000000000 --- a/usr/src/lib/print/libprint/sparc/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# ident "%Z%%M% %I% %E% SMI" -# - -include ../Makefile.com - -install: all $(ROOTLIBS) $(ROOTLINKS) # $(ROOTLINT) diff --git a/usr/src/lib/print/mod_ipp/Makefile b/usr/src/lib/print/mod_ipp/Makefile deleted file mode 100644 index 8d6500fb41..0000000000 --- a/usr/src/lib/print/mod_ipp/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -LIBRARY = mod_ipp.a -VERS = -OBJECTS = mod_ipp.o - -include ../../Makefile.lib -include ../../Makefile.rootfs - -APACHEMODDIR = $(ROOT)/usr/apache/libexec -APACHECONFDIR = $(ROOT)/etc/apache -LISTENERDIR = $(ROOT)/var/lp/ipp-listener - -ROOTDIRS = $(ROOT)/usr/apache $(APACHEMODDIR) $(APACHECONFDIR) \ - $(ROOT)/var/lp $(LISTENERDIR) - -$(ROOT)/var/lp:= DIRMODE = 775 -$(ROOT)/var/lp:= FILEMODE = 775 - -LIBS = $(DYNLIB) - -SRCS = $(OBJECTS:%.o = %.c) - - -CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I../libipp-listener/common -CPPFLAGS += -I../libipp-core/common -CPPFLAGS += -I/usr/apache/include -CPPFLAGS += -DEAPI -ZDEFS = $(ZNODEFS) - -MAPFILES = mapfile - -LDLIBS += -lipp-listener -lipp-core -lpapi -lc - -# SMF manifest -MANIFEST= ipp-listener.xml -ROOTMANIFESTDIR= $(ROOT)/lib/svc/manifest/application/print -ROOTMANIFEST= $(MANIFEST:%=$(ROOTMANIFESTDIR)/%) -$(ROOTMANIFEST) := FILEMODE= 444 - -# Apache module -$(APACHEMODDIR)/$(LIBLINKS): $(ROOTDIRS) - -# Apache config -APACHECONFFILE= $(APACHECONFDIR)/httpd-standalone-ipp.conf -$(APACHECONFFILE) := FILEMODE= 644 -LISTENERFILE= $(LISTENERDIR)/index.html -$(LISTENERFILE) := FILEMODE= 444 - -$(ROOT)/var/lp:= FILEMODE = 0775 - -$(APACHEMODDIR)/$(LIBLINKS):= FILEMODE = 0555 - -$(ROOTMANIFESTDIR)/% $(APACHEMODDIR)/% $(APACHECONFDIR)/% $(LISTENERDIR)/%: % - $(INS.file) - -$(ROOTDIRS): - $(INS.dir) - -.KEEP_STATE: - -all: $(LIBS) - -install: all $(APACHEMODDIR)/$(LIBLINKS) $(APACHECONFFILE) \ - $(LISTENERFILE) $(ROOTMANIFEST) - -install_h: - -lint: - -include ../../Makefile.targ diff --git a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf b/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf deleted file mode 100644 index 07a4b8dc11..0000000000 --- a/usr/src/lib/print/mod_ipp/httpd-standalone-ipp.conf +++ /dev/null @@ -1,341 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# - -# -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -# -# "$Id: httpd-standalone-ipp.conf,v 1.4 2006/03/24 00:26:54 njacobs Exp $" -# - -# ident "%Z%%M% %I% %E% SMI" - -## -## httpd-standalone-ipp.conf -- Apache HTTP server configuration file for -## an Internet Print Protocol (IPP) listener -## - -# -# Based upon the NCSA server configuration files originally by Rob McCool. -# -# This is the main Apache server configuration file. It contains the -# configuration directives that give the server its instructions. -# See <URL:http://www.apache.org/docs/> for detailed information about -# the directives. mod_ipp specific directives are described in the -# mod_ipp(4) man page. -# - -### Section 1: Global Environment -# -# The directives in this section affect the overall operation of Apache, -# such as the number of concurrent requests it can handle or where it -# can find its configuration files. -# - -# -# ServerType is either inetd, or standalone. Inetd mode is only supported on -# Unix platforms. -# -ServerType standalone - -# -# ServerRoot: The top of the directory tree under which the server's -# configuration, error, and log files are kept. -# -# NOTE! If you intend to place this on an NFS (or otherwise network) -# mounted filesystem then please read the LockFile documentation -# (available at <URL:http://www.apache.org/docs/mod/core.html#lockfile>); -# you will save yourself a lot of trouble. -# -ServerRoot "/usr/apache" - -# -# The LockFile directive sets the path to the lockfile used when Apache -# is compiled with either USE_FCNTL_SERIALIZED_ACCEPT or -# USE_FLOCK_SERIALIZED_ACCEPT. This directive should normally be left at -# its default value. The main reason for changing it is if the logs -# directory is NFS mounted, since the lockfile MUST BE STORED ON A LOCAL -# DISK. The PID of the main server process is automatically appended to -# the filename. -# -#LockFile /var/run/httpd.lock -LockFile /var/run/httpd-standalone-ipp.lock - -# -# PidFile: The file in which the server should record its process -# identification number when it starts. -# -PidFile /var/run/httpd-standalone-ipp.pid - -# -# ScoreBoardFile: File used to store internal server process information. -# Not all architectures require this. But if yours does (you'll know because -# this file will be created when you run Apache) then you *must* ensure that -# no two invocations of Apache share the same scoreboard file. -# -ScoreBoardFile /var/run/httpd-standalone-ipp.scoreboard - -# -# In the standard configuration, the server will process httpd.conf (this -# file, specified by the -f command line option), srm.conf, and access.conf -# in that order. The latter two files are now distributed empty, as it is -# recommended that all directives be kept in a single file for simplicity. -# The commented-out values below are the built-in defaults. You can have the -# server ignore these files altogether by using "/dev/null" (for Unix) or -# "nul" (for Win32) for the arguments to the directives. -# -#ResourceConfig conf/srm.conf -#AccessConfig conf/access.conf - -# -# Timeout: The number of seconds before receives and sends time out. -# -Timeout 300 - -# -# KeepAlive: Whether or not to allow persistent connections (more than -# one request per connection). Set to "Off" to deactivate. -# -KeepAlive On - -# -# MaxKeepAliveRequests: The maximum number of requests to allow -# during a persistent connection. Set to 0 to allow an unlimited amount. -# We recommend you leave this number high, for maximum performance. -# -MaxKeepAliveRequests 100 - -# -# KeepAliveTimeout: Number of seconds to wait for the next request from the -# same client on the same connection. -# -KeepAliveTimeout 15 - -# -# Server-pool size regulation. Rather than making you guess how many -# server processes you need, Apache dynamically adapts to the load it -# sees --- that is, it tries to maintain enough server processes to -# handle the current load, plus a few spare servers to handle transient -# load spikes (e.g., multiple simultaneous requests from a single -# Netscape browser). -# -# It does this by periodically checking how many servers are waiting -# for a request. If there are fewer than MinSpareServers, it creates -# a new spare. If there are more than MaxSpareServers, some of the -# spares die off. The default values are probably OK for most sites. -# -MinSpareServers 1 -MaxSpareServers 2 - -# -# Number of servers to start initially --- should be a reasonable ballpark -# figure. -# -StartServers 1 - -# -# Limit on total number of servers running, i.e., limit on the number -# of clients who can simultaneously connect --- if this limit is ever -# reached, clients will be LOCKED OUT, so it should NOT BE SET TOO LOW. -# It is intended mainly as a brake to keep a runaway server from taking -# the system with it as it spirals down... -# -MaxClients 150 - -# -# MaxRequestsPerChild: the number of requests each child process is -# allowed to process before the child dies. The child will exit so -# as to avoid problems after prolonged use when Apache (and maybe the -# libraries it uses) leak memory or other resources. On most systems, this -# isn't really needed, but a few (such as Solaris) do have notable leaks -# in the libraries. For these platforms, set to something like 10000 -# or so; a setting of 0 means unlimited. -# -# NOTE: This value does not include keepalive requests after the initial -# request per connection. For example, if a child process handles -# an initial request and 10 subsequent "keptalive" requests, it -# would only count as 1 request towards this limit. -# -MaxRequestsPerChild 10 - -# -# Dynamic Shared Object (DSO) Support -# -# To be able to use the functionality of a module which was built as a DSO you -# have to place corresponding `LoadModule' lines at this location so the -# directives contained in it are actually available _before_ they are used. -# Please read the file http://httpd.apache.org/docs/dso.html for more -# details about the DSO mechanism and run `httpd -l' for the list of already -# built-in (statically linked and thus always available) modules in your httpd -# binary. -# -# Note: The order in which modules are loaded is important. Don't change -# the order below without expert advice. -# -LoadModule access_module libexec/mod_access.so -LoadModule alias_module libexec/mod_alias.so -LoadModule auth_module libexec/mod_auth.so -LoadModule mime_module libexec/mod_mime.so -LoadModule mime_magic_module libexec/mod_mime_magic.so -LoadModule ipp_module libexec/mod_ipp.so - -# Reconstruction of the complete module list from all available modules -# (static and shared ones) to achieve correct module execution order. -# [WHENEVER YOU CHANGE THE LOADMODULE SECTION ABOVE UPDATE THIS, TOO] -ClearModuleList -AddModule mod_access.c -AddModule mod_alias.c -AddModule mod_auth.c -AddModule mod_mime.c -AddModule mod_mime_magic.c -AddModule mod_ipp.c -AddModule mod_so.c - -### Section 2: 'Main' server configuration -# -# The directives in this section set up the values used by the 'main' -# server, which responds to any requests that aren't handled by a -# <VirtualHost> definition. These values also provide defaults for -# any <VirtualHost> containers you may define later in the file. -# -# All of these directives may appear inside <VirtualHost> containers, -# in which case these default settings will be overridden for the -# virtual host being defined. -# - -# -# If your ServerType directive (set earlier in the 'Global Environment' -# section) is set to "inetd", the next few directives don't have any -# effect since their settings are defined by the inetd configuration. -# Skip ahead to the ServerAdmin directive. -# - -# -# Port: The port to which the standalone server listens. For -# ports < 1023, you will need httpd to be run as root initially. -# -Port 631 - -# -# If you wish httpd to run as a different user or group, you must run -# httpd as root initially and it will switch. -# -# User/Group: The name (or #number) of the user/group to run httpd as. -# . On SCO (ODT 3) use "User nouser" and "Group nogroup". -# . On HPUX you may not be able to use shared memory as nobody, and the -# suggested workaround is to create a user www and use that user. -# NOTE that some kernels refuse to setgid(Group) or semctl(IPC_SET) -# when the value of (unsigned)Group is above 60000; -# don't use Group nobody on these systems! -# -User lp -Group lp - -# -# ServerAdmin: Your address, where problems with the server should be -# e-mailed. This address appears on some server-generated pages, such -# as error documents. -# -ServerAdmin lp@localhost - -# -# ServerName allows you to set a host name which is sent back to clients for -# your server if it's different than the one the program would get (i.e., use -# "www" instead of the host's real name). -# -# Note: You cannot just invent host names and hope they work. The name you -# define here must be a valid DNS name for your host. If you don't understand -# this, ask your network administrator. -# If your host doesn't have a registered DNS name, enter its IP address here. -# You will have to access it by its address (e.g., http://123.45.67.89/) -# anyway, and this will make redirections work in a sensible way. -# -# 127.0.0.1 is the TCP/IP local loop-back address, often named localhost. Your -# machine always knows itself by this address. If you use Apache strictly for -# local testing and development, you may use 127.0.0.1 as the server name. -# -#Servername printserver.some_company.com - -DefaultType application/ipp - -ErrorLog /var/lp/logs/ipp-errors -LogLevel warn - -DocumentRoot /var/lp/ipp-listener - -# Allow passing PPD files from this service as well -Alias /etc/lp/ppd/ /etc/lp/ppd/ -<Directory /etc/lp/ppd> - SetHandler send-as-is - <LimitExcept GET> - Deny from all - </LimitExcept> -</Directory> - -# mod_ipp specific configuration -<IfModule mod_ipp.c> - - <Location /> - # ipp-conformance automatic # default - # ipp-default-user nobody - ipp-default-service lpsched - # - # By default, only turn on operations that are not - # likely to cause real problems when the user can't - # be trusted. - # - ipp-operation all off - ipp-operation print-job on - ipp-operation validate-job on - ipp-operation create-job on - ipp-operation get-jobs on - ipp-operation get-printer-attributes on - ipp-operation send-document on - ipp-operation cancel-job on - ipp-operation get-job-attributes on - ipp-operation cups-get-default on - ipp-operation cups-get-printers on - ipp-operation cups-get-classes on - ipp-operation cups-move-job on - - # redirect non-IPP requests - ErrorDocument 404 /index.html - </Location> - - <Location /admin> - # ipp-conformance automatic # default - # ipp-default-user nobody - ipp-default-service lpsched - - ipp-operation all on - - AuthType Basic - AuthName "IPP Server" - AuthUserFile /etc/ipp-users - Require valid-user - - # redirect non-IPP requests - ErrorDocument 404 /index.html - </Location> -</IfModule> - diff --git a/usr/src/lib/print/mod_ipp/index.html b/usr/src/lib/print/mod_ipp/index.html deleted file mode 100644 index 15f680c666..0000000000 --- a/usr/src/lib/print/mod_ipp/index.html +++ /dev/null @@ -1,44 +0,0 @@ -<!-- - - CDDL HEADER START - - The contents of this file are subject to the terms of the - Common Development and Distribution License (the "License"). - You may not use this file except in compliance with the License. - - You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - or http://www.opensolaris.org/os/licensing. - See the License for the specific language governing permissions - and limitations under the License. - - When distributing Covered Code, include this CDDL HEADER in each - file and include the License file at usr/src/OPENSOLARIS.LICENSE. - If applicable, add the following below this CDDL HEADER, with the - fields enclosed by brackets "[]" replaced with your own identifying - information: Portions Copyright [yyyy] [name of copyright owner] - - CDDL HEADER END - - - Copyright 2006 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. - - ident "%Z%%M% %I% %E% SMI" ---> -<html> -<body> -The Internet Print Protocol (IPP) requires that all protocol requests be -encapsulated in HTTP and that all HTTP protocol requests be POST requests with -a Content-Type of "application/ipp". Since your request did not meet this -criteria, it has been ignored by the IPP listener. You will be redirected to -the -<a href=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris> -<b>Solaris®</b> AnswerBook -</a> -so that you can learn more about the Internet Print Protocol Listener. -<p> -If you would like more information about the Internet Print Protocol itself, -please visit <a href=http://www.pwg.org/ipp>http://www.pwg.org/ipp/</a>. -</body> -</html> -<meta HTTP-EQUIV=REFRESH CONTENT=10;URL=http://docs.sun.com/db?q=%22Internet+Print+Protocol%22&p=prod%2Fsolaris> diff --git a/usr/src/lib/print/mod_ipp/ipp-listener.xml b/usr/src/lib/print/mod_ipp/ipp-listener.xml deleted file mode 100644 index 686646a78c..0000000000 --- a/usr/src/lib/print/mod_ipp/ipp-listener.xml +++ /dev/null @@ -1,84 +0,0 @@ -<?xml version="1.0"?> -<!-- -CDDL HEADER START - -The contents of this file are subject to the terms of the -Common Development and Distribution License (the "License"). -You may not use this file except in compliance with the License. - -You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -or http://www.opensolaris.org/os/licensing. -See the License for the specific language governing permissions -and limitations under the License. - -When distributing Covered Code, include this CDDL HEADER in each -file and include the License file at usr/src/OPENSOLARIS.LICENSE. -If applicable, add the following below this CDDL HEADER, with the -fields enclosed by brackets "[]" replaced with your own identifying -information: Portions Copyright [yyyy] [name of copyright owner] - -CDDL HEADER END ---> -<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> -<!-- - Copyright 2009 Sun Microsystems, Inc. All rights reserved. - Use is subject to license terms. ---> - -<service_bundle type='manifest' name='SUNWipplr:ipp-listener'> - -<service - name='application/print/ipp-listener' - type='service' - version='1'> - - <create_default_instance enabled='false' /> - - <dependency name='print-service' - grouping='require_any' - restart_on='refresh' - type='service'> - <service_fmri value='svc:/application/print/server' /> - </dependency> - - <exec_method - type='method' - name='start' - exec='/usr/apache/bin/httpd -f /etc/apache/httpd-standalone-ipp.conf' - timeout_seconds='10' /> - - <exec_method - type='method' - name='stop' - exec='/bin/pkill -f httpd-standalone-ipp.conf' - timeout_seconds='5' /> - - <property_group name='general' type='framework'> - <!-- to start/stop IPP listening service--> - <propval name='action_authorization' type='astring' - value='solaris.print.admin' /> - <propval name='value_authorization' type='astring' - value='solaris.print.admin' /> - </property_group> - - <property_group name='firewall_context' type='com.sun,fw_definition'> - <propval name='ipf_method' type='astring' - value='/lib/svc/method/print-svc ipfilter svc:/application/print/server:default' /> - </property_group> - - <stability value='Unstable' /> - - <template> - <common_name> - <loctext xml:lang='C'> - Internet Print Protocol Listening Service - </loctext> - </common_name> - <documentation> - <manpage title='mod_ipp' section='4' - manpath='/usr/share/man' /> - </documentation> - </template> -</service> - -</service_bundle> diff --git a/usr/src/lib/print/mod_ipp/mod_ipp.c b/usr/src/lib/print/mod_ipp/mod_ipp.c deleted file mode 100644 index 2d9ece2287..0000000000 --- a/usr/src/lib/print/mod_ipp/mod_ipp.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ - -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - */ - -/* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Internet Printing Protocol (IPP) module for Apache. - */ - -#include "ap_config.h" - -#include <stdio.h> -#include <time.h> -#include <sys/time.h> -#include <values.h> -#include <libintl.h> -#include <alloca.h> - -#include "httpd.h" -#include "http_config.h" -#include "http_core.h" -#include "http_protocol.h" -#include "http_log.h" -#include "http_main.h" -#include "papi.h" -#ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */ -#define APACHE2 -#include "apr_compat.h" -#endif - -#include <papi.h> -#include <ipp-listener.h> - -#ifndef APACHE2 -module MODULE_VAR_EXPORT ipp_module; -#else -module AP_MODULE_DECLARE_DATA ipp_module; -#endif - -#ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */ -#define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \ - { directive, action, arg, where, NO_ARGS, mesg } -#define AP_INIT_TAKE1(directive, action, arg, where, mesg) \ - { directive, action, arg, where, TAKE1, mesg } -#define AP_INIT_TAKE2(directive, action, arg, where, mesg) \ - { directive, action, arg, where, TAKE2, mesg } -#endif - -typedef struct { - int conformance; - char *default_user; - char *default_svc; - papi_attribute_t **operations; -} IPPListenerConfig; - -#ifdef DEBUG -void -dump_buffer(FILE *fp, char *tag, char *buffer, int bytes) -{ - int i, j, ch; - - fprintf(fp, "%s %d(0x%x) bytes\n", (tag ? tag : ""), bytes, bytes); - for (i = 0; i < bytes; i += 16) { - fprintf(fp, "%s ", (tag ? tag : "")); - - for (j = 0; j < 16 && (i + j) < bytes; j ++) - fprintf(fp, " %02X", buffer[i + j] & 255); - - while (j < 16) { - fprintf(fp, " "); - j++; - } - - fprintf(fp, " "); - for (j = 0; j < 16 && (i + j) < bytes; j ++) { - ch = buffer[i + j] & 255; - if (ch < ' ' || ch == 127) - ch = '.'; - putc(ch, fp); - } - putc('\n', fp); - } - fflush(fp); -} -#endif - -static ssize_t -read_data(void *fd, void *buf, size_t siz) -{ - ssize_t len_read; - request_rec *ap_r = (request_rec *)fd; - - len_read = ap_get_client_block(ap_r, buf, siz); -#ifndef APACHE2 - ap_reset_timeout(ap_r); -#endif - -#ifdef DEBUG - fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d", - fd, buf, siz, len_read); - if (len_read < 0) - fprintf(stderr, ": %s", strerror(errno)); - putc('\n', stderr); - dump_buffer(stderr, "read_data:", buf, len_read); -#endif - - return (len_read); -} - -static ssize_t -write_data(void *fd, void *buf, size_t siz) -{ - ssize_t len_written; - request_rec *ap_r = (request_rec *)fd; - -#ifndef APACHE2 - ap_reset_timeout(ap_r); -#endif -#ifdef DEBUG - dump_buffer(stderr, "write_data:", buf, siz); -#endif - len_written = ap_rwrite(buf, siz, ap_r); - - return (len_written); -} - -static void -discard_data(request_rec *r) -{ -#ifdef APACHE2 - (void) ap_discard_request_body(r); -#else - /* - * This is taken from ap_discard_request_body(). The reason we can't - * just use it in Apache 1.3 is that it does various timeout things we - * don't want it to do. Apache 2.0 doesn't do that, so we can safely - * use the normal function. - */ - if (r->read_chunked || r->remaining > 0) { - char dumpbuf[HUGE_STRING_LEN]; - int i; - - do { - i = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN); -#ifdef DEBUG - dump_buffer(stderr, "discarded", dumpbuf, i); -#endif - } while (i > 0); - } -#endif -} - -void _log_rerror(const char *file, int line, int level, request_rec *r, - const char *fmt, ...) -{ - va_list args; - size_t size; - char *message = alloca(BUFSIZ); - - va_start(args, fmt); - /* - * fill in the message. If the buffer is too small, allocate - * one that is large enough and fill it in. - */ - if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ) - if ((message = alloca(size)) != NULL) - vsnprintf(message, size, fmt, args); - va_end(args); - -#ifdef APACHE2 - ap_log_rerror(file, line, level, NULL, r, message); -#else - ap_log_rerror(file, line, level, r, message); -#endif -} - -static int -ipp_handler(request_rec *r) -{ - papi_attribute_t **request = NULL, **response = NULL; - IPPListenerConfig *config; - papi_status_t status; - int ret; - - /* Really, IPP is all POST requests */ - if (r->method_number != M_POST) - return (DECLINED); - -#ifndef APACHE2 - /* - * An IPP request must have a MIME type of "application/ipp" - * (RFC-2910, Section 4, page 19). If it doesn't match this - * MIME type, we should decline the request and let someone else - * try and handle it. - */ - if (r->headers_in != NULL) { - char *mime_type = (char *)ap_table_get(r->headers_in, - "Content-Type"); - - if ((mime_type == NULL) || - (strcasecmp(mime_type, "application/ipp") != 0)) - return (DECLINED); - } -#endif - /* CHUNKED_DECHUNK might not work right for IPP? */ - if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) - return (ret); - - if (!ap_should_client_block(r)) - return (HTTP_INTERNAL_SERVER_ERROR); - -#ifndef APACHE2 - ap_soft_timeout("ipp_module: read/reply request ", r); -#endif - /* read the IPP request off the network */ - status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST); - - if (status != PAPI_OK) - _log_rerror(APLOG_MARK, APLOG_ERR, r, - "read failed: %s\n", papiStatusString(status)); -#ifdef DEBUG - papiAttributeListPrint(stderr, request, "request (%d) ", getpid()); -#endif - - (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, - "originating-host", (char *) -#ifdef APACHE2 - ap_get_remote_host - (r->connection, r->per_dir_config, REMOTE_NAME, NULL)); -#else - ap_get_remote_host - (r->connection, r->per_dir_config, REMOTE_NAME)); -#endif - - (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, - "uri-port", ap_get_server_port(r)); - if (r->headers_in != NULL) { - char *host = (char *)ap_table_get(r->headers_in, "Host"); - - if ((host == NULL) || (host[0] == '\0')) - host = (char *)ap_get_server_name(r); - - (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, - "uri-host", host); - } - (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, - "uri-path", r->uri); - - config = ap_get_module_config(r->per_dir_config, &ipp_module); - if (config != NULL) { - (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, - "conformance", config->conformance); - (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, - "operations", config->operations); - if (config->default_user != NULL) - (void) papiAttributeListAddString(&request, - PAPI_ATTR_EXCL, "default-user", - config->default_user); - if (config->default_svc != NULL) - (void) papiAttributeListAddString(&request, - PAPI_ATTR_EXCL, "default-service", - config->default_svc); - } - - /* - * For Trusted Solaris, pass the fd number of the socket connection - * to the backend so the it can be forwarded to the backend print - * service to retrieve the sensativity label off of a multi-level - * port. - */ - (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, - "peer-socket", ap_bfileno(r->connection->client, B_RD)); - - /* process the request */ - status = ipp_process_request(request, &response, read_data, r); - if (status != PAPI_OK) { - errno = 0; - _log_rerror(APLOG_MARK, APLOG_ERR, r, - "request failed: %s\n", papiStatusString(status)); - discard_data(r); - } -#ifdef DEBUG - fprintf(stderr, "processing result: %s\n", papiStatusString(status)); - papiAttributeListPrint(stderr, response, "response (%d) ", getpid()); -#endif - - /* - * If the client is using chunking and we have not yet received the - * final "0" sized chunk, we need to discard any data that may - * remain in the post request. - */ - if ((r->read_chunked != 0) && - (ap_table_get(r->headers_in, "Content-Length") == NULL)) - discard_data(r); - - /* write an IPP response back to the network */ - r->content_type = "application/ipp"; - -#ifndef APACHE2 - ap_send_http_header(r); -#endif - - status = ipp_write_message(write_data, r, response); - if (status != PAPI_OK) - _log_rerror(APLOG_MARK, APLOG_ERR, r, - "write failed: %s\n", papiStatusString(status)); -#ifdef DEBUG - fprintf(stderr, "write result: %s\n", papiStatusString(status)); - fflush(stderr); -#endif - - papiAttributeListFree(request); - papiAttributeListFree(response); - -#ifndef APACHE2 - ap_kill_timeout(r); - if (ap_rflush(r) < 0) - _log_rerror(APLOG_MARK, APLOG_ERR, r, - "flush failed, response may not have been sent"); -#endif - - return (OK); -} - - -/*ARGSUSED1*/ -static void * -create_ipp_dir_config( -#ifndef APACHE2 - pool *p, -#else - apr_pool_t *p, -#endif - char *dirspec) -{ - IPPListenerConfig *config = -#ifndef APACHE2 - ap_pcalloc(p, sizeof (*config)); -#else - apr_pcalloc(p, sizeof (*config)); -#endif - - if (config != NULL) { - (void) memset(config, 0, sizeof (*config)); - config->conformance = IPP_PARSE_CONFORMANCE_RASH; - config->default_user = NULL; - config->default_svc = NULL; - (void) ipp_configure_operation(&config->operations, "required", - "enable"); - } - - return (config); -} - -/*ARGSUSED0*/ -static const char * -ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg) -{ - IPPListenerConfig *config = (IPPListenerConfig *)cfg; - - if (strncasecmp(arg, "automatic", 4) == 0) { - config->conformance = IPP_PARSE_CONFORMANCE_RASH; - } else if (strcasecmp(arg, "1.0") == 0) { - config->conformance = IPP_PARSE_CONFORMANCE_LOOSE; - } else if (strcasecmp(arg, "1.1") == 0) { - config->conformance = IPP_PARSE_CONFORMANCE_STRICT; - } else { - return ("unknown conformance, try (automatic/1.0/1.1)"); - } - - return (NULL); -} - -/*ARGSUSED0*/ -static const char * -ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle) -{ - IPPListenerConfig *config = (IPPListenerConfig *)cfg; - papi_status_t status; - - status = ipp_configure_operation(&config->operations, op, toggle); - switch (status) { - case PAPI_OK: - return (NULL); - case PAPI_BAD_ARGUMENT: - return (gettext("internal error (invalid argument)")); - default: - return (papiStatusString(status)); - } - - /* NOTREACHED */ - /* return (gettext("contact your software vendor")); */ -} - -static const char * -ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg) -{ - IPPListenerConfig *config = (IPPListenerConfig *)cfg; - - config->default_user = (char *)arg; - - return (NULL); -} - -static const char * -ipp_default_svc(cmd_parms *cmd, void *cfg, const char *arg) -{ - IPPListenerConfig *config = (IPPListenerConfig *)cfg; - - config->default_svc = (char *)arg; - - return (NULL); -} - -#ifdef DEBUG -/*ARGSUSED0*/ -static const char * -ipp_module_hang(cmd_parms *cmd, void *cfg) -{ - static int i = 1; - - /* wait so we can attach a debugger, assign i = 0, and step through */ - while (i); - - return (NULL); -} -#endif /* DEBUG */ - -static const command_rec ipp_cmds[] = -{ - AP_INIT_TAKE1("ipp-conformance", ipp_conformance, NULL, ACCESS_CONF, - "IPP protocol conformance (loose/strict)"), - AP_INIT_TAKE2("ipp-operation", ipp_operation, NULL, ACCESS_CONF, - "IPP protocol operations to enable/disable)"), - AP_INIT_TAKE1("ipp-default-user", ipp_default_user, NULL, ACCESS_CONF, - "default user for various operations"), - AP_INIT_TAKE1("ipp-default-service", ipp_default_svc, NULL, ACCESS_CONF, - "default service for various operations"), -#ifdef DEBUG - AP_INIT_NO_ARGS("ipp-module-hang", ipp_module_hang, NULL, ACCESS_CONF, - "hang the module until we can attach a debugger (no args)"), -#endif - { NULL } -}; - -#ifdef APACHE2 -/*ARGSUSED0*/ -static const char * -ipp_method(const request_rec *r) -{ - return ("ipp"); -} - -/*ARGSUSED0*/ -static unsigned short -ipp_port(const request_rec *r) -{ - return (631); -} - -/* Dispatch list for API hooks */ -/*ARGSUSED0*/ -static void -ipp_register_hooks(apr_pool_t *p) -{ - static const char * const modules[] = { "mod_dir.c", NULL }; - - /* Need to make sure we don't get directory listings by accident */ - ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE); - ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA ipp_module = { - STANDARD20_MODULE_STUFF, - create_ipp_dir_config, /* create per-dir config */ - NULL, /* merge per-dir config */ - NULL, /* create per-server config */ - NULL, /* merge per-server config */ - ipp_cmds, /* table of config commands */ - ipp_register_hooks /* register hooks */ -}; - -#else /* Apache 1.X */ - -/* Dispatch list of content handlers */ -static const handler_rec ipp_handlers[] = { - /* - * This handler association causes all IPP request with the - * correct MIME type to call the protocol handler. - */ - { "application/ipp", ipp_handler }, - /* - * This hander association is causes everything to go through the IPP - * protocol request handler. This is necessary because client POST - * request may be for something outside of the normal printer-uri - * space. - */ - { "*/*", ipp_handler }, - - { NULL, NULL } -}; - - -module MODULE_VAR_EXPORT ipp_module = { - STANDARD_MODULE_STUFF, - NULL, /* module initializer */ - create_ipp_dir_config, /* create per-dir config structures */ - NULL, /* merge per-dir config structures */ - NULL, /* create per-server config structures */ - NULL, /* merge per-server config structures */ - ipp_cmds, /* table of config file commands */ - ipp_handlers, /* [#8] MIME-typed-dispatched handlers */ - NULL, /* [#1] URI to filename translation */ - NULL, /* [#4] validate user id from request */ - NULL, /* [#5] check if the user is ok _here_ */ - NULL, /* [#3] check access by host address */ - NULL, /* [#6] determine MIME type */ - NULL, /* [#7] pre-run fixups */ - NULL, /* [#9] log a transaction */ - NULL, /* [#2] header parser */ - NULL, /* child_init */ - NULL, /* child_exit */ - NULL /* [#0] post read-request */ -}; -#endif diff --git a/usr/src/lib/pylibbe/Makefile.com b/usr/src/lib/pylibbe/Makefile.com index aa26dec043..9f964ce417 100644 --- a/usr/src/lib/pylibbe/Makefile.com +++ b/usr/src/lib/pylibbe/Makefile.com @@ -44,7 +44,8 @@ C99MODE= $(C99_ENABLE) LIBS = $(DYNLIB) LDLIBS += -lbe -lnvpair -lc CFLAGS += $(CCVERBOSE) -CPPFLAGS += -I/usr/include/python2.6 -D_FILE_OFFSET_BITS=64 -I../../libbe/common +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/python2.6 \ + -D_FILE_OFFSET_BITS=64 -I../../libbe/common .KEEP_STATE: diff --git a/usr/src/lib/pysolaris/Makefile.com b/usr/src/lib/pysolaris/Makefile.com index a27492771a..0e5b385bd8 100644 --- a/usr/src/lib/pysolaris/Makefile.com +++ b/usr/src/lib/pysolaris/Makefile.com @@ -44,6 +44,7 @@ C99LMODE= -Xc99=%all LIBS = $(DYNLIB) LDLIBS += -lc -lsec -lidmap -lpython2.6 CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/python2.6 CERRWARN += -_gcc=-Wno-unused-variable CPPFLAGS += -I/usr/include/python2.6 diff --git a/usr/src/lib/pyzfs/Makefile.com b/usr/src/lib/pyzfs/Makefile.com index 29d0407cae..a565ed8059 100644 --- a/usr/src/lib/pyzfs/Makefile.com +++ b/usr/src/lib/pyzfs/Makefile.com @@ -47,6 +47,7 @@ C99LMODE= -Xc99=%all LIBS = $(DYNLIB) LDLIBS += -lc -lnvpair -lpython2.6 -lzfs CFLAGS += $(CCVERBOSE) +CPPFLAGS += -I$(ADJUNCT_PROTO)/usr/include/python2.6 CERRWARN += -_gcc=-Wno-unused-variable CPPFLAGS += -I/usr/include/python2.6 CPPFLAGS += -I../../../uts/common/fs/zfs |