1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23 /*	  All Rights Reserved  	*/
24 
25 
26 /*
27  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 
31 /* EMACS_MODES: !fill, lnumb, !overwrite, !nodelete, !picture */
32 
33 #include "stdio.h"
34 #include "string.h"
35 #include "stdlib.h"
36 #include "unistd.h"
37 
38 #include "lp.h"
39 #include "filters.h"
40 
41 static void		q_print ( int , char * );
42 
43 static char *fw_zDblQte (char *zBuf);
44 
45 /**
46  ** dumpfilters() - WRITE FILTERS FROM INTERNAL STRUCTURE TO FILTER TABLE
47  **/
48 
49 int
dumpfilters(char * file)50 dumpfilters(char *file)
51 {
52 	register _FILTER	*pf;
53 	register TEMPLATE	*pt;
54 	register TYPE		*pty;
55 	register char		*p,
56 				*sep;
57 	register int		fld;
58 	int fd;
59 
60 	if ((fd = open_filtertable(file, "w")) < 0)
61 		return (-1);
62 
63 	printlist_setup ("", "", LP_SEP, "");
64 	if (filters) for (pf = filters; pf->name; pf++) {
65 
66 		for (fld = 0; fld < FL_MAX; fld++) switch (fld) {
67 		case FL_IGN:
68 			break;
69 		case FL_NAME:
70 			p = pf->name;
71 			goto String;
72 		case FL_CMD:
73 			if ((p = fw_zDblQte (pf->command)) != NULL) {
74 				(void)fdprintf (fd, "%s%s", FL_SEP, p);
75 				free (p);
76 				break;
77 			}
78 			/* zDblQte failed so go without quotes */
79 			p = pf->command;
80 String:			(void)fdprintf (fd, "%s%s", FL_SEP, (p? p : ""));
81 			break;
82 		case FL_TYPE:
83 			(void)fdprintf(fd, "%s%s", FL_SEP,
84 				(pf->type == fl_fast? FL_FAST : FL_SLOW));
85 			break;
86 		case FL_PTYPS:
87 			pty = pf->printer_types;
88 			goto Types;
89 		case FL_ITYPS:
90 			pty = pf->input_types;
91 			goto Types;
92 		case FL_OTYPS:
93 			pty = pf->output_types;
94 Types:			(void)fdprintf(fd, "%s", FL_SEP);
95 			sep = "";
96 			if (pty) {
97 				for (; pty->name; pty++) {
98 					(void)fdprintf(fd, "%s%s", sep,
99 						pty->name);
100 					sep = ",";
101 				}
102 			} else
103 				(void)fdprintf(fd, "%s", NAME_ANY);
104 			break;
105 		case FL_PRTRS:
106 			(void)fdprintf(fd, "%s", FL_SEP);
107 			if (pf->printers)
108 				fdprintlist (fd, pf->printers);
109 			else
110 				(void)fdprintf(fd, "%s", NAME_ANY);
111 			break;
112 		case FL_TMPS:
113 			(void)fdprintf(fd, "%s", FL_SEP);
114 			sep = "";
115 			if ((pt = pf->templates))
116 				for(; pt->keyword; pt++) {
117 					(void)fdprintf(fd, "%s%s ", sep,
118 						pt->keyword);
119 					q_print(fd, pt->pattern);
120 					(void)fdprintf(fd, " = ");
121 					q_print(fd, pt->result);
122 					sep = ",";
123 				}
124 			break;
125 		}
126 		(void)fdprintf(fd, FL_END);
127 	}
128 
129 	close(fd);
130 	return (0);
131 }
132 
133 /**
134  ** q_print() - PRINT STRING, QUOTING SEPARATOR CHARACTERS
135  **/
136 
137 static void
q_print(int fd,char * str)138 q_print(int fd, char *str)
139 {
140 	/*
141 	 * There are four reasons to quote a character: It is
142 	 * a quote (backslash) character, it is a field separator,
143 	 * it is a list separator, or it is a template separator.
144 	 * "loadfilters()" strips the quote (backslash), but not
145 	 * in one place.
146 	 */
147 	if (!str)
148 		return;
149 	while (*str) {
150 		if (
151 			*str == '\\'		/* quote reason #1 */
152 		     || strchr(FL_SEP, *str)	/* quote reason #2 */
153 		     || strchr(LP_SEP, *str)	/* quote reason #3 */
154 		     || strchr("=", *str)	/* quote reason #4 */
155 		)
156 			fdputc ('\\', fd);
157 		fdputc (*str, fd);
158 		str++;
159 	}
160 	return;
161 }
162 
163 /*********************************************************
164 
165 	fw_zDblQte
166 
167 	Duplicates the given string allocating memory
168 	using malloc.
169 
170 	Double quotes are used to encase the string
171 	and a backslash s put infront of any embedded
172 	quotes.
173 
174 	returns a pointer to the string provided.
175 
176 	It the function runs out of memory it returns
177 	NULL.
178 
179 
180 */
fw_zDblQte(char * zBuf)181 static char *fw_zDblQte (char *zBuf)
182 {
183 	char *zT;
184 	int i;
185 	int j;
186 	int iNewSize;
187 
188 	/* count the embedded double quotes */
189 	for (i = j = 0; zBuf[i]; i++) {
190 		if (zBuf[i] == '"') {
191 			j++;
192 		}
193 	}
194 
195 	/*
196 		Allocate a new buffer
197 		add 3 extra bytes for:
198 			the new leading double quote
199 			the new trailing double quote
200 			and the NULL
201 		add an extra byte for each embedded double quote
202 	*/
203 	iNewSize = (strlen (zBuf) + 3 + j);
204 	if ((zT = malloc (iNewSize)) == NULL) {
205 		return (NULL); /* buffer overflow */
206 	}
207 
208 	j = 0;
209 	zT[j++] = '"'; /* start with a leading double quote */
210 	for (i = 0; zBuf[i]; i++) {
211 		if (zBuf[i] == '"') {
212 			zT[j++] = '\\';
213 		}
214 		zT[j++] = zBuf[i];
215 	}
216 
217 	zT[j++] = '"'; /* add a trailing double quote */
218 	zT[j] = '\0';
219 
220 	return (zT);
221 }
222 
223