1/*
2 * $Id: magics.c,v 1.15 2009-10-13 22:55:37 didg Exp $
3 *
4 * Copyright (c) 1990,1994 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 <atalk/logger.h>
13#include <sys/param.h>
14#include <stdio.h>
15#include <string.h>
16#include <stdlib.h>
17
18#include <netatalk/at.h>
19
20#include "file.h"
21#include "comment.h"
22#include "lp.h"
23
24static int state=0;
25
26static void parser_error(struct papfile *outfile)
27{
28                spoolerror( outfile, "Comments error, Ignoring job." );
29		outfile->pf_state |= PF_EOF;
30		lp_close();
31}
32
33int ps( struct papfile *infile, struct papfile *outfile, struct sockaddr_at *sat)
34{
35    char			*start;
36    int				linelength, crlflength;
37    struct papd_comment		*comment;
38
39    for (;;) {
40        if ( infile->pf_state & PF_STW ) {
41		infile->pf_state &= ~PF_STW;
42		/* set up spool file */
43		if ( lp_open( outfile, sat ) < 0 && !state) {
44		    LOG(log_error, logtype_papd, "lp_open failed" );
45		    spoolerror( outfile, "Ignoring job." );
46		}
47		state = 1;
48	}
49	if ( (comment = compeek()) ) {
50	    switch( (*comment->c_handler)( infile, outfile, sat )) {
51	    case CH_DONE :
52		continue;
53
54	    case CH_MORE :
55		return( CH_MORE );
56
57	    case CH_ERROR :
58	        parser_error(outfile);
59		return( 0 );
60
61	    default :
62		return( CH_ERROR );
63	    }
64	} else {
65	    switch ( markline( infile, &start, &linelength, &crlflength )) {
66	    case 0 :
67		/* eof on infile */
68		outfile->pf_state |= PF_EOF;
69		lp_close();
70		return( 0 );
71
72	    case -2:
73	        parser_error(outfile);
74		return( 0 );
75
76	    case -1 :
77		return( 0 );
78	    }
79
80	    if ( infile->pf_state & PF_BOT ) {
81		if (( comment = commatch( start, start+linelength, magics )) != NULL ) {
82		    compush( comment );
83		    continue;	/* top of for (;;) */
84		}
85#if 0
86		infile->pf_state &= ~PF_BOT;
87
88		/* set up spool file */
89		if ( lp_open( outfile, sat ) < 0 ) {
90		    LOG(log_error, logtype_papd, "lp_open failed" );
91		    spoolerror( outfile, "Ignoring job." );
92		}
93#endif
94	    }
95
96	    /* write to file */
97	    lp_write( infile, start, linelength + crlflength );
98	    CONSUME( infile, linelength + crlflength );
99	}
100    }
101}
102
103int cm_psquery( struct papfile *in, struct papfile *out, struct sockaddr_at *sat _U_)
104{
105    struct papd_comment	*comment;
106    char		*start;
107    int			linelength, crlflength;
108
109    for (;;) {
110	switch ( markline( in, &start, &linelength, &crlflength )) {
111	case 0 :
112	    /* eof on infile */
113	    out->pf_state |= PF_EOF;
114	    compop();
115	    return( CH_DONE );
116
117	case -1 :
118	    return( CH_MORE );
119
120        case -2 :
121            return( CH_ERROR );
122	}
123
124	if ( in->pf_state & PF_BOT ) {
125	    in->pf_state &= ~PF_BOT;
126	} else {
127	    if (( comment = commatch( start, start+linelength, queries )) != NULL ) {
128		compush( comment );
129		return( CH_DONE );
130	    }
131	}
132
133	CONSUME( in, linelength + crlflength );
134    }
135}
136
137int cm_psadobe( struct papfile *in, struct papfile *out, struct sockaddr_at *sat _U_)
138{
139    char		*start;
140    int			linelength, crlflength;
141    struct papd_comment	*comment = compeek();
142
143    for (;;) {
144	switch ( markline( in, &start, &linelength, &crlflength )) {
145	case 0 :
146	    /* eof on infile */
147	    out->pf_state |= PF_EOF;
148	    compop();
149	    return( CH_DONE );
150
151	case -1 :
152	    return( CH_MORE );
153
154        case -2 :
155            return( CH_ERROR );
156	}
157	if ( in->pf_state & PF_BOT ) {
158	    in->pf_state &= ~PF_BOT;
159#if 0
160	    if ( lp_open( out, sat ) < 0 ) {
161		LOG(log_error, logtype_papd, "lp_open failed" );
162		spoolerror( out, "Ignoring job." );
163	    }
164#endif
165	} else {
166	    if (( comment = commatch( start, start + linelength, headers )) != NULL ) {
167		compush( comment );
168		return( CH_DONE );
169	    }
170	}
171
172	lp_write( in, start, linelength + crlflength );
173	CONSUME( in, linelength + crlflength );
174    }
175}
176
177char	*Query = "Query";
178
179int cm_psswitch(struct papfile *in, struct papfile *out, struct sockaddr_at *sat _U_)
180{
181    char		*start, *stop, *p;
182    int			linelength, crlflength;
183
184    switch ( markline( in, &start, &linelength, &crlflength )) {
185    case 0 :
186	/* eof on infile */
187	out->pf_state |= PF_EOF;
188	compop();
189	return( 0 );
190
191    case -1 :
192	return( CH_MORE );
193
194    case -2 :
195        return( CH_ERROR );
196    }
197
198    stop = start + linelength;
199    for ( p = start; p < stop; p++ ) {
200	if ( *p == ' ' || *p == '\t' ) {
201	    break;
202	}
203    }
204    for ( ; p < stop; p++ ) {
205	if ( *p != ' ' && *p != '\t' ) {
206	    break;
207	}
208    }
209
210    if ( (size_t)(stop - p) >= strlen( Query ) &&
211	    strncmp( p, Query, strlen( Query )) == 0 ) {
212	if ( comswitch( magics, cm_psquery ) < 0 ) {
213	    LOG(log_error, logtype_papd, "cm_psswitch: can't find psquery!" );
214	    exit( 1 );
215	}
216    } else {
217	if ( comswitch( magics, cm_psadobe ) < 0 ) {
218	    LOG(log_error, logtype_papd, "cm_psswitch: can't find psadobe!" );
219	    exit( 1 );
220	}
221    }
222    return( CH_DONE );
223}
224
225
226struct papd_comment	magics[] = {
227    { "%!PS-Adobe-3.0 Query",	NULL,			cm_psquery, C_FULL },
228    { "%!PS-Adobe-3.0",		NULL,			cm_psadobe, C_FULL },
229    { "%!PS-Adobe-",		NULL,			cm_psswitch,	0 },
230    { NULL,			NULL,			NULL,		0 },
231};
232