Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/printing/pcap.c

    r597 r740  
    2727
    2828/*
    29  *  This module contains code to parse and cache printcap data, possibly
    30  *  in concert with the CUPS/SYSV/AIX-specific code found elsewhere.
    31  *
    32  *  The way this module looks at the printcap file is very simplistic.
    33  *  Only the local printcap file is inspected (no searching of NIS
    34  *  databases etc).
    35  *
    36  *  There are assumed to be one or more printer names per record, held
    37  *  as a set of sub-fields separated by vertical bar symbols ('|') in the
    38  *  first field of the record. The field separator is assumed to be a colon
    39  *  ':' and the record separator a newline.
    40  *
    41  *  Lines ending with a backspace '\' are assumed to flag that the following
    42  *  line is a continuation line so that a set of lines can be read as one
    43  *  printcap entry.
    44  *
    45  *  A line stating with a hash '#' is assumed to be a comment and is ignored
    46  *  Comments are discarded before the record is strung together from the
    47  *  set of continuation lines.
    48  *
    49  *  Opening a pipe for "lpc status" and reading that would probably
    50  *  be pretty effective. Code to do this already exists in the freely
    51  *  distributable PCNFS server code.
    52  *
    5329 *  Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
    5430 *  in smb.conf under Solaris.
     
    6238
    6339#include "includes.h"
    64 
     40#include "printing/pcap.h"
     41#include "printer_list.h"
    6542
    6643struct pcap_cache {
    6744        char *name;
    6845        char *comment;
     46        char *location;
    6947        struct pcap_cache *next;
    7048};
    7149
    72 /* The systemwide printcap cache. */
    73 static struct pcap_cache *pcap_cache = NULL;
    74 
    75 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment)
     50bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location)
    7651{
    7752        struct pcap_cache *p;
     
    8257        p->name = SMB_STRDUP(name);
    8358        p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
    84 
    85         DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s\n",
    86                 p->name, p->comment ? p->comment : ""));
     59        p->location = (location && *location) ? SMB_STRDUP(location) : NULL;
     60
     61        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 : ""));
    8764
    8865        p->next = *ppcache;
     
    10178                SAFE_FREE(p->name);
    10279                SAFE_FREE(p->comment);
     80                SAFE_FREE(p->location);
    10381                SAFE_FREE(p);
    10482        }
     
    10684}
    10785
    108 bool pcap_cache_add(const char *name, const char *comment)
    109 {
    110         return pcap_cache_add_specific(&pcap_cache, name, comment);
     86bool pcap_cache_add(const char *name, const char *comment, const char *location)
     87{
     88        NTSTATUS status;
     89        time_t t = time_mono(NULL);
     90
     91        status = printer_list_set_printer(talloc_tos(), name, comment, location, t);
     92        return NT_STATUS_IS_OK(status);
    11193}
    11294
    11395bool pcap_cache_loaded(void)
    11496{
    115         return (pcap_cache != NULL);
    116 }
    117 
    118 void pcap_cache_replace(const struct pcap_cache *pcache)
     97        NTSTATUS status;
     98        time_t last;
     99
     100        status = printer_list_get_last_refresh(&last);
     101        return NT_STATUS_IS_OK(status);
     102}
     103
     104bool pcap_cache_replace(const struct pcap_cache *pcache)
    119105{
    120106        const struct pcap_cache *p;
    121 
    122         pcap_cache_destroy_specific(&pcap_cache);
     107        NTSTATUS status;
     108
     109        status = printer_list_mark_reload();
     110        if (!NT_STATUS_IS_OK(status)) {
     111                DEBUG(0, ("Failed to mark printer list for reload!\n"));
     112                return false;
     113        }
     114
    123115        for (p = pcache; p; p = p->next) {
    124                 pcap_cache_add(p->name, p->comment);
    125         }
    126 }
    127 
    128 void pcap_cache_reload(void (*post_cache_fill_fn)(void))
     116                pcap_cache_add(p->name, p->comment, p->location);
     117        }
     118
     119        status = printer_list_clean_old();
     120        if (!NT_STATUS_IS_OK(status)) {
     121                DEBUG(0, ("Failed to cleanup printer list!\n"));
     122                return false;
     123        }
     124
     125        return true;
     126}
     127
     128void pcap_cache_reload(struct tevent_context *ev,
     129                       struct messaging_context *msg_ctx,
     130                       void (*post_cache_fill_fn)(struct tevent_context *,
     131                                                  struct messaging_context *))
    129132{
    130133        const char *pcap_name = lp_printcapname();
    131134        bool pcap_reloaded = False;
    132         struct pcap_cache *tmp_cache = NULL;
    133         XFILE *pcap_file;
    134         char *pcap_line;
     135        NTSTATUS status;
    135136        bool post_cache_fill_fn_handled = false;
    136137
     
    143144        }
    144145
    145         tmp_cache = pcap_cache;
    146         pcap_cache = NULL;
     146        status = printer_list_mark_reload();
     147        if (!NT_STATUS_IS_OK(status)) {
     148                DEBUG(0, ("Failed to mark printer list for reload!\n"));
     149                return;
     150        }
    147151
    148152#ifdef HAVE_CUPS
    149153        if (strequal(pcap_name, "cups")) {
    150                 pcap_reloaded = cups_cache_reload(post_cache_fill_fn);
     154                pcap_reloaded = cups_cache_reload(ev, msg_ctx,
     155                                                  post_cache_fill_fn);
    151156                /*
    152157                 * cups_cache_reload() is async and calls post_cache_fill_fn()
     
    179184#endif
    180185
    181         /* handle standard printcap - moved from pcap_printer_fn() */
    182 
    183         if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
    184                 DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
    185                 goto done;
    186         }
    187 
    188         for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; free(pcap_line)) {
    189                 char name[MAXPRINTERLEN+1];
    190                 char comment[62];
    191                 char *p, *q;
    192 
    193                 if (*pcap_line == '#' || *pcap_line == 0)
    194                         continue;
    195 
    196                 /* now we have a real printer line - cut at the first : */     
    197                 if ((p = strchr_m(pcap_line, ':')) != NULL)
    198                         *p = 0;
    199      
    200                 /*
    201                  * now find the most likely printer name and comment
    202                  * this is pure guesswork, but it's better than nothing
    203                  */
    204                 for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) {
    205                         bool has_punctuation;
    206 
    207                         if ((q = strchr_m(p, '|')) != NULL)
    208                                 *q++ = 0;
    209 
    210                         has_punctuation = (strchr_m(p, ' ') ||
    211                                            strchr_m(p, '\t') ||
    212                                            strchr_m(p, '"') ||
    213                                            strchr_m(p, '\'') ||
    214                                            strchr_m(p, ';') ||
    215                                            strchr_m(p, ',') ||
    216                                            strchr_m(p, '(') ||
    217                                            strchr_m(p, ')'));
    218 
    219                         if (strlen(p) > strlen(comment) && has_punctuation) {
    220                                 strlcpy(comment, p, sizeof(comment));
    221                                 continue;
    222                         }
    223 
    224                         if (strlen(p) <= MAXPRINTERLEN && *name == '\0' && !has_punctuation) {
    225                                 if (!*comment) {
    226                                         strlcpy(comment, name, sizeof(comment));
    227                                 }
    228                                 strlcpy(name, p, sizeof(name));
    229                                 continue;
    230                         }
    231 
    232                         if (!strchr_m(comment, ' ') &&
    233                             strlen(p) > strlen(comment)) {
    234                                 strlcpy(comment, p, sizeof(comment));
    235                                 continue;
    236                         }
    237                 }
    238 
    239                 if (*name && !pcap_cache_add(name, comment)) {
    240                         x_fclose(pcap_file);
    241                         goto done;
    242                 }
    243         }
    244 
    245         x_fclose(pcap_file);
    246         pcap_reloaded = True;
     186        pcap_reloaded = std_pcap_cache_reload(pcap_name);
    247187
    248188done:
    249189        DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
    250190
    251         if (pcap_reloaded) {
    252                 pcap_cache_destroy_specific(&tmp_cache);
    253                 if ((post_cache_fill_fn_handled == false)
    254                  && (post_cache_fill_fn != NULL)) {
    255                         post_cache_fill_fn();
     191        if ((pcap_reloaded) && (post_cache_fill_fn_handled == false)) {
     192                /* cleanup old entries only if the operation was successful,
     193                 * otherwise keep around the old entries until we can
     194                 * successfuly reaload */
     195                status = printer_list_clean_old();
     196                if (!NT_STATUS_IS_OK(status)) {
     197                        DEBUG(0, ("Failed to cleanup printer list!\n"));
    256198                }
    257         } else {
    258                 pcap_cache_destroy_specific(&pcap_cache);
    259                 pcap_cache = tmp_cache;
     199                if (post_cache_fill_fn != NULL) {
     200                        post_cache_fill_fn(ev, msg_ctx);
     201                }
    260202        }
    261203
     
    266208bool pcap_printername_ok(const char *printername)
    267209{
    268         struct pcap_cache *p;
    269 
    270         for (p = pcap_cache; p != NULL; p = p->next)
    271                 if (strequal(p->name, printername))
    272                         return True;
    273 
    274         return False;
     210        NTSTATUS status;
     211
     212        status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, 0);
     213        return NT_STATUS_IS_OK(status);
    275214}
    276215
     
    280219
    281220void pcap_printer_fn_specific(const struct pcap_cache *pc,
    282                         void (*fn)(const char *, const char *, void *),
     221                        void (*fn)(const char *, const char *, const char *, void *),
    283222                        void *pdata)
    284223{
     
    286225
    287226        for (p = pc; p != NULL; p = p->next)
    288                 fn(p->name, p->comment, pdata);
     227                fn(p->name, p->comment, p->location, pdata);
    289228
    290229        return;
    291230}
    292231
    293 void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *pdata)
    294 {
    295         pcap_printer_fn_specific(pcap_cache, fn, pdata);
    296 }
     232void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata)
     233{
     234        NTSTATUS status;
     235
     236        status = printer_list_run_fn(fn, pdata);
     237        if (!NT_STATUS_IS_OK(status)) {
     238                DEBUG(3, ("Failed to run fn for all printers!\n"));
     239        }
     240        return;
     241}
Note: See TracChangeset for help on using the changeset viewer.