/*
- * "$Id: dirsvc.c 6590 2007-06-21 18:22:22Z mike $"
+ * "$Id: dirsvc.c 7003 2007-10-01 23:10:13Z mike $"
*
* Directory services routines for the Common UNIX Printing System (CUPS).
*
+ * Copyright 2007 by Apple Inc.
* Copyright 1997-2007 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
+ * property of Apple Inc. 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
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* Contents:
*
* slp_url_callback() - SLP service url callback
* update_cups_browse() - Update the browse lists using the CUPS
* protocol.
+ * update_lpd() - Update the LPD configuration as needed.
* update_polling() - Read status messages from the poll daemons.
+ * update_smb() - Update the SMB configuration as needed.
*/
/*
#ifdef HAVE_DNSSD
# include <dns_sd.h>
-# include <nameser.h>
-# include <nameser.h>
-# ifdef HAVE_COREFOUNDATION
-# include <CoreFoundation/CoreFoundation.h>
-# endif /* HAVE_COREFOUNDATION */
-# ifdef HAVE_SYSTEMCONFIGURATION
-# include <SystemConfiguration/SystemConfiguration.h>
-# endif /* HAVE_SYSTEMCONFIGURATION */
+# ifdef __APPLE__
+# include <nameser.h>
+# ifdef HAVE_COREFOUNDATION
+# include <CoreFoundation/CoreFoundation.h>
+# endif /* HAVE_COREFOUNDATION */
+# ifdef HAVE_SYSTEMCONFIGURATION
+# include <SystemConfiguration/SystemConfiguration.h>
+# endif /* HAVE_SYSTEMCONFIGURATION */
+# endif /* __APPLE__ */
#endif /* HAVE_DNSSD */
ipp_pstate_t state, const char *location,
const char *info, const char *make_model,
int num_attrs, cups_option_t *attrs);
-static void process_implicit_classes(void);
+static void process_implicit_classes(int *write_printcap);
static void send_cups_browse(cupsd_printer_t *p);
#ifdef HAVE_LDAP
static void send_ldap_browse(cupsd_printer_t *p);
static void send_slp_browse(cupsd_printer_t *p);
#endif /* HAVE_LIBSLP */
static void update_cups_browse(void);
+static void update_lpd(int onoff);
static void update_polling(void);
+static void update_smb(int onoff);
#ifdef HAVE_OPENLDAP
* Announce the deletion...
*/
- if ((BrowseLocalProtocols & BROWSE_CUPS))
+ if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
{
cups_ptype_t savedtype = p->type; /* Saved printer type */
* Do auto-classing if needed...
*/
- process_implicit_classes();
+ process_implicit_classes(NULL);
}
cupsd_printer_t *p; /* Current printer */
time_t ut, /* Minimum update time */
to; /* Timeout time */
+ int write_printcap; /* Write the printcap file? */
if (!Browsing || !BrowseLocalProtocols || !Printers)
p->browse_time = time(NULL);
- if (BrowseLocalProtocols & BROWSE_CUPS)
+ if ((BrowseLocalProtocols & BROWSE_CUPS) && BrowseSocket >= 0)
send_cups_browse(p);
#ifdef HAVE_LIBSLP
* Loop through all of the printers and send local updates as needed...
*/
- for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
+ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers), write_printcap = 0;
p;
p = (cupsd_printer_t *)cupsArrayNext(Printers))
{
cupsArraySave(Printers);
cupsdDeletePrinter(p, 1);
cupsArrayRestore(Printers);
+ write_printcap = 1;
}
}
}
+
+ if (write_printcap)
+ cupsdWritePrintcap();
}
if ((BrowseSocket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdStartBrowsing: Unable to create broadcast "
- "socket - %s.", strerror(errno));
+ "Unable to create broadcast socket - %s.",
+ strerror(errno));
BrowseLocalProtocols &= ~BROWSE_CUPS;
BrowseRemoteProtocols &= ~BROWSE_CUPS;
return;
if (bind(BrowseSocket, (struct sockaddr *)&addr, sizeof(addr)))
{
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdStartBrowsing: Unable to bind broadcast "
- "socket - %s.", strerror(errno));
+ "Unable to bind broadcast socket - %s.",
+ strerror(errno));
#ifdef WIN32
closesocket(BrowseSocket);
val = 1;
if (setsockopt(BrowseSocket, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
{
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdStartBrowsing: Unable to set broadcast mode - %s.",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to set broadcast mode - %s.",
strerror(errno));
#ifdef WIN32
struct berval bv = {0, ""}; /* SASL bind value */
+ /*
+ * Set the certificate file to use for encrypted LDAP sessions...
+ */
+
+ if (BrowseLDAPCACertFile)
+ {
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "cupsdStartBrowsing: Setting CA certificate file \"%s\"",
+ BrowseLDAPCACertFile);
+
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+ (void *)BrowseLDAPCACertFile))
+ != LDAP_SUCCESS)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to set CA certificate file for LDAP "
+ "connections: %d - %s", rc, ldap_err2string(rc));
+ }
+
/*
* LDAP stuff currently only supports ldapi EXTERNAL SASL binds...
*/
}
#endif /* HAVE_OPENLDAP */
+ /*
+ * Enable LPD and SMB printer sharing as needed through external programs...
+ */
+
+ if (BrowseLocalProtocols & BROWSE_LPD)
+ update_lpd(1);
+
+ if (BrowseLocalProtocols & BROWSE_SMB)
+ update_smb(1);
+
/*
* Register the individual printers
*/
BrowseLDAPHandle = NULL;
}
#endif /* HAVE_OPENLDAP */
+
+ /*
+ * Disable LPD and SMB printer sharing as needed through external programs...
+ */
+
+ if (BrowseLocalProtocols & BROWSE_LPD)
+ update_lpd(0);
+
+ if (BrowseLocalProtocols & BROWSE_SMB)
+ update_smb(0);
}
cups_option_t *attrs) /* I - Attributes */
{
int i; /* Looping var */
- int update; /* Update printer attributes? */
+ int update, /* Update printer attributes? */
+ write_printcap; /* Write the printcap file? */
char finaluri[HTTP_MAX_URI], /* Final URI for printer */
name[IPP_MAX_NAME], /* Name of printer */
newname[IPP_MAX_NAME], /* New name of printer */
* See if we already have it listed in the Printers list, and add it if not...
*/
- type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
- type &= ~CUPS_PRINTER_IMPLICIT;
- update = 0;
- hptr = strchr(host, '.');
- sptr = strchr(ServerName, '.');
+ type |= CUPS_PRINTER_REMOTE | CUPS_PRINTER_DISCOVERED;
+ type &= ~CUPS_PRINTER_IMPLICIT;
+ update = 0;
+ write_printcap = 0;
+ hptr = strchr(host, '.');
+ sptr = strchr(ServerName, '.');
if (!ServerNameIsIP && sptr != NULL && hptr != NULL)
{
cupsdSetString(&p->device_uri, uri);
cupsdSetString(&p->hostname, host);
- update = 1;
+ update = 1;
+ write_printcap = 1;
}
}
else
cupsdSetString(&p->uri, uri);
cupsdSetString(&p->device_uri, uri);
- update = 1;
+ write_printcap = 1;
+ update = 1;
}
}
if (info && (!p->info || strcmp(p->info, info)))
{
cupsdSetString(&p->info, info);
- update = 1;
+ update = 1;
+ write_printcap = 1;
}
if (!make_model || !make_model[0])
cupsdDeletePrinter(p, 1);
cupsdUpdateImplicitClasses();
+ write_printcap = 1;
}
else if (update)
{
if (p->type & CUPS_PRINTER_DEFAULT)
{
DefaultPrinter = p;
+ write_printcap = 1;
break;
}
}
* Do auto-classing if needed...
*/
- process_implicit_classes();
+ process_implicit_classes(&write_printcap);
/*
* Update the printcap file...
*/
- cupsdWritePrintcap();
+ if (write_printcap)
+ cupsdWritePrintcap();
}
*/
static void
-process_implicit_classes(void)
+process_implicit_classes(
+ int *write_printcap) /* O - Write printcap file? */
{
int i; /* Looping var */
int update; /* Update printer attributes? */
update = 1;
+ if (write_printcap)
+ *write_printcap = 1;
+
cupsdLogMessage(CUPSD_LOG_DEBUG, "Added implicit class \"%s\"...",
name);
cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED, p, NULL,
}
+/*
+ * 'update_lpd()' - Update the LPD configuration as needed.
+ */
+
+static void
+update_lpd(int onoff) /* - 1 = turn on, 0 = turn off */
+{
+ if (!LPDConfigFile)
+ return;
+
+ if (!strncmp(LPDConfigFile, "xinetd:///", 10))
+ {
+ /*
+ * Enable/disable LPD via the xinetd.d config file for cups-lpd...
+ */
+
+ char newfile[1024]; /* New cups-lpd.N file */
+ cups_file_t *ofp, /* Original file pointer */
+ *nfp; /* New file pointer */
+ char line[1024]; /* Line from file */
+
+
+ snprintf(newfile, sizeof(newfile), "%s.N", LPDConfigFile + 9);
+
+ if ((ofp = cupsFileOpen(LPDConfigFile + 9, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
+ LPDConfigFile + 9, strerror(errno));
+ return;
+ }
+
+ if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
+ newfile, strerror(errno));
+ cupsFileClose(ofp);
+ return;
+ }
+
+ /*
+ * Copy all of the lines from the cups-lpd file...
+ */
+
+ while (cupsFileGets(ofp, line, sizeof(line)))
+ {
+ if (line[0] == '{')
+ {
+ cupsFilePrintf(nfp, "%s\n", line);
+ snprintf(line, sizeof(line), "\tdisable = %s",
+ onoff ? "no" : "yes");
+ }
+ else if (strstr(line, "disable ="))
+ continue;
+
+ cupsFilePrintf(nfp, "%s\n", line);
+ }
+
+ cupsFileClose(nfp);
+ cupsFileClose(ofp);
+ rename(newfile, LPDConfigFile + 9);
+ }
+ else if (!strncmp(LPDConfigFile, "launchd:///", 11))
+ {
+ /*
+ * Enable/disable LPD via the launchctl command...
+ */
+
+ char *argv[5], /* Arguments for command */
+ *envp[MAX_ENV]; /* Environment for command */
+ int pid; /* Process ID */
+
+
+ cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
+ argv[0] = (char *)"launchctl";
+ argv[1] = (char *)(onoff ? "load" : "unload");
+ argv[2] = (char *)"-w";
+ argv[3] = LPDConfigFile + 10;
+ argv[4] = NULL;
+
+ cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, &pid);
+ }
+}
+
+
/*
* 'update_polling()' - Read status messages from the poll daemons.
*/
/*
- * End of "$Id: dirsvc.c 6590 2007-06-21 18:22:22Z mike $".
+ * 'update_smb()' - Update the SMB configuration as needed.
+ */
+
+static void
+update_smb(int onoff) /* I - 1 = turn on, 0 = turn off */
+{
+ if (!SMBConfigFile)
+ return;
+
+ if (!strncmp(SMBConfigFile, "samba:///", 9))
+ {
+ /*
+ * Enable/disable SMB via the specified smb.conf config file...
+ */
+
+ char newfile[1024]; /* New smb.conf.N file */
+ cups_file_t *ofp, /* Original file pointer */
+ *nfp; /* New file pointer */
+ char line[1024]; /* Line from file */
+ int in_printers; /* In [printers] section? */
+
+
+ snprintf(newfile, sizeof(newfile), "%s.N", SMBConfigFile + 8);
+
+ if ((ofp = cupsFileOpen(SMBConfigFile + 8, "r")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
+ SMBConfigFile + 8, strerror(errno));
+ return;
+ }
+
+ if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
+ newfile, strerror(errno));
+ cupsFileClose(ofp);
+ return;
+ }
+
+ /*
+ * Copy all of the lines from the smb.conf file...
+ */
+
+ in_printers = 0;
+
+ while (cupsFileGets(ofp, line, sizeof(line)))
+ {
+ if (in_printers && strstr(line, "printable ="))
+ snprintf(line, sizeof(line), " printable = %s",
+ onoff ? "yes" : "no");
+
+ cupsFilePrintf(nfp, "%s\n", line);
+
+ if (line[0] == '[')
+ in_printers = !strcmp(line, "[printers]");
+ }
+
+ cupsFileClose(nfp);
+ cupsFileClose(ofp);
+ rename(newfile, SMBConfigFile + 8);
+ }
+ else if (!strncmp(SMBConfigFile, "launchd:///", 11))
+ {
+ /*
+ * Enable/disable SMB via the launchctl command...
+ */
+
+ char *argv[5], /* Arguments for command */
+ *envp[MAX_ENV]; /* Environment for command */
+ int pid; /* Process ID */
+
+
+ cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
+ argv[0] = (char *)"launchctl";
+ argv[1] = (char *)(onoff ? "load" : "unload");
+ argv[2] = (char *)"-w";
+ argv[3] = SMBConfigFile + 10;
+ argv[4] = NULL;
+
+ cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1, &pid);
+ }
+}
+
+
+/*
+ * End of "$Id: dirsvc.c 7003 2007-10-01 23:10:13Z mike $".
*/