r4539: patch from Rob -- adding real printcap name cache function to speed up printca...
authorGerald Carter <jerry@samba.org>
Wed, 5 Jan 2005 16:20:35 +0000 (16:20 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:46 +0000 (10:53 -0500)
(This used to be commit 1cad5250932b963c2eb9b775221b13db386d601b)

12 files changed:
source3/Makefile.in
source3/printing/load.c
source3/printing/nt_printing.c
source3/printing/pcap.c
source3/printing/print_aix.c [new file with mode: 0644]
source3/printing/print_cups.c
source3/printing/print_svid.c
source3/printing/printing.c
source3/smbd/process.c
source3/smbd/server.c
source3/smbd/service.c
source3/utils/testprns.c

index a6e434464feb0e488b23f5809415b275760dc04b..79579b21c12d8fc3db5624de36e668864f4b4ee6 100644 (file)
@@ -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
 
index 59306aa1047d3bc9853d3f993508a9a212a1b796..a925a63e17f5a1b214c14b51ba712e1d45c9fb4d 100644 (file)
 #include "includes.h"
 
 
-/***************************************************************************
-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);
 }
index 3ffedcf1858cebf7f1909aac43cee9c4e0f461e2..a72f63009a4d05051c90407ea6e3bc27ff1d591f 100644 (file)
@@ -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);
index a5fb53a320dca01f7f180d3a93b95f9f4d873f85..0495b6fc1fc2e71d10f4a42699b8b3d4a8744705 100644 (file)
 */
 
 /*
- *  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
 
 #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 (file)
index 0000000..6ed3510
--- /dev/null
@@ -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 */
index 5cc36d6e170284a575efc1a2de9637dfae28edca..862d60a279bdf89739fa2cfa392788b43eaad78c 100644 (file)
@@ -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;
 }
 
 
index d9db500425e5c1fe6ef67450d7930e531558d710..3a7c9356344b3844ab35adab672841aa690f2b56 100644 (file)
 #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
index b5785440aeb7020ac118847d4cc0f73d1eceec92..67b9b9f22ab698fa102c56c5f3a7ec270a706f9c 100644 (file)
@@ -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;
index 1372ebbf458b6101bc659f20c00b4cbc515260ed..54837c3b9ae8aa43af6250e294e745962d438d99 100644 (file)
@@ -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;
                }
        }
 }
index 724a49321a27bf5b544e939b3566577887ff2bd2..7f7d55c7e3a027e70c57ea34072273708441fe1f 100644 (file)
@@ -463,6 +463,39 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
 /* NOTREACHED  return True; */
 }
 
+/****************************************************************************
+ 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)
index 3dcd803a7ce6aa632decc444f3d65c15b7d042c3..2e60adc63663d2454afc72e7c1ec6094c3096ef1 100644 (file)
@@ -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);
-               }
-       }
-}
index 7e52b86afb6979bd731ebc177d98fbca1e9767c0..1525ab11d0f0338509c6767a84ca47d547a1fe22 100644 (file)
 
 #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]);