2010-05-13 22:23:23 +04:00
/*
Unix SMB / CIFS implementation .
printcap parsing
Copyright ( C ) Karl Auer 1993 - 1998
Re - working by Martin Kiff , 1994
Re - written again by Andrew Tridgell
Modified for SVID support by Norm Jacobs , 1997
Modified for CUPS support by Michael Sweet , 1999
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 3 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 , see < http : //www.gnu.org/licenses/>.
*/
/*
* 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
* databases etc ) .
*
* There are assumed to be one or more printer names per record , held
* as a set of sub - fields separated by vertical bar symbols ( ' | ' ) in the
* first field of the record . The field separator is assumed to be a colon
* ' : ' and the record separator a newline .
*
* Lines ending with a backspace ' \ ' are assumed to flag that the following
* line is a continuation line so that a set of lines can be read as one
* printcap entry .
*
* A line stating with a hash ' # ' is assumed to be a comment and is ignored
* Comments are discarded before the record is strung together from the
* set of continuation lines .
*
* Opening a pipe for " lpc status " and reading that would probably
* be pretty effective . Code to do this already exists in the freely
* distributable PCNFS server code .
*/
/* printcap parsing specific code moved here from printing/pcap.c */
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-05-14 16:39:40 +04:00
# include "printing/pcap.h"
2010-05-13 22:23:23 +04:00
/* handle standard printcap - moved from pcap_printer_fn() */
2014-07-22 22:17:38 +04:00
bool std_pcap_cache_reload ( const char * pcap_name , struct pcap_cache * * _pcache )
2010-05-13 22:23:23 +04:00
{
2016-11-10 13:47:54 +03:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2016-11-26 11:27:19 +03:00
FILE * pcap_file ;
2010-05-13 22:23:23 +04:00
char * pcap_line ;
2014-07-22 22:17:38 +04:00
struct pcap_cache * pcache = NULL ;
2016-11-10 13:47:54 +03:00
bool print_warning = false ;
2010-05-13 22:23:23 +04:00
2016-11-26 11:27:19 +03:00
if ( ( pcap_file = fopen ( pcap_name , " r " ) ) = = NULL ) {
2010-05-13 22:23:23 +04:00
DEBUG ( 0 , ( " Unable to open printcap file %s for read! \n " , pcap_name ) ) ;
2016-11-10 13:47:54 +03:00
talloc_free ( frame ) ;
2010-05-13 22:23:23 +04:00
return false ;
}
2016-11-26 11:27:19 +03:00
while ( ( pcap_line = fgets_slash ( frame , NULL , 1024 ,
pcap_file ) ) ! = NULL ) {
2016-11-10 13:47:54 +03:00
char * name = NULL ;
char * comment = NULL ;
2010-05-13 22:23:23 +04:00
char * p , * q ;
2016-11-26 11:27:19 +03:00
if ( * pcap_line = = ' # ' | | * pcap_line = = 0 ) {
TALLOC_FREE ( pcap_line ) ;
2010-05-13 22:23:23 +04:00
continue ;
2016-11-26 11:27:19 +03:00
}
2010-05-13 22:23:23 +04:00
/* 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
*/
2016-11-10 13:47:54 +03:00
for ( p = pcap_line ; p ! = NULL ; p = q ) {
bool has_punctuation = false ;
2010-05-13 22:23:23 +04:00
if ( ( q = strchr_m ( p , ' | ' ) ) ! = NULL )
* q + + = 0 ;
has_punctuation = ( strchr_m ( p , ' ' ) | |
strchr_m ( p , ' \t ' ) | |
2011-05-20 23:27:02 +04:00
strchr_m ( p , ' " ' ) | |
strchr_m ( p , ' \' ' ) | |
strchr_m ( p , ' ; ' ) | |
strchr_m ( p , ' , ' ) | |
2010-05-13 22:23:23 +04:00
strchr_m ( p , ' ( ' ) | |
strchr_m ( p , ' ) ' ) ) ;
2016-11-10 13:47:54 +03:00
if ( name = = NULL & & ! has_punctuation ) {
name = talloc_strdup ( frame , p ) ;
2016-11-26 11:27:19 +03:00
TALLOC_FREE ( pcap_line ) ;
2010-05-13 22:23:23 +04:00
continue ;
}
2016-11-10 13:47:54 +03:00
if ( has_punctuation ) {
comment = talloc_strdup ( frame , p ) ;
2016-11-26 11:27:19 +03:00
TALLOC_FREE ( pcap_line ) ;
2010-05-13 22:23:23 +04:00
continue ;
}
2016-11-10 13:47:54 +03:00
}
2010-05-13 22:23:23 +04:00
2016-11-10 13:47:54 +03:00
if ( name ! = NULL ) {
bool ok ;
if ( ! print_warning & & strlen ( name ) > MAXPRINTERLEN ) {
print_warning = true ;
2010-05-13 22:23:23 +04:00
}
2016-11-10 13:47:54 +03:00
ok = pcap_cache_add_specific ( & pcache ,
name ,
comment ,
NULL ) ;
if ( ! ok ) {
2016-11-26 11:27:19 +03:00
fclose ( pcap_file ) ;
2016-11-10 13:47:54 +03:00
pcap_cache_destroy_specific ( & pcache ) ;
talloc_free ( frame ) ;
return false ;
}
2010-05-13 22:23:23 +04:00
}
2016-11-10 13:47:54 +03:00
TALLOC_FREE ( name ) ;
TALLOC_FREE ( comment ) ;
2016-11-26 11:27:19 +03:00
TALLOC_FREE ( pcap_line ) ;
2016-11-10 13:47:54 +03:00
}
if ( print_warning ) {
DBG_WARNING ( " WARNING: You have some printer names that are "
" longer than %u characters. These may not be "
" accessible to some older clients! \n " ,
( unsigned int ) MAXPRINTERLEN ) ;
2010-05-13 22:23:23 +04:00
}
2016-11-26 11:27:19 +03:00
fclose ( pcap_file ) ;
2014-07-22 22:17:38 +04:00
* _pcache = pcache ;
2016-11-10 13:47:54 +03:00
talloc_free ( frame ) ;
2010-05-13 22:23:23 +04:00
return true ;
}