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