fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * CDDL HEADER START
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * The contents of this file are subject to the terms of the
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Common Development and Distribution License (the "License").
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * You may not use this file except in compliance with the License.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * or http://www.opensolaris.org/os/licensing.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * See the License for the specific language governing permissions
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * and limitations under the License.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * When distributing Covered Code, include this CDDL HEADER in each
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * If applicable, add the following below this CDDL HEADER, with the
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * fields enclosed by brackets "[]" replaced with your own identifying
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * information: Portions Copyright [yyyy] [name of copyright owner]
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * CDDL HEADER END
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * CUPS support for the SMB and SPOOLSS print services.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <sys/types.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <sys/stat.h>
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#include <sys/atomic.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <strings.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <syslog.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <signal.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <pthread.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <synch.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <dlfcn.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <errno.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <smbsrv/smb.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include <smbsrv/smb_share.h>
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#include "smbd.h"
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross#ifdef HAVE_CUPS
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross#include <cups/cups.h>
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMB_SPOOL_WAIT 2
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMBD_PJOBLEN 256
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMBD_PRINTER "Postscript"
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMBD_FN_PREFIX "cifsprintjob-"
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMBD_CUPS_SPOOL_DIR "//var//spool//cups"
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh#define SMBD_CUPS_DOCNAME "generic_doc"
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshtypedef struct smbd_printjob {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pid_t pj_pid;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int pj_sysjob;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int pj_fd;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh time_t pj_start_time;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int pj_status;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh size_t pj_size;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int pj_page_count;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh boolean_t pj_isspooled;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh boolean_t pj_jobnum;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char pj_filename[SMBD_PJOBLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char pj_jobname[SMBD_PJOBLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char pj_username[SMBD_PJOBLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char pj_queuename[SMBD_PJOBLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh} smbd_printjob_t;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshtypedef struct smb_cups_ops {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh void *cups_hdl;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups_lang_t *(*cupsLangDefault)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh const char *(*cupsLangEncoding)(cups_lang_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh void (*cupsLangFree)(cups_lang_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_status_t (*cupsLastError)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int (*cupsGetDests)(cups_dest_t **);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh void (*cupsFreeDests)(int, cups_dest_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_t *(*cupsDoFileRequest)(http_t *, ipp_t *,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh const char *, const char *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_t *(*ippNew)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh void (*ippDelete)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char *(*ippErrorString)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_attribute_t *(*ippAddString)();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh void (*httpClose)(http_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh http_t *(*httpConnect)(const char *, int);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh} smb_cups_ops_t;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic uint32_t smbd_cups_jobnum = 1;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic smb_cups_ops_t smb_cups;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic mutex_t smbd_cups_mutex;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void *smbd_spool_monitor(void *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic smb_cups_ops_t *smbd_cups_ops(void);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void smbd_print_share_comment(smb_share_t *, cups_dest_t *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void *smbd_share_printers(void *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void smbd_spool_copyfile(smb_inaddr_t *, char *, char *, char *);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshextern smbd_t smbd;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
b7301bf5522d8b9141fe432333ded586218327f2Gordon Ross * Start the spool thread.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Returns 0 on success, an error number if thread creation fails.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshvoid
b7301bf5522d8b9141fe432333ded586218327f2Gordon Rosssmbd_spool_start(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pthread_attr_t attr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int rc;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
b7301bf5522d8b9141fe432333ded586218327f2Gordon Ross if (!smb_config_getbool(SMB_CI_PRINT_ENABLE))
b7301bf5522d8b9141fe432333ded586218327f2Gordon Ross return;
b7301bf5522d8b9141fe432333ded586218327f2Gordon Ross
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_init(&attr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh rc = pthread_create(&smbd.s_spool_tid, &attr, smbd_spool_monitor, NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_destroy(&attr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (rc != 0)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_NOTICE,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "failed to start print monitor: %s", strerror(errno));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * A single pthread_kill should be sufficient but we include
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * a couple of retries to avoid implementation idiosyncrasies
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * around signal delivery.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshvoid
b7301bf5522d8b9141fe432333ded586218327f2Gordon Rosssmbd_spool_stop(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int i;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (pthread_self() == smbd.s_spool_tid)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh for (i = 0; i < 3 && smbd.s_spool_tid != 0; ++i) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (pthread_kill(smbd.s_spool_tid, SIGTERM) == ESRCH)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh break;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) sleep(1);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * This thread blocks waiting for close print file in the kernel.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * It then uses the data returned from the ioctl to copy the spool file
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * into the cups spooler.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * This mechanism is really only used by Windows Vista and Windows 7.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Other versions of Windows create a zero size file, which is removed
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * by smbd_spool_copyfile.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*ARGSUSED*/
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_spool_monitor(void *arg)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh uint32_t spool_num;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char username[MAXNAMELEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char path[MAXPATHLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_inaddr_t ipaddr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int error_retry_cnt = 5;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbd_online_wait("smbd_spool_monitor");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh spoolss_register_copyfile(smbd_spool_copyfile);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh while (!smbd.s_shutting_down && (error_retry_cnt > 0)) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh errno = 0;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_kmod_get_spool_doc(&spool_num, username,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh path, &ipaddr) == 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbd_spool_copyfile(&ipaddr,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh username, path, SMBD_CUPS_DOCNAME);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh error_retry_cnt = 5;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh } else {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (errno == ECANCELED)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh break;
23a9c295bad892ce51d86fda89698563b5810495Gordon Ross if ((errno != EINTR) && (errno != EAGAIN))
23a9c295bad892ce51d86fda89698563b5810495Gordon Ross error_retry_cnt--;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) sleep(SMB_SPOOL_WAIT);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh spoolss_register_copyfile(NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbd.s_spool_tid = 0;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * All versions of windows use this function to spool files to a printer
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * via the cups interface
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_spool_copyfile(smb_inaddr_t *ipaddr, char *username, char *path,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char *doc_name)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups_ops_t *cups;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh http_t *http = NULL; /* HTTP connection to server */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_t *request = NULL; /* IPP Request */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh ipp_t *response = NULL; /* IPP Response */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups_lang_t *language = NULL; /* Default language */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char uri[HTTP_MAX_URI]; /* printer-uri attribute */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char new_jobname[SMBD_PJOBLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbd_printjob_t pjob;
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross char clientname[INET6_ADDRSTRLEN];
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh struct stat sbuf;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int rc = 1;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (stat(path, &sbuf)) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_INFO, "smbd_spool_copyfile: %s: %s",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh path, strerror(errno));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh /*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * Remove zero size files and return; these were inadvertantly
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * created by XP or 2000.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (sbuf.st_size == 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (remove(path) != 0)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_INFO,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: cannot remove %s: %s",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh path, strerror(errno));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((cups = smbd_cups_ops()) == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((http = cups->httpConnect("localhost", 631)) == NULL) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_INFO,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: cupsd not running");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((request = cups->ippNew()) == NULL) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_INFO,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: ipp not running");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh request->request.op.operation_id = IPP_PRINT_JOB;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh request->request.op.request_id = 1;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh language = cups->cupsLangDefault();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "attributes-charset", NULL, cups->cupsLangEncoding(language));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "attributes-natural-language", NULL, language->language);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) snprintf(uri, sizeof (uri), "ipp://localhost/printers/%s",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh SMBD_PRINTER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_pid = pthread_self();
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_sysjob = 10;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(pjob.pj_filename, path, SMBD_PJOBLEN);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_start_time = time(NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_status = 2;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_size = sbuf.st_blocks * 512;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_page_count = 1;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_isspooled = B_TRUE;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_jobnum = smbd_cups_jobnum;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(pjob.pj_jobname, doc_name, SMBD_PJOBLEN);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(pjob.pj_username, username, SMBD_PJOBLEN);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(pjob.pj_queuename, SMBD_CUPS_SPOOL_DIR, SMBD_PJOBLEN);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "printer-uri", NULL, uri);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "requesting-user-name", NULL, pjob.pj_username);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_inet_ntop(ipaddr, clientname,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh SMB_IPSTRLEN(ipaddr->a_family)) == NULL) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_INFO,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: %s: unknown client", clientname);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh goto out;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "job-originating-host-name", NULL, clientname);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) snprintf(new_jobname, SMBD_PJOBLEN, "%s%d",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh SMBD_FN_PREFIX, pjob.pj_jobnum);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "job-name", NULL, new_jobname);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) snprintf(uri, sizeof (uri) - 1, "/printers/%s", SMBD_PRINTER);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh response = cups->cupsDoFileRequest(http, request, uri,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pjob.pj_filename);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (response != NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (response->request.status.status_code >= IPP_OK_CONFLICT) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_ERR,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: printer %s: %s",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh SMBD_PRINTER,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippErrorString(cups->cupsLastError()));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh } else {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh atomic_inc_32(&smbd_cups_jobnum);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh rc = 0;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh } else {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_ERR,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_spool_copyfile: unable to print to %s",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippErrorString(cups->cupsLastError()));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (rc == 0)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) unlink(pjob.pj_filename);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshout:
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (response)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->ippDelete(response);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (language)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->cupsLangFree(language);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (http)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->httpClose(http);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshint
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_cups_init(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_lock(&smbd_cups_mutex);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_cups.cups_hdl != NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_unlock(&smbd_cups_mutex);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (0);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((smb_cups.cups_hdl = dlopen("libcups.so.2", RTLD_NOW)) == NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_unlock(&smbd_cups_mutex);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_DEBUG,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_cups_init: cannot open libcups");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (ENOENT);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLangDefault =
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (cups_lang_t *(*)())dlsym(smb_cups.cups_hdl, "cupsLangDefault");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLangEncoding = (const char *(*)(cups_lang_t *))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsLangEncoding");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsDoFileRequest =
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (ipp_t *(*)(http_t *, ipp_t *, const char *, const char *))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsDoFileRequest");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLastError = (ipp_status_t (*)())
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsLastError");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLangFree = (void (*)(cups_lang_t *))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsLangFree");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsGetDests = (int (*)(cups_dest_t **))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsGetDests");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsFreeDests = (void (*)(int, cups_dest_t *))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "cupsFreeDests");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.httpClose = (void (*)(http_t *))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "httpClose");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.httpConnect = (http_t *(*)(const char *, int))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "httpConnect");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippNew = (ipp_t *(*)())dlsym(smb_cups.cups_hdl, "ippNew");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippDelete = (void (*)())dlsym(smb_cups.cups_hdl, "ippDelete");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippErrorString = (char *(*)())
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "ippErrorString");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippAddString = (ipp_attribute_t *(*)())
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh dlsym(smb_cups.cups_hdl, "ippAddString");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_cups.cupsLangDefault == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLangEncoding == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsDoFileRequest == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLastError == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsLangFree == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsGetDests == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cupsFreeDests == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippNew == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.httpClose == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.httpConnect == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippDelete == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippErrorString == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.ippAddString == NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) dlclose(smb_cups.cups_hdl);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cups_hdl = NULL;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_unlock(&smbd_cups_mutex);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_DEBUG,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_cups_init: cannot load libcups");
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (ENOENT);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_unlock(&smbd_cups_mutex);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (0);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshvoid
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_cups_fini(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_lock(&smbd_cups_mutex);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_cups.cups_hdl != NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) dlclose(smb_cups.cups_hdl);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups.cups_hdl = NULL;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) mutex_unlock(&smbd_cups_mutex);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic smb_cups_ops_t *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_cups_ops(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_cups.cups_hdl == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (&smb_cups);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshvoid
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_load_printers(void)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pthread_t tid;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh pthread_attr_t attr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int rc;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (!smb_config_getbool(SMB_CI_PRINT_ENABLE))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_init(&attr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh rc = pthread_create(&tid, &attr, smbd_share_printers, &tid);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) pthread_attr_destroy(&attr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (rc != 0)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_NOTICE,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "unable to load printer shares: %s", strerror(errno));
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh * All print shares use the path from print$.
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh */
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh/*ARGSUSED*/
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void *
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_share_printers(void *arg)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups_dest_t *dests;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups_dest_t *dest;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_cups_ops_t *cups;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smb_share_t si;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh uint32_t nerr;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int num_dests;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int i;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (!smb_config_getbool(SMB_CI_PRINT_ENABLE))
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((cups = smbd_cups_ops()) == NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_DEBUG,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_share_printers unable to load %s", SMB_SHARE_PRINT);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh num_dests = cups->cupsGetDests(&dests);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh for (i = num_dests, dest = dests; i > 0; i--, dest++) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (dest->instance != NULL)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh continue;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(si.shr_name, dest->name, MAXPATHLEN);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh smbd_print_share_comment(&si, dest);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh si.shr_type = STYPE_PRINTQ;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh nerr = smb_shr_add(&si);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (nerr == NERR_Success || nerr == NERR_DuplicateShare)
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_DEBUG,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "shared printer: %s", si.shr_name);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh else
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross syslog(LOG_DEBUG,
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh "smbd_share_printers: unable to add share %s: %u",
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh si.shr_name, nerr);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups->cupsFreeDests(num_dests, dests);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return (NULL);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshstatic void
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintoshsmbd_print_share_comment(smb_share_t *si, cups_dest_t *dest)
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh{
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh cups_option_t *options;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char *comment;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char *name;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh char *value;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh int i;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh comment = "Print Share";
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if ((options = dest->options) == NULL) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(si->shr_cmnt, comment, SMB_SHARE_CMNT_MAX);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh return;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh for (i = 0; i < dest->num_options; ++i) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh name = options[i].name;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh value = options[i].value;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (name == NULL || value == NULL ||
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh *name == '\0' || *value == '\0')
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh continue;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh if (strcasecmp(name, "printer-info") == 0) {
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh comment = value;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh break;
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh }
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh (void) strlcpy(si->shr_cmnt, comment, SMB_SHARE_CMNT_MAX);
fd9ee8b58485b20072eeef1310a88ff348d5e7fajoyce mcintosh}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross#else /* HAVE_CUPS */
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross/*
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross * If not HAVE_CUPS, just provide a few "stubs".
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross */
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossint
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_cups_init(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross return (ENOENT);
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_cups_fini(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_load_printers(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_spool_init(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_spool_fini(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_spool_start(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rossvoid
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Rosssmbd_spool_stop(void)
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross{
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross}
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross
86d7016b0051dd58772baafe5b5bcee51d560b05Gordon Ross#endif /* HAVE_CUPS */