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