summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-01-05 16:20:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:46 -0500
commitd097ea490525e7a35739dae6a295fd03ba52cfc0 (patch)
tree131dc7af2e2e944283c70d255d8ad5d6bbef0726
parent846b8d4cfdee815cd22d7e00b7f120668f9758a9 (diff)
downloadsamba-d097ea490525e7a35739dae6a295fd03ba52cfc0.tar.gz
samba-d097ea490525e7a35739dae6a295fd03ba52cfc0.tar.bz2
samba-d097ea490525e7a35739dae6a295fd03ba52cfc0.zip
r4539: patch from Rob -- adding real printcap name cache function to speed up printcap reloads
(This used to be commit 1cad5250932b963c2eb9b775221b13db386d601b)
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/printing/load.c48
-rw-r--r--source3/printing/nt_printing.c22
-rw-r--r--source3/printing/pcap.c468
-rw-r--r--source3/printing/print_aix.c111
-rw-r--r--source3/printing/print_cups.c123
-rw-r--r--source3/printing/print_svid.c69
-rw-r--r--source3/printing/printing.c2
-rw-r--r--source3/smbd/process.c15
-rw-r--r--source3/smbd/server.c36
-rw-r--r--source3/smbd/service.c37
-rw-r--r--source3/utils/testprns.c18
12 files changed, 385 insertions, 566 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index a6e434464f..79579b21c1 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -397,7 +397,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
$(BUILDOPT_OBJ) $(SMBLDAP_OBJ)
-PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
+PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
printing/print_cups.o printing/print_generic.o \
printing/lpq_parse.o printing/load.o
diff --git a/source3/printing/load.c b/source3/printing/load.c
index 59306aa104..a925a63e17 100644
--- a/source3/printing/load.c
+++ b/source3/printing/load.c
@@ -22,44 +22,29 @@
/***************************************************************************
-auto-load printer services
-***************************************************************************/
-void add_all_printers(void)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) return;
-
- pcap_printer_fn(lp_add_one_printer);
-}
-
-/***************************************************************************
auto-load some homes and printer services
***************************************************************************/
static void add_auto_printers(void)
{
const char *p;
- int printers;
- char *str = SMB_STRDUP(lp_auto_services());
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ char *str;
- if (!str) return;
-
- printers = lp_servicenumber(PRINTERS_NAME);
+ if (pnum < 0)
+ return;
- if (printers < 0) {
- SAFE_FREE(str);
+ if ((str = SMB_STRDUP(lp_auto_services())) == NULL)
return;
- }
-
- for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
- if (lp_servicenumber(p) >= 0) continue;
+
+ for (p = strtok(str, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
+ if (lp_servicenumber(p) >= 0)
+ continue;
- if (pcap_printername_ok(p,NULL)) {
- lp_add_printer(p,printers);
- }
+ if (pcap_printername_ok(p))
+ lp_add_printer(p, pnum);
}
- SAFE_FREE(str);
+ SAFE_FREE(str);
}
/***************************************************************************
@@ -67,7 +52,12 @@ load automatic printer services
***************************************************************************/
void load_printers(void)
{
+ if (!pcap_cache_loaded())
+ pcap_cache_reload();
+
add_auto_printers();
- if (lp_load_printers())
- add_all_printers();
+
+ /* load all printcap printers */
+ if (lp_load_printers() && lp_servicenumber(PRINTERS_NAME) >= 0)
+ pcap_printer_fn(lp_add_one_printer);
}
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 3ffedcf185..a72f63009a 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -2046,17 +2046,32 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
handles are not affected.
****************************************************************************/
-uint32 del_a_printer(char *sharename)
+uint32 del_a_printer(const char *sharename)
{
pstring key;
TDB_DATA kbuf;
+ pstring printdb_path;
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
-
kbuf.dptr=key;
kbuf.dsize=strlen(key)+1;
+ tdb_delete(tdb_printers, kbuf);
+ slprintf(key, sizeof(key)-1, "%s%s", SECDESC_PREFIX, sharename);
+ kbuf.dptr=key;
+ kbuf.dsize=strlen(key)+1;
tdb_delete(tdb_printers, kbuf);
+
+ close_all_print_db();
+
+ if (geteuid() == 0) {
+ pstrcpy(printdb_path, lock_path("printing/"));
+ pstrcat(printdb_path, sharename);
+ pstrcat(printdb_path, ".tdb");
+
+ unlink(printdb_path);
+ }
+
return 0;
}
@@ -2899,7 +2914,8 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
return False;
}
- if (regval_size(guid_val) == sizeof(struct uuid))
+ /* fetching printer guids really ought to be a separate function.. */
+ if (guid && regval_size(guid_val) == sizeof(struct uuid))
memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
free_a_printer(&printer, 2);
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c
index a5fb53a320..0495b6fc1f 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -27,10 +27,8 @@
*/
/*
- * Parse printcap file.
- *
- * This module does exactly one thing - it looks into the printcap file
- * and tells callers if a specified string appears as a printer name.
+ * This module contains code to parse and cache printcap data, possibly
+ * in concert with the CUPS/SYSV/AIX-specific code found elsewhere.
*
* The way this module looks at the printcap file is very simplistic.
* Only the local printcap file is inspected (no searching of NIS
@@ -62,352 +60,194 @@
#include "includes.h"
-#ifdef AIX
-/* ******************************************
- Extend for AIX system and qconfig file
- from 'boulard@univ-rennes1.fr
- ****************************************** */
-static int strlocate(char *xpLine,char *xpS)
+
+typedef struct pcap_cache {
+ char *name;
+ char *comment;
+ struct pcap_cache *next;
+} pcap_cache_t;
+
+static pcap_cache_t *pcap_cache = NULL;
+
+BOOL pcap_cache_add(const char *name, const char *comment)
{
- int iS,iL,iRet;
- char *p;
- iS = strlen(xpS);
- iL = strlen(xpLine);
-
- iRet = 0;
- p = xpLine;
- while (iL >= iS)
- {
- if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
- p++;
- iL--;
- }
- /*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
-
- return(iRet);
+ pcap_cache_t *p;
+
+ if (name == NULL || ((p = SMB_MALLOC_P(pcap_cache_t)) == NULL))
+ return False;
+
+ p->name = SMB_STRDUP(name);
+ p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
+
+ p->next = pcap_cache;
+ pcap_cache = p;
+
+ return True;
}
-
-
-/* ******************************************************************* */
-/* * Scan qconfig and search all virtual printer (device printer) * */
-/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
+
+static void pcap_cache_destroy(pcap_cache_t *cache)
{
- int iEtat;
- XFILE *pfile;
- char *line,*p;
- pstring name,comment;
- line = NULL;
- *name = 0;
- *comment = 0;
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- return;
- }
+ pcap_cache_t *p, *next;
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr_m(line,':')))
- {
- *p = '\0';
- p = strtok(line,":");
- if (strcmp(p,"bsh")!=0)
- {
- pstrcpy(name,p);
- iEtat = 1;
- continue;
- }
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
- break;
- }
+ for (p = cache; p != NULL; p = next) {
+ next = p->next;
+
+ SAFE_FREE(p->name);
+ SAFE_FREE(p->comment);
+ SAFE_FREE(p);
}
- x_fclose(pfile);
}
-/* Scan qconfig file and locate de printername */
-
-static BOOL ScanQconfig(char *psz,char *pszPrintername)
+BOOL pcap_cache_loaded(void)
{
- int iLg,iEtat;
- XFILE *pfile;
- char *pName;
- char *line;
-
- pName = NULL;
- line = NULL;
- if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
- pName = malloc(iLg+10);
- if (pName == NULL)
- {
- DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
- return(False);
- }
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- SAFE_FREE(pName);
- return(False);
- }
- slprintf(pName, iLg + 9, "%s:",pszPrintername);
- iLg = strlen(pName);
- /*DEBUG(3,( " Looking for entry %s\n",pName));*/
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* scanning entry */
- if (strncmp(line,pName,iLg) == 0)
- {
- iEtat = 1;
- continue;
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- free (line);
- SAFE_FREE(pName);
- x_fclose(pfile);
- return(True);
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- free (line);
- SAFE_FREE(pName);
- x_fclose(pfile);
- return(True);
- }
- break;
- }
- }
- free (pName);
- x_fclose(pfile);
- return(False);
+ return (pcap_cache != NULL);
}
-#endif /* AIX */
-
-/***************************************************************************
-Scan printcap file pszPrintcapname for a printer called pszPrintername.
-Return True if found, else False. Returns False on error, too, after logging
-the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
-***************************************************************************/
-BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
+void pcap_cache_reload(void)
{
- char *line=NULL;
- const char *psz;
- char *p,*q;
- XFILE *pfile;
-
- if (pszPrintername == NULL || pszPrintername[0] == '\0')
- {
- DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
- return(False);
- }
-
- /* only go looking if no printcap name supplied */
- if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return(False);
- }
+ const char *pcap_name = lp_printcapname();
+ BOOL pcap_reloaded = False;
+ pcap_cache_t *tmp_cache = NULL;
+ XFILE *pcap_file;
+ char *pcap_line;
+
+ DEBUG(3, ("reloading printcap cache\n"));
+
+ /* only go looking if no printcap name supplied */
+ if (pcap_name == NULL || *pcap_name == 0) {
+ DEBUG(0, ("No printcap file name configured!\n"));
+ return;
+ }
+
+ tmp_cache = pcap_cache;
+ pcap_cache = NULL;
#ifdef HAVE_CUPS
- if (strequal(psz, "cups"))
- return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_CUPS */
+ if (strequal(pcap_name, "cups")) {
+ pcap_reloaded = cups_cache_reload();
+ goto done;
+ }
+#endif
#ifdef SYSV
- if (strequal(psz, "lpstat"))
- return (sysv_printername_ok(pszPrintername));
+ if (strequal(pcap_name, "lpstat")) {
+ pcap_reloaded = sysv_cache_reload();
+ goto done;
+ }
#endif
#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- return(ScanQconfig(psz,pszPrintername));
+ if (strstr_m(pcap_name, "/qconfig") != NULL) {
+ pcap_reloaded = aix_cache_reload();
+ goto done;
+ }
#endif
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return(False);
- }
+ /* handle standard printcap - moved from pcap_printer_fn() */
+
+ if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
+ DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
+ goto done;
+ }
+
+ for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) {
+ pstring name, comment;
+ char *p, *q;
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
+ if (*pcap_line == '#' || *pcap_line == 0)
+ continue;
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
+ /* now we have a real printer line - cut at the first : */
+ if ((p = strchr_m(pcap_line, ':')) != NULL)
+ *p = 0;
- /* now just check if the name is in the list */
- /* NOTE: I avoid strtok as the fn calling this one may be using it */
- for (p=line; p; p=q)
- {
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- if (strequal(p,pszPrintername))
- {
- SAFE_FREE(line);
- x_fclose(pfile);
- return(True);
- }
- p = q;
+ /*
+ * now find the most likely printer name and comment
+ * this is pure guesswork, but it's better than nothing
+ */
+ for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) {
+ BOOL has_punctuation;
+
+ if ((q = strchr_m(p, '|')) != NULL)
+ *q++ = 0;
+
+ has_punctuation = (strchr_m(p, ' ') ||
+ strchr_m(p, '\t') ||
+ strchr_m(p, '(') ||
+ strchr_m(p, ')'));
+
+ if (strlen(p) > strlen(comment) && has_punctuation) {
+ pstrcpy(comment, p);
+ continue;
+ }
+
+ if (strlen(p) <= MAXPRINTERLEN &&
+ strlen(p) > strlen(name) && !has_punctuation) {
+ if (!*comment)
+ pstrcpy(comment, name);
+
+ pstrcpy(name, p);
+ continue;
+ }
+
+ if (!strchr_m(comment, ' ') &&
+ strlen(p) > strlen(comment)) {
+ pstrcpy(comment, p);
+ continue;
+ }
+ }
+
+ comment[60] = 0;
+ name[MAXPRINTERLEN] = 0;
+
+ if (*name && !pcap_cache_add(name, comment)) {
+ x_fclose(pcap_file);
+ goto done;
+ }
}
- }
- x_fclose(pfile);
- return(False);
+ x_fclose(pcap_file);
+ pcap_reloaded = True;
+
+done:
+ DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
+
+ if (pcap_reloaded)
+ pcap_cache_destroy(tmp_cache);
+ else {
+ pcap_cache_destroy(pcap_cache);
+ pcap_cache = tmp_cache;
+ }
+
+ return;
}
+BOOL pcap_printername_ok(const char *printername)
+{
+ pcap_cache_t *p;
+
+ for (p = pcap_cache; p != NULL; p = p->next)
+ if (strequal(p->name, printername))
+ return True;
+
+ return False;
+}
+
/***************************************************************************
run a function on each printer name in the printcap file. The function is
passed the primary name and the comment (if possible). Note the fn() takes
strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
to return DOS codepage. FIXME !! JRA.
+
+XXX: I'm not sure if this comment still applies.. Anyone? -Rob
***************************************************************************/
void pcap_printer_fn(void (*fn)(char *, char *))
{
- pstring name,comment;
- char *line;
- char *psz;
- char *p,*q;
- XFILE *pfile;
-
- /* only go looking if no printcap name supplied */
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return;
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups")) {
- cups_printer_fn(fn);
- return;
- }
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat")) {
- sysv_printer_fn(fn);
- return;
- }
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- {
- ScanQconfig_fn(psz,fn);
- return;
- }
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return;
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now find the most likely printer name and comment
- this is pure guesswork, but it's better than nothing */
- *name = 0;
- *comment = 0;
- for (p=line; p; p=q)
- {
- BOOL has_punctuation;
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
-
- if (strlen(p)>strlen(comment) && has_punctuation)
- {
- pstrcpy(comment,p);
- continue;
- }
-
- if (strlen(p) <= MAXPRINTERLEN && strlen(p)>strlen(name) && !has_punctuation)
- {
- if (!*comment) pstrcpy(comment,name);
- pstrcpy(name,p);
- continue;
- }
-
- if (!strchr_m(comment,' ') &&
- strlen(p) > strlen(comment))
- {
- pstrcpy(comment,p);
- continue;
- }
- }
+ pcap_cache_t *p;
- comment[60] = 0;
- name[MAXPRINTERLEN] = 0;
+ for (p = pcap_cache; p != NULL; p = p->next)
+ fn(p->name, p->comment);
- if (*name)
- fn(name,comment);
- }
- x_fclose(pfile);
+ return;
}
diff --git a/source3/printing/print_aix.c b/source3/printing/print_aix.c
new file mode 100644
index 0000000000..6ed3510ee4
--- /dev/null
+++ b/source3/printing/print_aix.c
@@ -0,0 +1,111 @@
+/*
+ AIX-specific printcap loading
+ Copyright (C) Jean-Pierre.Boulard@univ-rennes1.fr 1996
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 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.
+*/
+
+/*
+ * This module implements AIX-specific printcap loading. Most of the code
+ * here was originally provided by Jean-Pierre.Boulard@univ-rennes1.fr in
+ * the Samba 1.9.14 release, and was formerly contained in pcap.c. It has
+ * been moved here and condensed as part of a larger effort to clean up and
+ * simplify the printcap code. -- Rob Foehl, 2004/12/06
+ */
+
+#include "includes.h"
+
+#ifdef AIX
+BOOL aix_cache_reload(void)
+{
+ int iEtat;
+ XFILE *pfile;
+ char *line = NULL, *p;
+ pstring name, comment;
+
+ *name = 0;
+ *comment = 0;
+
+ DEBUG(5, ("reloading aix printcap cache\n"));
+
+ if ((pfile = x_fopen(lp_printcapname(), O_RDONLY, 0)) == NULL) {
+ DEBUG(0,( "Unable to open qconfig file %s for read!\n", lp_printcapname()));
+ return False;
+ }
+
+ iEtat = 0;
+ /* scan qconfig file for searching <printername>: */
+ for (;(line = fgets_slash(NULL, sizeof(pstring), pfile)); safe_free(line)) {
+ if (*line == '*' || *line == 0)
+ continue;
+
+ switch (iEtat) {
+ case 0: /* locate an entry */
+ if (*line == '\t' || *line == ' ')
+ continue;
+
+ if ((p = strchr_m(line, ':'))) {
+ *p = '\0';
+ p = strtok(line, ":");
+ if (strcmp(p, "bsh") != 0) {
+ pstrcpy(name, p);
+ iEtat = 1;
+ continue;
+ }
+ }
+ break;
+
+ case 1: /* scanning device stanza */
+ if (*line == '*' || *line == 0)
+ continue;
+
+ if (*line != '\t' && *line != ' ') {
+ /* name is found without stanza device */
+ /* probably a good printer ??? */
+ iEtat = 0;
+ if (!pcap_cache_add(name, NULL)) {
+ safe_free(line);
+ x_fclose(pfile);
+ return False;
+ }
+ continue;
+ }
+
+ if (strstr_m(line, "backend")) {
+ /* it's a device, not a virtual printer */
+ iEtat = 0;
+ } else if (strstr_m(line, "device")) {
+ /* it's a good virtual printer */
+ iEtat = 0;
+ if (!pcap_cache_add(name, NULL)) {
+ safe_free(line);
+ x_fclose(pfile);
+ return False;
+ }
+ continue;
+ }
+ break;
+ }
+ }
+
+ x_fclose(pfile);
+ return True;
+}
+
+#else
+/* this keeps fussy compilers happy */
+ void print_aix_dummy(void);
+ void print_aix_dummy(void) {}
+#endif /* AIX */
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 5cc36d6e17..862d60a279 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -52,14 +52,8 @@ static const char *cups_server(void)
return cupsServer();
}
-/*
- * 'cups_printer_fn()' - Call a function for every printer known to the
- * system.
- */
-
-void cups_printer_fn(void (*fn)(char *, char *))
+BOOL cups_cache_reload(void)
{
- /* I - Function to call */
http_t *http; /* HTTP connection to server */
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
@@ -74,7 +68,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
};
- DEBUG(5,("cups_printer_fn(%p)\n", fn));
+ DEBUG(5, ("reloading cups printcap cache\n"));
/*
* Make sure we don't ask for passwords...
@@ -90,7 +84,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
{
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
cups_server(), strerror(errno)));
- return;
+ return False;
}
/*
@@ -129,7 +123,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
DEBUG(0,("Unable to get printer list - %s\n",
ippErrorString(cupsLastError())));
httpClose(http);
- return;
+ return False;
}
for (attr = response->attrs; attr != NULL;)
@@ -171,7 +165,11 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- (*fn)(name, info);
+ if (!pcap_cache_add(name, info)) {
+ ippDelete(response);
+ httpClose(http);
+ return False;
+ }
}
ippDelete(response);
@@ -213,7 +211,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
DEBUG(0,("Unable to get printer list - %s\n",
ippErrorString(cupsLastError())));
httpClose(http);
- return;
+ return False;
}
for (attr = response->attrs; attr != NULL;)
@@ -255,7 +253,11 @@ void cups_printer_fn(void (*fn)(char *, char *))
if (name == NULL)
break;
- (*fn)(name, info);
+ if (!pcap_cache_add(name, info)) {
+ ippDelete(response);
+ httpClose(http);
+ return False;
+ }
}
ippDelete(response);
@@ -265,100 +267,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
*/
httpClose(http);
-}
-
-
-/*
- * 'cups_printername_ok()' - Provide the equivalent of pcap_printername_ok()
- * for CUPS.
- * O - 1 if printer name OK
- * I - Name of printer
- */
-int cups_printername_ok(const char *name)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_printername_ok(\"%s\")\n", name));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cups_server(), ippPort())) == NULL)
- {
- DEBUG(3,("Unable to connect to CUPS server %s - %s\n",
- cups_server(), strerror(errno)));
- return (0);
- }
-
- /*
- * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes", NULL, "printer-uri");
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", name);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
- }
-
- httpClose(http);
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- return (0);
- }
- else
- {
- ippDelete(response);
- return (1);
- }
+ return True;
}
diff --git a/source3/printing/print_svid.c b/source3/printing/print_svid.c
index d9db500425..3a7c935634 100644
--- a/source3/printing/print_svid.c
+++ b/source3/printing/print_svid.c
@@ -35,23 +35,17 @@
#include "includes.h"
#ifdef SYSV
-
-typedef struct printer {
- char *name;
- struct printer *next;
-} printer_t;
-static printer_t *printers = NULL;
-
-static void populate_printers(void)
+BOOL sysv_cache_reload(void)
{
char **lines;
int i;
- lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
- if (!lines) return;
+ DEBUG(5, ("reloading sysv printcap cache\n"));
- for (i=0;lines[i];i++) {
- printer_t *ptmp;
+ if ((lines = file_lines_pload("/usr/bin/lpstat -v", NULL)) == NULL)
+ return False;
+
+ for (i = 0; lines[i]; i++) {
char *name, *tmp;
char *buf = lines[i];
@@ -64,7 +58,7 @@ static void populate_printers(void)
* In case we're only at the "for ".
*/
- if(!strncmp("for ",++tmp,4)) {
+ if(!strncmp("for ", ++tmp, 4)) {
tmp=strchr_m(tmp, ' ');
tmp++;
}
@@ -78,7 +72,7 @@ static void populate_printers(void)
* On HPUX there is an extra line that can be ignored.
* d.thibadeau 2001/08/09
*/
- if(!strncmp("remote to",tmp,9))
+ if(!strncmp("remote to", tmp, 9))
continue;
name = tmp;
@@ -88,53 +82,14 @@ static void populate_printers(void)
*tmp = '\0';
/* add it to the cache */
- if ((ptmp = SMB_MALLOC_P(printer_t)) != NULL) {
- ZERO_STRUCTP(ptmp);
- if((ptmp->name = SMB_STRDUP(name)) == NULL)
- DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
- ptmp->next = printers;
- printers = ptmp;
- } else {
- DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
+ if (!pcap_cache_add(name, NULL)) {
+ file_lines_free(lines);
+ return False;
}
}
file_lines_free(lines);
-}
-
-
-/*
- * provide the equivalent of pcap_printer_fn() for SVID/XPG4 conforming
- * systems. It was unclear why pcap_printer_fn() was tossing names longer
- * than 8 characters. I suspect that its a protocol limit, but amazingly
- * names longer than 8 characters appear to work with my test
- * clients (Win95/NT).
- */
-void sysv_printer_fn(void (*fn)(char *, char *))
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- (fn)(tmp->name, "");
-}
-
-
-/*
- * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
- * systems.
- */
-int sysv_printername_ok(const char *name)
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- if (strcmp(tmp->name, name) == 0)
- return (True);
- return (False);
+ return True;
}
#else
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index b5785440ae..67b9b9f22a 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -2247,7 +2247,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
}
/* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
+ if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
release_print_db(pdb);
errno = ENOENT;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 1372ebbf45..54837c3b9a 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1282,7 +1282,7 @@ static int setup_select_timeout(void)
void check_reload(int t)
{
static time_t last_smb_conf_reload_time = 0;
- static time_t last_load_printers_reload_time = 0;
+ static time_t last_printer_reload_time = 0;
time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
if(last_smb_conf_reload_time == 0) {
@@ -1291,9 +1291,9 @@ void check_reload(int t)
Then no printer is available till the first printers check
is performed. A lower initial interval circumvents this. */
if ( printcap_cache_time > 60 )
- last_load_printers_reload_time = t - printcap_cache_time + 60;
+ last_printer_reload_time = t - printcap_cache_time + 60;
else
- last_load_printers_reload_time = t;
+ last_printer_reload_time = t;
}
if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
@@ -1308,13 +1308,12 @@ void check_reload(int t)
{
/* see if it's time to reload or if the clock has been set back */
- if ( (t >= last_load_printers_reload_time+printcap_cache_time)
- || (t-last_load_printers_reload_time < 0) )
+ if ( (t >= last_printer_reload_time+printcap_cache_time)
+ || (t-last_printer_reload_time < 0) )
{
DEBUG( 3,( "Printcap cache time expired.\n"));
- remove_stale_printers();
- load_printers();
- last_load_printers_reload_time = t;
+ reload_printers();
+ last_printer_reload_time = t;
}
}
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 724a49321a..7f7d55c7e3 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -464,6 +464,39 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
}
/****************************************************************************
+ Reload printers
+**************************************************************************/
+void reload_printers(void)
+{
+ int snum;
+ int n_services = lp_numservices();
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ const char *pname;
+
+ pcap_cache_reload();
+
+ /* remove stale printers */
+ for (snum = 0; snum < n_services; snum++) {
+ /* avoid removing PRINTERS_NAME or non-autoloaded printers */
+ if (snum == pnum || !(lp_snum_ok(snum) && lp_print_ok(snum) &&
+ lp_autoloaded(snum)))
+ continue;
+
+ pname = lp_printername(snum);
+ if (!pcap_printername_ok(pname)) {
+ DEBUG(3, ("removing stale printer %s\n", pname));
+
+ if (is_printer_published(NULL, snum, NULL))
+ nt_printer_publish(NULL, snum, SPOOL_DS_UNPUBLISH);
+ del_a_printer(pname);
+ lp_killservice(snum);
+ }
+ }
+
+ load_printers();
+}
+
+/****************************************************************************
Reload the services file.
**************************************************************************/
@@ -490,8 +523,7 @@ BOOL reload_services(BOOL test)
ret = lp_load(dyn_CONFIGFILE, False, False, True);
- remove_stale_printers();
- load_printers();
+ reload_printers();
/* perhaps the config filename is now set */
if (!test)
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 3dcd803a7c..2e60adc636 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -152,10 +152,8 @@ int find_service(fstring service)
int iPrinterService;
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
- const char *pszTemp = lp_printcapname();
-
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp)) {
+ if (pcap_printername_ok(service)) {
DEBUG(3,("%s is a valid printer name\n", service));
DEBUG(3,("adding %s as a printer service\n", service));
lp_add_printer(service, iPrinterService);
@@ -863,36 +861,3 @@ void close_cnum(connection_struct *conn, uint16 vuid)
conn_free(conn);
}
-
-/****************************************************************************
- Remove stale printers
-****************************************************************************/
-
-void remove_stale_printers( void )
-{
- int snum, iNumServices, printersServiceNum;
- const char *pname;
-
- iNumServices = lp_numservices();
- printersServiceNum = lp_servicenumber( PRINTERS_NAME);
- for( snum = 0; snum < iNumServices; snum++) {
-
- /* Never remove PRINTERS_NAME */
-
- if ( snum == printersServiceNum)
- continue;
- pname = lp_printername( snum);
-
- /* Is snum an autoloaded print service and still
- in the printing subsystem? */
-
- if ( lp_snum_ok(snum)
- && lp_print_ok(snum)
- && lp_autoloaded(snum)
- && !pcap_printername_ok( pname, NULL))
- {
- DEBUG( 3, ( "Removing printer: %s\n", pname));
- lp_killservice( snum);
- }
- }
-}
diff --git a/source3/utils/testprns.c b/source3/utils/testprns.c
index 7e52b86afb..1525ab11d0 100644
--- a/source3/utils/testprns.c
+++ b/source3/utils/testprns.c
@@ -32,14 +32,17 @@
#include "includes.h"
+/*
+ * NOTE: this code is likely to be removed, and no longer supports
+ * checking against non-configured printcap files. -Rob
+ */
+
int main(int argc, char *argv[])
{
- const char *pszTemp;
-
setup_logging(argv[0],True);
- if (argc < 2 || argc > 3)
- printf("Usage: testprns printername [printcapfile]\n");
+ if (argc != 2)
+ printf("Usage: testprns printername\n");
else
{
dbf = x_fopen("test.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
@@ -47,10 +50,9 @@ int main(int argc, char *argv[])
printf("Unable to open logfile.\n");
} else {
DEBUGLEVEL = 3;
- pszTemp = (argc < 3) ? PRINTCAP_NAME : argv[2];
- printf("Looking for printer %s in printcap file %s\n",
- argv[1], pszTemp);
- if (!pcap_printername_ok(argv[1], pszTemp))
+ printf("Looking for printer %s\n", argv[1]);
+ load_printers();
+ if (!pcap_printername_ok(argv[1]))
printf("Printer name %s is not valid.\n", argv[1]);
else
printf("Printer name %s is valid.\n", argv[1]);