63
61
#include "includes.h"
66
/* ******************************************
67
Extend for AIX system and qconfig file
68
from 'boulard@univ-rennes1.fr
69
****************************************** */
70
static int strlocate(char *xpLine,char *xpS)
81
if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
85
/*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
91
/* ******************************************************************* */
92
/* * Scan qconfig and search all virtual printer (device printer) * */
93
/* ******************************************************************* */
94
static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
104
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
106
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
111
/* scan qconfig file for searching <printername>: */
112
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
114
if (*line == '*' || *line == 0)
118
case 0: /* locate an entry */
119
if (*line == '\t' || *line == ' ') continue;
120
if ((p=strchr_m(line,':')))
123
p = strtok(line,":");
124
if (strcmp(p,"bsh")!=0)
132
case 1: /* scanning device stanza */
133
if (*line == '*' || *line == 0) continue;
134
if (*line != '\t' && *line != ' ')
136
/* name is found without stanza device */
137
/* probably a good printer ??? */
143
if (strlocate(line,"backend"))
145
/* it's a device, not a virtual printer*/
148
else if (strlocate(line,"device"))
150
/* it's a good virtual printer */
161
/* Scan qconfig file and locate de printername */
163
static BOOL ScanQconfig(char *psz,char *pszPrintername)
172
if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
173
pName = malloc(iLg+10);
176
DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
179
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
181
DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
185
slprintf(pName, iLg + 9, "%s:",pszPrintername);
187
/*DEBUG(3,( " Looking for entry %s\n",pName));*/
189
/* scan qconfig file for searching <printername>: */
190
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
192
if (*line == '*' || *line == 0)
196
case 0: /* scanning entry */
197
if (strncmp(line,pName,iLg) == 0)
203
case 1: /* scanning device stanza */
204
if (*line == '*' || *line == 0) continue;
205
if (*line != '\t' && *line != ' ')
207
/* name is found without stanza device */
208
/* probably a good printer ??? */
215
if (strlocate(line,"backend"))
217
/* it's a device, not a virtual printer*/
220
else if (strlocate(line,"device"))
222
/* it's a good virtual printer */
238
/***************************************************************************
239
Scan printcap file pszPrintcapname for a printer called pszPrintername.
240
Return True if found, else False. Returns False on error, too, after logging
241
the error at level 0. For generality, the printcap name may be passed - if
242
passed as NULL, the configuration will be queried for the name.
243
***************************************************************************/
244
BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
251
if (pszPrintername == NULL || pszPrintername[0] == '\0')
253
DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
257
/* only go looking if no printcap name supplied */
258
if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
259
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
261
DEBUG(0,( "No printcap file name configured!\n"));
64
typedef struct pcap_cache {
67
struct pcap_cache *next;
70
static pcap_cache_t *pcap_cache = NULL;
72
BOOL pcap_cache_add(const char *name, const char *comment)
76
if (name == NULL || ((p = SMB_MALLOC_P(pcap_cache_t)) == NULL))
79
p->name = SMB_STRDUP(name);
80
p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
88
static void pcap_cache_destroy(pcap_cache_t *cache)
90
pcap_cache_t *p, *next;
92
for (p = cache; p != NULL; p = next) {
96
SAFE_FREE(p->comment);
101
BOOL pcap_cache_loaded(void)
103
return (pcap_cache != NULL);
106
void pcap_cache_reload(void)
108
const char *pcap_name = lp_printcapname();
109
BOOL pcap_reloaded = False;
110
pcap_cache_t *tmp_cache = NULL;
114
DEBUG(3, ("reloading printcap cache\n"));
116
/* only go looking if no printcap name supplied */
117
if (pcap_name == NULL || *pcap_name == 0) {
118
DEBUG(0, ("No printcap file name configured!\n"));
122
tmp_cache = pcap_cache;
266
if (strequal(psz, "cups"))
267
return (cups_printername_ok(pszPrintername));
268
#endif /* HAVE_CUPS */
126
if (strequal(pcap_name, "cups")) {
127
pcap_reloaded = cups_cache_reload();
271
if (strequal(psz, "lpstat"))
272
return (sysv_printername_ok(pszPrintername));
132
#if defined(SYSV) || defined(HPUX)
133
if (strequal(pcap_name, "lpstat")) {
134
pcap_reloaded = sysv_cache_reload();
276
if (strlocate(psz,"/qconfig"))
277
return(ScanQconfig(psz,pszPrintername));
140
if (strstr_m(pcap_name, "/qconfig") != NULL) {
141
pcap_reloaded = aix_cache_reload();
280
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
282
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
286
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
288
if (*line == '#' || *line == 0)
291
/* now we have a real printer line - cut it off at the first : */
292
p = strchr_m(line,':');
146
/* handle standard printcap - moved from pcap_printer_fn() */
148
if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
149
DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
153
for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) {
154
pstring name, comment;
157
if (*pcap_line == '#' || *pcap_line == 0)
160
/* now we have a real printer line - cut at the first : */
161
if ((p = strchr_m(pcap_line, ':')) != NULL)
295
/* now just check if the name is in the list */
296
/* NOTE: I avoid strtok as the fn calling this one may be using it */
299
if ((q = strchr_m(p,'|'))) *q++ = 0;
301
if (strequal(p,pszPrintername))
165
* now find the most likely printer name and comment
166
* this is pure guesswork, but it's better than nothing
168
for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) {
169
BOOL has_punctuation;
171
if ((q = strchr_m(p, '|')) != NULL)
174
has_punctuation = (strchr_m(p, ' ') ||
179
if (strlen(p) > strlen(comment) && has_punctuation) {
184
if (strlen(p) <= MAXPRINTERLEN &&
185
strlen(p) > strlen(name) && !has_punctuation) {
187
pstrcpy(comment, name);
193
if (!strchr_m(comment, ' ') &&
194
strlen(p) > strlen(comment)) {
201
name[MAXPRINTERLEN] = 0;
203
if (*name && !pcap_cache_add(name, comment)) {
210
pcap_reloaded = True;
213
DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
216
pcap_cache_destroy(tmp_cache);
218
pcap_cache_destroy(pcap_cache);
219
pcap_cache = tmp_cache;
226
BOOL pcap_printername_ok(const char *printername)
230
for (p = pcap_cache; p != NULL; p = p->next)
231
if (strequal(p->name, printername))
316
237
/***************************************************************************
317
238
run a function on each printer name in the printcap file. The function is
318
239
passed the primary name and the comment (if possible). Note the fn() takes
319
240
strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
320
241
to return DOS codepage. FIXME !! JRA.
243
XXX: I'm not sure if this comment still applies.. Anyone? -Rob
321
244
***************************************************************************/
322
245
void pcap_printer_fn(void (*fn)(char *, char *))
324
pstring name,comment;
330
/* only go looking if no printcap name supplied */
331
if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
333
DEBUG(0,( "No printcap file name configured!\n"));
338
if (strequal(psz, "cups")) {
342
#endif /* HAVE_CUPS */
345
if (strequal(psz, "lpstat")) {
352
if (strlocate(psz,"/qconfig"))
354
ScanQconfig_fn(psz,fn);
359
if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
361
DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
365
for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
367
if (*line == '#' || *line == 0)
370
/* now we have a real printer line - cut it off at the first : */
371
p = strchr_m(line,':');
374
/* now find the most likely printer name and comment
375
this is pure guesswork, but it's better than nothing */
380
BOOL has_punctuation;
381
if ((q = strchr_m(p,'|'))) *q++ = 0;
383
has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
385
if (strlen(p)>strlen(comment) && has_punctuation)
391
if (strlen(p) <= MAXPRINTERLEN && strlen(p)>strlen(name) && !has_punctuation)
393
if (!*comment) pstrcpy(comment,name);
398
if (!strchr_m(comment,' ') &&
399
strlen(p) > strlen(comment))
407
name[MAXPRINTERLEN] = 0;
249
for (p = pcap_cache; p != NULL; p = p->next)
250
fn(p->name, p->comment);