mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
r4539: patch from Rob -- adding real printcap name cache function to speed up printcap reloads
(This used to be commit 1cad525093
)
This commit is contained in:
parent
846b8d4cfd
commit
d097ea4905
@ -397,7 +397,7 @@ SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
|
|||||||
$(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
|
$(REGISTRY_OBJ) $(POPT_LIB_OBJ) \
|
||||||
$(BUILDOPT_OBJ) $(SMBLDAP_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/print_cups.o printing/print_generic.o \
|
||||||
printing/lpq_parse.o printing/load.o
|
printing/lpq_parse.o printing/load.o
|
||||||
|
|
||||||
|
@ -21,45 +21,30 @@
|
|||||||
#include "includes.h"
|
#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
|
auto-load some homes and printer services
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static void add_auto_printers(void)
|
static void add_auto_printers(void)
|
||||||
{
|
{
|
||||||
const char *p;
|
const char *p;
|
||||||
int printers;
|
int pnum = lp_servicenumber(PRINTERS_NAME);
|
||||||
char *str = SMB_STRDUP(lp_auto_services());
|
char *str;
|
||||||
|
|
||||||
if (!str) return;
|
if (pnum < 0)
|
||||||
|
|
||||||
printers = lp_servicenumber(PRINTERS_NAME);
|
|
||||||
|
|
||||||
if (printers < 0) {
|
|
||||||
SAFE_FREE(str);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
if ((str = SMB_STRDUP(lp_auto_services())) == NULL)
|
||||||
for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
|
return;
|
||||||
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)) {
|
if (pcap_printername_ok(p))
|
||||||
lp_add_printer(p,printers);
|
lp_add_printer(p, pnum);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SAFE_FREE(str);
|
SAFE_FREE(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@ -67,7 +52,12 @@ load automatic printer services
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void load_printers(void)
|
void load_printers(void)
|
||||||
{
|
{
|
||||||
|
if (!pcap_cache_loaded())
|
||||||
|
pcap_cache_reload();
|
||||||
|
|
||||||
add_auto_printers();
|
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);
|
||||||
}
|
}
|
||||||
|
@ -2046,17 +2046,32 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
|
|||||||
handles are not affected.
|
handles are not affected.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
uint32 del_a_printer(char *sharename)
|
uint32 del_a_printer(const char *sharename)
|
||||||
{
|
{
|
||||||
pstring key;
|
pstring key;
|
||||||
TDB_DATA kbuf;
|
TDB_DATA kbuf;
|
||||||
|
pstring printdb_path;
|
||||||
|
|
||||||
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
|
slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
|
||||||
|
|
||||||
kbuf.dptr=key;
|
kbuf.dptr=key;
|
||||||
kbuf.dsize=strlen(key)+1;
|
kbuf.dsize=strlen(key)+1;
|
||||||
|
|
||||||
tdb_delete(tdb_printers, kbuf);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2899,7 +2914,8 @@ BOOL is_printer_published(Printer_entry *print_hnd, int snum,
|
|||||||
return False;
|
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));
|
memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
|
||||||
|
|
||||||
free_a_printer(&printer, 2);
|
free_a_printer(&printer, 2);
|
||||||
|
@ -27,10 +27,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse printcap file.
|
* This module contains code to parse and cache printcap data, possibly
|
||||||
*
|
* in concert with the CUPS/SYSV/AIX-specific code found elsewhere.
|
||||||
* This module does exactly one thing - it looks into the printcap file
|
|
||||||
* and tells callers if a specified string appears as a printer name.
|
|
||||||
*
|
*
|
||||||
* The way this module looks at the printcap file is very simplistic.
|
* The way this module looks at the printcap file is very simplistic.
|
||||||
* Only the local printcap file is inspected (no searching of NIS
|
* Only the local printcap file is inspected (no searching of NIS
|
||||||
@ -62,352 +60,194 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#ifdef AIX
|
|
||||||
/* ******************************************
|
typedef struct pcap_cache {
|
||||||
Extend for AIX system and qconfig file
|
char *name;
|
||||||
from 'boulard@univ-rennes1.fr
|
char *comment;
|
||||||
****************************************** */
|
struct pcap_cache *next;
|
||||||
static int strlocate(char *xpLine,char *xpS)
|
} pcap_cache_t;
|
||||||
|
|
||||||
|
static pcap_cache_t *pcap_cache = NULL;
|
||||||
|
|
||||||
|
BOOL pcap_cache_add(const char *name, const char *comment)
|
||||||
{
|
{
|
||||||
int iS,iL,iRet;
|
pcap_cache_t *p;
|
||||||
char *p;
|
|
||||||
iS = strlen(xpS);
|
|
||||||
iL = strlen(xpLine);
|
|
||||||
|
|
||||||
iRet = 0;
|
if (name == NULL || ((p = SMB_MALLOC_P(pcap_cache_t)) == NULL))
|
||||||
p = xpLine;
|
return False;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* ******************************************************************* */
|
|
||||||
/* * Scan qconfig and search all virtual printer (device printer) * */
|
|
||||||
/* ******************************************************************* */
|
|
||||||
static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
|
|
||||||
{
|
|
||||||
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)
|
p->name = SMB_STRDUP(name);
|
||||||
{
|
p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
|
||||||
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
iEtat = 0;
|
p->next = pcap_cache;
|
||||||
/* scan qconfig file for searching <printername>: */
|
pcap_cache = p;
|
||||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
|
|
||||||
{
|
return True;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
x_fclose(pfile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Scan qconfig file and locate de printername */
|
static void pcap_cache_destroy(pcap_cache_t *cache)
|
||||||
|
|
||||||
static BOOL ScanQconfig(char *psz,char *pszPrintername)
|
|
||||||
{
|
{
|
||||||
int iLg,iEtat;
|
pcap_cache_t *p, *next;
|
||||||
XFILE *pfile;
|
|
||||||
char *pName;
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
pName = NULL;
|
for (p = cache; p != NULL; p = next) {
|
||||||
line = NULL;
|
next = p->next;
|
||||||
if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
|
|
||||||
pName = malloc(iLg+10);
|
SAFE_FREE(p->name);
|
||||||
if (pName == NULL)
|
SAFE_FREE(p->comment);
|
||||||
{
|
SAFE_FREE(p);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
#endif /* AIX */
|
|
||||||
|
|
||||||
|
BOOL pcap_cache_loaded(void)
|
||||||
/***************************************************************************
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
char *line=NULL;
|
return (pcap_cache != NULL);
|
||||||
const char *psz;
|
}
|
||||||
char *p,*q;
|
|
||||||
XFILE *pfile;
|
|
||||||
|
|
||||||
if (pszPrintername == NULL || pszPrintername[0] == '\0')
|
void pcap_cache_reload(void)
|
||||||
{
|
{
|
||||||
DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
|
const char *pcap_name = lp_printcapname();
|
||||||
return(False);
|
BOOL pcap_reloaded = False;
|
||||||
}
|
pcap_cache_t *tmp_cache = NULL;
|
||||||
|
XFILE *pcap_file;
|
||||||
|
char *pcap_line;
|
||||||
|
|
||||||
/* only go looking if no printcap name supplied */
|
DEBUG(3, ("reloading printcap cache\n"));
|
||||||
if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
|
|
||||||
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
|
/* only go looking if no printcap name supplied */
|
||||||
{
|
if (pcap_name == NULL || *pcap_name == 0) {
|
||||||
DEBUG(0,( "No printcap file name configured!\n"));
|
DEBUG(0, ("No printcap file name configured!\n"));
|
||||||
return(False);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tmp_cache = pcap_cache;
|
||||||
|
pcap_cache = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_CUPS
|
#ifdef HAVE_CUPS
|
||||||
if (strequal(psz, "cups"))
|
if (strequal(pcap_name, "cups")) {
|
||||||
return (cups_printername_ok(pszPrintername));
|
pcap_reloaded = cups_cache_reload();
|
||||||
#endif /* HAVE_CUPS */
|
goto done;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SYSV
|
#ifdef SYSV
|
||||||
if (strequal(psz, "lpstat"))
|
if (strequal(pcap_name, "lpstat")) {
|
||||||
return (sysv_printername_ok(pszPrintername));
|
pcap_reloaded = sysv_cache_reload();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AIX
|
#ifdef AIX
|
||||||
if (strlocate(psz,"/qconfig"))
|
if (strstr_m(pcap_name, "/qconfig") != NULL) {
|
||||||
return(ScanQconfig(psz,pszPrintername));
|
pcap_reloaded = aix_cache_reload();
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
|
/* handle standard printcap - moved from pcap_printer_fn() */
|
||||||
{
|
|
||||||
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
|
|
||||||
return(False);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
|
if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
|
||||||
{
|
DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
|
||||||
if (*line == '#' || *line == 0)
|
goto done;
|
||||||
continue;
|
|
||||||
|
|
||||||
/* now we have a real printer line - cut it off at the first : */
|
|
||||||
p = strchr_m(line,':');
|
|
||||||
if (p) *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;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
x_fclose(pfile);
|
for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) {
|
||||||
return(False);
|
pstring name, comment;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
if (*pcap_line == '#' || *pcap_line == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* now we have a real printer line - cut at the first : */
|
||||||
|
if ((p = strchr_m(pcap_line, ':')) != NULL)
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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(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
|
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
|
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
|
strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
|
||||||
to return DOS codepage. FIXME !! JRA.
|
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 *))
|
void pcap_printer_fn(void (*fn)(char *, char *))
|
||||||
{
|
{
|
||||||
pstring name,comment;
|
pcap_cache_t *p;
|
||||||
char *line;
|
|
||||||
char *psz;
|
|
||||||
char *p,*q;
|
|
||||||
XFILE *pfile;
|
|
||||||
|
|
||||||
/* only go looking if no printcap name supplied */
|
for (p = pcap_cache; p != NULL; p = p->next)
|
||||||
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
|
fn(p->name, p->comment);
|
||||||
{
|
|
||||||
DEBUG(0,( "No printcap file name configured!\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_CUPS
|
return;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comment[60] = 0;
|
|
||||||
name[MAXPRINTERLEN] = 0;
|
|
||||||
|
|
||||||
if (*name)
|
|
||||||
fn(name,comment);
|
|
||||||
}
|
|
||||||
x_fclose(pfile);
|
|
||||||
}
|
}
|
||||||
|
111
source3/printing/print_aix.c
Normal file
111
source3/printing/print_aix.c
Normal file
@ -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 */
|
@ -52,14 +52,8 @@ static const char *cups_server(void)
|
|||||||
return cupsServer();
|
return cupsServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
BOOL cups_cache_reload(void)
|
||||||
* 'cups_printer_fn()' - Call a function for every printer known to the
|
|
||||||
* system.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void cups_printer_fn(void (*fn)(char *, char *))
|
|
||||||
{
|
{
|
||||||
/* I - Function to call */
|
|
||||||
http_t *http; /* HTTP connection to server */
|
http_t *http; /* HTTP connection to server */
|
||||||
ipp_t *request, /* IPP Request */
|
ipp_t *request, /* IPP Request */
|
||||||
*response; /* IPP Response */
|
*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...
|
* 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",
|
DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
|
||||||
cups_server(), strerror(errno)));
|
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",
|
DEBUG(0,("Unable to get printer list - %s\n",
|
||||||
ippErrorString(cupsLastError())));
|
ippErrorString(cupsLastError())));
|
||||||
httpClose(http);
|
httpClose(http);
|
||||||
return;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (attr = response->attrs; attr != NULL;)
|
for (attr = response->attrs; attr != NULL;)
|
||||||
@ -171,7 +165,11 @@ void cups_printer_fn(void (*fn)(char *, char *))
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
(*fn)(name, info);
|
if (!pcap_cache_add(name, info)) {
|
||||||
|
ippDelete(response);
|
||||||
|
httpClose(http);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ippDelete(response);
|
ippDelete(response);
|
||||||
@ -213,7 +211,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
|
|||||||
DEBUG(0,("Unable to get printer list - %s\n",
|
DEBUG(0,("Unable to get printer list - %s\n",
|
||||||
ippErrorString(cupsLastError())));
|
ippErrorString(cupsLastError())));
|
||||||
httpClose(http);
|
httpClose(http);
|
||||||
return;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (attr = response->attrs; attr != NULL;)
|
for (attr = response->attrs; attr != NULL;)
|
||||||
@ -255,7 +253,11 @@ void cups_printer_fn(void (*fn)(char *, char *))
|
|||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
(*fn)(name, info);
|
if (!pcap_cache_add(name, info)) {
|
||||||
|
ippDelete(response);
|
||||||
|
httpClose(http);
|
||||||
|
return False;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ippDelete(response);
|
ippDelete(response);
|
||||||
@ -265,100 +267,7 @@ void cups_printer_fn(void (*fn)(char *, char *))
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
httpClose(http);
|
httpClose(http);
|
||||||
}
|
return True;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* '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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,23 +35,17 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#ifdef SYSV
|
#ifdef SYSV
|
||||||
|
BOOL sysv_cache_reload(void)
|
||||||
typedef struct printer {
|
|
||||||
char *name;
|
|
||||||
struct printer *next;
|
|
||||||
} printer_t;
|
|
||||||
static printer_t *printers = NULL;
|
|
||||||
|
|
||||||
static void populate_printers(void)
|
|
||||||
{
|
{
|
||||||
char **lines;
|
char **lines;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
|
DEBUG(5, ("reloading sysv printcap cache\n"));
|
||||||
if (!lines) return;
|
|
||||||
|
|
||||||
for (i=0;lines[i];i++) {
|
if ((lines = file_lines_pload("/usr/bin/lpstat -v", NULL)) == NULL)
|
||||||
printer_t *ptmp;
|
return False;
|
||||||
|
|
||||||
|
for (i = 0; lines[i]; i++) {
|
||||||
char *name, *tmp;
|
char *name, *tmp;
|
||||||
char *buf = lines[i];
|
char *buf = lines[i];
|
||||||
|
|
||||||
@ -64,7 +58,7 @@ static void populate_printers(void)
|
|||||||
* In case we're only at the "for ".
|
* In case we're only at the "for ".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(!strncmp("for ",++tmp,4)) {
|
if(!strncmp("for ", ++tmp, 4)) {
|
||||||
tmp=strchr_m(tmp, ' ');
|
tmp=strchr_m(tmp, ' ');
|
||||||
tmp++;
|
tmp++;
|
||||||
}
|
}
|
||||||
@ -78,7 +72,7 @@ static void populate_printers(void)
|
|||||||
* On HPUX there is an extra line that can be ignored.
|
* On HPUX there is an extra line that can be ignored.
|
||||||
* d.thibadeau 2001/08/09
|
* d.thibadeau 2001/08/09
|
||||||
*/
|
*/
|
||||||
if(!strncmp("remote to",tmp,9))
|
if(!strncmp("remote to", tmp, 9))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
name = tmp;
|
name = tmp;
|
||||||
@ -88,53 +82,14 @@ static void populate_printers(void)
|
|||||||
*tmp = '\0';
|
*tmp = '\0';
|
||||||
|
|
||||||
/* add it to the cache */
|
/* add it to the cache */
|
||||||
if ((ptmp = SMB_MALLOC_P(printer_t)) != NULL) {
|
if (!pcap_cache_add(name, NULL)) {
|
||||||
ZERO_STRUCTP(ptmp);
|
file_lines_free(lines);
|
||||||
if((ptmp->name = SMB_STRDUP(name)) == NULL)
|
return False;
|
||||||
DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
|
|
||||||
ptmp->next = printers;
|
|
||||||
printers = ptmp;
|
|
||||||
} else {
|
|
||||||
DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file_lines_free(lines);
|
file_lines_free(lines);
|
||||||
}
|
return True;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -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 */
|
/* 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) ));
|
DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
|
||||||
release_print_db(pdb);
|
release_print_db(pdb);
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
|
@ -1282,7 +1282,7 @@ static int setup_select_timeout(void)
|
|||||||
void check_reload(int t)
|
void check_reload(int t)
|
||||||
{
|
{
|
||||||
static time_t last_smb_conf_reload_time = 0;
|
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();
|
time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
|
||||||
|
|
||||||
if(last_smb_conf_reload_time == 0) {
|
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
|
Then no printer is available till the first printers check
|
||||||
is performed. A lower initial interval circumvents this. */
|
is performed. A lower initial interval circumvents this. */
|
||||||
if ( printcap_cache_time > 60 )
|
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
|
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)) {
|
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 */
|
/* 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)
|
if ( (t >= last_printer_reload_time+printcap_cache_time)
|
||||||
|| (t-last_load_printers_reload_time < 0) )
|
|| (t-last_printer_reload_time < 0) )
|
||||||
{
|
{
|
||||||
DEBUG( 3,( "Printcap cache time expired.\n"));
|
DEBUG( 3,( "Printcap cache time expired.\n"));
|
||||||
remove_stale_printers();
|
reload_printers();
|
||||||
load_printers();
|
last_printer_reload_time = t;
|
||||||
last_load_printers_reload_time = t;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,6 +463,39 @@ static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_
|
|||||||
/* NOTREACHED return True; */
|
/* 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.
|
Reload the services file.
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
@ -490,8 +523,7 @@ BOOL reload_services(BOOL test)
|
|||||||
|
|
||||||
ret = lp_load(dyn_CONFIGFILE, False, False, True);
|
ret = lp_load(dyn_CONFIGFILE, False, False, True);
|
||||||
|
|
||||||
remove_stale_printers();
|
reload_printers();
|
||||||
load_printers();
|
|
||||||
|
|
||||||
/* perhaps the config filename is now set */
|
/* perhaps the config filename is now set */
|
||||||
if (!test)
|
if (!test)
|
||||||
|
@ -152,10 +152,8 @@ int find_service(fstring service)
|
|||||||
int iPrinterService;
|
int iPrinterService;
|
||||||
|
|
||||||
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
|
if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0) {
|
||||||
const char *pszTemp = lp_printcapname();
|
|
||||||
|
|
||||||
DEBUG(3,("checking whether %s is a valid printer name...\n", service));
|
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,("%s is a valid printer name\n", service));
|
||||||
DEBUG(3,("adding %s as a printer service\n", service));
|
DEBUG(3,("adding %s as a printer service\n", service));
|
||||||
lp_add_printer(service, iPrinterService);
|
lp_add_printer(service, iPrinterService);
|
||||||
@ -863,36 +861,3 @@ void close_cnum(connection_struct *conn, uint16 vuid)
|
|||||||
|
|
||||||
conn_free(conn);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -32,14 +32,17 @@
|
|||||||
|
|
||||||
#include "includes.h"
|
#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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *pszTemp;
|
|
||||||
|
|
||||||
setup_logging(argv[0],True);
|
setup_logging(argv[0],True);
|
||||||
|
|
||||||
if (argc < 2 || argc > 3)
|
if (argc != 2)
|
||||||
printf("Usage: testprns printername [printcapfile]\n");
|
printf("Usage: testprns printername\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dbf = x_fopen("test.log", O_WRONLY|O_CREAT|O_TRUNC, 0644);
|
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");
|
printf("Unable to open logfile.\n");
|
||||||
} else {
|
} else {
|
||||||
DEBUGLEVEL = 3;
|
DEBUGLEVEL = 3;
|
||||||
pszTemp = (argc < 3) ? PRINTCAP_NAME : argv[2];
|
printf("Looking for printer %s\n", argv[1]);
|
||||||
printf("Looking for printer %s in printcap file %s\n",
|
load_printers();
|
||||||
argv[1], pszTemp);
|
if (!pcap_printername_ok(argv[1]))
|
||||||
if (!pcap_printername_ok(argv[1], pszTemp))
|
|
||||||
printf("Printer name %s is not valid.\n", argv[1]);
|
printf("Printer name %s is not valid.\n", argv[1]);
|
||||||
else
|
else
|
||||||
printf("Printer name %s is valid.\n", argv[1]);
|
printf("Printer name %s is valid.\n", argv[1]);
|
||||||
|
Loading…
Reference in New Issue
Block a user