]> arthur.barton.de Git - netatalk.git/blob - etc/papd/ppd.c
Remove bdb env on exit
[netatalk.git] / etc / papd / ppd.c
1 /*
2  * $Id: ppd.c,v 1.17 2009-10-14 02:24:05 didg Exp $
3  *
4  * Copyright (c) 1995 Regents of The University of Michigan.
5  * All Rights Reserved.  See COPYRIGHT.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <atalk/logger.h>
17 #include <sys/types.h>
18 #include <sys/param.h>
19 #include <sys/time.h>
20 #include <netatalk/at.h>
21 #include <atalk/atp.h>
22
23 #include "printer.h"
24 #include "ppd.h"
25
26 struct ppd_font         *ppd_fonts = NULL;
27
28 struct ppd_feature      ppd_features[] = {
29     { "*LanguageLevel", NULL },
30     { "*PSVersion",     NULL },
31 #ifdef HAVE_CUPS
32     { "*FreeVM",        "33554432" },
33 #else
34     { "*FreeVM",        NULL },
35 #endif
36     { "*Product",       NULL },
37     { "*PCFileName",    NULL },
38     { "*ModelName",     NULL },
39     { "*NickName",      NULL },
40     { "*ColorDevice",   NULL },
41     { "*FaxSupport",    NULL },
42     { "*TTRasterizer",  NULL },
43     { NULL, NULL },
44 };
45
46 struct ppdent {
47     char        *pe_main;
48     char        *pe_option;
49     char        *pe_translation;
50     char        *pe_value;
51 };
52
53 #ifndef SHOWPPD
54 static int ppd_inited;
55
56 static void ppd_init(void)
57 {
58     if (ppd_inited)
59         return;
60
61     ppd_inited++;
62
63     if (printer->p_ppdfile)
64         read_ppd( printer->p_ppdfile, 0 );
65 }
66 #endif /* SHOWPPD */
67
68
69 /* quick and ugly hack to be able to read
70    ppd files with Mac line ending */
71 static char* my_fgets(char *buf, size_t bufsize, FILE *stream)
72 {
73     int p;           /* uninitialized, OK 310105 */
74     size_t count = 0;
75  
76     while (count < (bufsize - 1) && EOF != (p=fgetc(stream))) {
77         buf[count] = p;
78         count++;
79         if ( p == '\r' || p == '\n')
80            break;
81     }
82
83     if (p == EOF && count == 0)
84         return NULL;
85
86     /* translate line endings */
87     if ( buf[count - 1] == '\r')
88         buf[count - 1] = '\n';
89
90     buf[count] = 0;
91     return buf;
92 }
93
94 static struct ppdent *getppdent( FILE *stream)
95 {
96     static char                 buf[ 1024 ];
97     static struct ppdent        ppdent;
98     char                        *p, *q;
99
100     ppdent.pe_main = ppdent.pe_option = ppdent.pe_translation =
101             ppdent.pe_value = NULL;
102
103     while (( p = my_fgets( buf, sizeof( buf ), stream )) != NULL ) {
104         if ( *p != '*' ) {      /* main key word */
105             continue;
106         }
107         if ( p[ strlen( p ) - 1 ] != '\n') {
108             LOG(log_error, logtype_papd, "getppdent: line too long" );
109             continue;
110         }
111
112         q = p;
113         while ( (*p != ' ') && (*p != '\t') && (*p != ':') && (*p != '\n') ) {
114             p++;
115         }
116         if ( (*( q + 1 ) == '%') || (*( q + 1 ) == '?') ) {     /* comments & queries */
117             continue;
118         }
119         ppdent.pe_main = q;
120         if ( *p == '\n' ) {
121             *p = '\0';
122             ppdent.pe_option = ppdent.pe_translation = ppdent.pe_value = NULL;
123             return( &ppdent );
124         }
125
126         if ( *p != ':' ) {      /* option key word */
127             *p++ = '\0';
128
129             while ( (*p == ' ') || (*p == '\t') ) {
130                 p++;
131             }
132
133             q = p;
134             while ( (*p != ':') && (*p != '/') && (*p != '\n') ) {
135                 p++;
136             }
137
138             if ( *p == '\n' ) {
139                 continue;
140             }
141
142             ppdent.pe_option = q;
143             if ( *p == '/' ) {  /* translation string */
144                 *p++ = '\0';
145                 q = p;
146                 while ( *p != ':' && *p != '\n' ) {
147                     p++;
148                 }
149                 if ( *p != ':' ) {
150                     continue;
151                 }
152
153                 ppdent.pe_translation = q;
154             } else {
155                 ppdent.pe_translation = NULL;
156             }
157         }
158         *p++ = '\0';
159
160         while ( (*p == ' ') || (*p == '\t') ) {
161             p++;
162         }
163
164         /* value */
165         q = p;
166         while ( *p != '\n' ) {
167             p++;
168         }
169         *p = '\0';
170         ppdent.pe_value = q;
171
172         return( &ppdent );
173     }
174
175     return( NULL );
176 }
177
178 int read_ppd(char *file, int fcnt)
179 {
180     FILE                *ppdfile;
181     struct ppdent       *pe;
182     struct ppd_feature  *pfe;
183     struct ppd_font     *pfo;
184
185     if ( fcnt > 20 ) {
186         LOG(log_error, logtype_papd, "read_ppd: %s: Too many files!", file );
187         return( -1 );
188     }
189
190     if (( ppdfile = fopen( file, "r" )) == NULL ) {
191         LOG(log_error, logtype_papd, "read_ppd %s: %s", file, strerror(errno) );
192         return( -1 );
193     }
194
195     while (( pe = getppdent( ppdfile )) != NULL ) {
196         /* *Include files */
197         if ( strcmp( pe->pe_main, "*Include" ) == 0 ) {
198             read_ppd( pe->pe_value, fcnt + 1 );
199             continue;
200         }
201
202         /* *Font */
203         if ( strcmp( pe->pe_main, "*Font" ) == 0 && pe->pe_option ) {
204             for ( pfo = ppd_fonts; pfo; pfo = pfo->pd_next ) {
205                 if ( strcmp( pfo->pd_font, pe->pe_option ) == 0 ) {
206                     break;
207                 }
208             }
209             if ( pfo ) {
210                 continue;
211             }
212
213             if (( pfo = (struct ppd_font *)malloc( sizeof( struct ppd_font )))
214                     == NULL ) {
215                 LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
216                 exit( 1 );
217             }
218             if (( pfo->pd_font =
219                     (char *)malloc( strlen( pe->pe_option ) + 1 )) == NULL ) {
220                 LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
221                 exit( 1 );
222             }
223             strcpy( pfo->pd_font, pe->pe_option );
224             pfo->pd_next = ppd_fonts;
225             ppd_fonts = pfo;
226             continue;
227         }
228
229
230         /* Features */
231         for ( pfe = ppd_features; pfe->pd_name; pfe++ ) {
232             if ( strcmp( pe->pe_main, pfe->pd_name ) == 0 ) {
233                 break;
234             }
235         }
236         if ( pfe->pd_name && pe->pe_value ) { 
237             if (( pfe->pd_value =
238                     (char *)malloc( strlen( pe->pe_value ) + 1 )) == NULL ) {
239                 LOG(log_error, logtype_papd, "malloc: %s", strerror(errno) );
240                 exit( 1 );
241             }
242
243             strcpy( pfe->pd_value, pe->pe_value );
244             continue;
245         }
246     }
247
248     fclose( ppdfile );
249     return( 0 );
250 }
251
252 struct ppd_font *ppd_font( char *font)
253 {
254     struct ppd_font     *pfo;
255
256 #ifndef SHOWPPD
257     if ( ! ppd_inited ) {
258         ppd_init();
259     }
260 #endif /* SHOWPPD */
261
262     for ( pfo = ppd_fonts; pfo; pfo = pfo->pd_next ) {
263         if ( strcmp( pfo->pd_font, font ) == 0 ) {
264             return( pfo );
265         }
266     }
267     return( NULL );
268 }
269
270 struct ppd_feature *ppd_feature( const char *feature, int len)
271 {
272     struct ppd_feature  *pfe;
273     char                ppd_feature_main[ 256 ];
274     const char          *end, *p;
275     char                *q;
276
277 #ifndef SHOWPPD
278     if ( ! ppd_inited ) {
279         ppd_init();
280     }
281 #endif /* SHOWPPD */
282
283     if (len > sizeof(ppd_feature_main) -1)
284         return( NULL );
285         
286     for ( end = feature + len, p = feature, q = ppd_feature_main;
287             (p <= end) && (*p != '\n') && (*p != '\r'); p++, q++ ) {
288         *q = *p;
289     }
290     if ( p > end ) {
291         return( NULL );
292     }
293     *q = '\0';
294
295     for ( pfe = ppd_features; pfe->pd_name; pfe++ ) {
296         if ( (strcmp( pfe->pd_name, ppd_feature_main ) == 0) && pfe->pd_value ) {
297             return( pfe );
298         }
299     }
300
301     return( NULL );
302 }