LCOV - code coverage report
Current view: top level - source3/printing - pcap.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 31 73 42.5 %
Date: 2024-04-13 12:30:31 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    printcap parsing
       4             :    Copyright (C) Karl Auer 1993-1998
       5             : 
       6             :    Re-working by Martin Kiff, 1994
       7             :    
       8             :    Re-written again by Andrew Tridgell
       9             : 
      10             :    Modified for SVID support by Norm Jacobs, 1997
      11             : 
      12             :    Modified for CUPS support by Michael Sweet, 1999
      13             :    
      14             :    This program is free software; you can redistribute it and/or modify
      15             :    it under the terms of the GNU General Public License as published by
      16             :    the Free Software Foundation; either version 3 of the License, or
      17             :    (at your option) any later version.
      18             :    
      19             :    This program is distributed in the hope that it will be useful,
      20             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      21             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      22             :    GNU General Public License for more details.
      23             :    
      24             :    You should have received a copy of the GNU General Public License
      25             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      26             : */
      27             : 
      28             : /*
      29             :  *  Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
      30             :  *  in smb.conf under Solaris.
      31             :  *
      32             :  *  Modified to call CUPS support if printcap name is set to "cups"
      33             :  *  in smb.conf.
      34             :  *
      35             :  *  Modified to call iPrint support if printcap name is set to "iprint"
      36             :  *  in smb.conf.
      37             :  */
      38             : 
      39             : #include "includes.h"
      40             : #include "printing/pcap.h"
      41             : #include "printer_list.h"
      42             : 
      43             : struct pcap_cache {
      44             :         char *name;
      45             :         char *comment;
      46             :         char *location;
      47             :         struct pcap_cache *next;
      48             : };
      49             : 
      50           0 : bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location)
      51             : {
      52           0 :         struct pcap_cache *p;
      53             : 
      54           0 :         if (name == NULL || ((p = SMB_MALLOC_P(struct pcap_cache)) == NULL))
      55           0 :                 return false;
      56             : 
      57           0 :         p->name = SMB_STRDUP(name);
      58           0 :         p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
      59           0 :         p->location = (location && *location) ? SMB_STRDUP(location) : NULL;
      60             : 
      61           0 :         DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s\n",
      62             :                 p->name, p->comment ? p->comment : "",
      63             :                 p->location ? p->location : ""));
      64             : 
      65           0 :         p->next = *ppcache;
      66           0 :         *ppcache = p;
      67             : 
      68           0 :         return true;
      69             : }
      70             : 
      71         120 : void pcap_cache_destroy_specific(struct pcap_cache **pp_cache)
      72             : {
      73           0 :         struct pcap_cache *p, *next;
      74             : 
      75         120 :         for (p = *pp_cache; p != NULL; p = next) {
      76           0 :                 next = p->next;
      77             : 
      78           0 :                 SAFE_FREE(p->name);
      79           0 :                 SAFE_FREE(p->comment);
      80           0 :                 SAFE_FREE(p->location);
      81           0 :                 SAFE_FREE(p);
      82             :         }
      83         120 :         *pp_cache = NULL;
      84         120 : }
      85             : 
      86         120 : bool pcap_cache_replace(const struct pcap_cache *pcache)
      87             : {
      88           0 :         const struct pcap_cache *p;
      89           0 :         NTSTATUS status;
      90         120 :         time_t t = time_mono(NULL);
      91             : 
      92         120 :         status = printer_list_mark_reload();
      93         120 :         if (!NT_STATUS_IS_OK(status)) {
      94           0 :                 DEBUG(0, ("Failed to mark printer list for reload!\n"));
      95           0 :                 return false;
      96             :         }
      97             : 
      98         120 :         for (p = pcache; p; p = p->next) {
      99           0 :                 status = printer_list_set_printer(talloc_tos(), p->name,
     100           0 :                                                   p->comment, p->location, t);
     101           0 :                 if (!NT_STATUS_IS_OK(status)) {
     102           0 :                         return false;
     103             :                 }
     104             :         }
     105             : 
     106         120 :         status = printer_list_clean_old();
     107         120 :         if (!NT_STATUS_IS_OK(status)) {
     108           0 :                 DEBUG(0, ("Failed to cleanup printer list!\n"));
     109           0 :                 return false;
     110             :         }
     111             : 
     112         120 :         return true;
     113             : }
     114             : 
     115         120 : void pcap_cache_reload(struct tevent_context *ev,
     116             :                        struct messaging_context *msg_ctx,
     117             :                        void (*post_cache_fill_fn)(struct tevent_context *,
     118             :                                                   struct messaging_context *))
     119             : {
     120         120 :         const char *pcap_name = lp_printcapname();
     121         120 :         bool pcap_reloaded = False;
     122         120 :         bool post_cache_fill_fn_handled = false;
     123         120 :         struct pcap_cache *pcache = NULL;
     124             : 
     125         120 :         DEBUG(3, ("reloading printcap cache\n"));
     126             : 
     127         120 :         if (!lp_load_printers()) {
     128           0 :                 DBG_NOTICE("skipping reload - load printers disabled\n");
     129           0 :                 return;
     130             :         }
     131             : 
     132             :         /* only go looking if a printcap name is supplied */
     133         120 :         if (pcap_name == NULL || *pcap_name == 0) {
     134           0 :                 DEBUG(0, ("No printcap file name configured!\n"));
     135           0 :                 return;
     136             :         }
     137             : 
     138             : #ifdef HAVE_CUPS
     139         120 :         if (strequal(pcap_name, "cups")) {
     140           0 :                 pcap_reloaded = cups_cache_reload(ev, msg_ctx,
     141             :                                                   post_cache_fill_fn);
     142             :                 /*
     143             :                  * cups_cache_reload() is async and calls post_cache_fill_fn()
     144             :                  * on successful completion
     145             :                  */
     146           0 :                 post_cache_fill_fn_handled = true;
     147           0 :                 goto done;
     148             :         }
     149             : #endif
     150             : 
     151             : #ifdef HAVE_IPRINT
     152         120 :         if (strequal(pcap_name, "iprint")) {
     153           0 :                 pcap_reloaded = iprint_cache_reload(&pcache);
     154           0 :                 goto done;
     155             :         }
     156             : #endif
     157             : 
     158             : #if defined(SYSV) || defined(HPUX)
     159             :         if (strequal(pcap_name, "lpstat")) {
     160             :                 pcap_reloaded = sysv_cache_reload(&pcache);
     161             :                 goto done;
     162             :         }
     163             : #endif
     164             : 
     165             : #ifdef AIX
     166             :         if (strstr_m(pcap_name, "/qconfig") != NULL) {
     167             :                 pcap_reloaded = aix_cache_reload(&pcache);
     168             :                 goto done;
     169             :         }
     170             : #endif
     171             : 
     172         120 :         pcap_reloaded = std_pcap_cache_reload(pcap_name, &pcache);
     173             : 
     174             : /* Fix silly compiler warning about done not being used if none of the above
     175             :  * ifdefs are used */
     176             : #if defined(HAVE_CUPS) || defined(HAVE_IPRINT) || defined(SYSV) || defined(HPUX) || defined(AIX)
     177         120 : done:
     178             : #endif
     179         120 :         DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
     180             : 
     181         120 :         if ((pcap_reloaded) && (post_cache_fill_fn_handled == false)) {
     182             :                 /* cleanup old entries only if the operation was successful,
     183             :                  * otherwise keep around the old entries until we can
     184             :                  * successfully reload */
     185             : 
     186         120 :                 if (!pcap_cache_replace(pcache)) {
     187           0 :                         DEBUG(0, ("Failed to replace printer list!\n"));
     188             :                 }
     189             : 
     190         120 :                 if (post_cache_fill_fn != NULL) {
     191         120 :                         post_cache_fill_fn(ev, msg_ctx);
     192             :                 }
     193             :         }
     194         120 :         pcap_cache_destroy_specific(&pcache);
     195             : 
     196         120 :         return;
     197             : }
     198             : 
     199             : /***************************************************************************
     200             : run a function on each printer name in the printcap file.
     201             : ***************************************************************************/
     202             : 
     203           0 : void pcap_printer_fn_specific(const struct pcap_cache *pc,
     204             :                         void (*fn)(const char *, const char *, const char *, void *),
     205             :                         void *pdata)
     206             : {
     207           0 :         const struct pcap_cache *p;
     208             : 
     209           0 :         for (p = pc; p != NULL; p = p->next)
     210           0 :                 fn(p->name, p->comment, p->location, pdata);
     211             : 
     212           0 :         return;
     213             : }

Generated by: LCOV version 1.14