1/*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License as
4 * published by the Free Software Foundation; either version 2 of
5 * the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
15 * MA 02111-1307 USA
16 */
17/***************************************************************************
18 * LPRng - An Extended Print Spooler System
19 *
20 * Copyright 1988-2003, Patrick Powell, San Diego, CA
21 *     papowell@lprng.com
22 * See LICENSE for conditions of use.
23 *
24 ***************************************************************************/
25
26 static char *const _id =
27"$Id: getprinter.c,v 1.1.1.1 2008/10/15 03:28:26 james26_jang Exp $";
28
29
30#include "lp.h"
31#include "gethostinfo.h"
32#include "getprinter.h"
33#include "getqueue.h"
34#include "child.h"
35/**** ENDINCLUDE ****/
36#ifdef REMOVE
37/***************************************************************************
38 Get_printer()
39    determine the name of the printer - Printer_DYN variable
40	Note: this is used by clients to find the name of default printer
41	or by server to find forwarding information.  If the printcap
42	RemotePrinter_DYN is specified this overrides the printer name.
43	1. -P option
44	2. $PRINTER, $LPDEST, $NPRINTER, $NGPRINTER argument variable
45	3. printcap file
46	4. "lp" if none specified
47	5. Get the printcap entry (if any),  and re-extract information-
48        - printer name (primary name)
49		- lp=printer@remote or rp@rm information
50    6. recheck the printer name for printer@hostname form,
51       and set RemoteHost_DYN to the hostname
52	Note: this appears to cover all the cases, with the exception that
53	a primary name of the form printer@host will be detected as the
54	destination.  Sigh...
55 ***************************************************************************/
56
57char *Get_printer(void)
58{
59	char *s = Printer_DYN;
60
61	DEBUG1("Get_printer: original printer '%s'", s );
62	if( s == 0 ) s = getenv( "PRINTER" );
63	if( s == 0 ) s = getenv( "LPDEST" );
64	if( s == 0 ) s = getenv( "NPRINTER" );
65	if( s == 0 ) s = getenv( "NGPRINTER" );
66
67	if( !Require_explicit_Q_DYN ){
68
69		if( s == 0 ){
70			Get_all_printcap_entries();
71			if( All_line_list.count ){
72				s = All_line_list.list[0];
73			}
74		}
75		if( s == 0 ) s = Default_printer_DYN;
76	}
77	if( s == 0 ){
78		FATAL(LOG_ERR) "No printer name available, usage: 'lpr -Pprinter filename'" );
79	}
80	Set_DYN(&Printer_DYN,s);
81	Expand_vars();
82	DEBUG1("Get_printer: final printer '%s'",Printer_DYN);
83	return(Printer_DYN);
84}
85
86/***************************************************************************
87 * Fix_Rm_Rp_info
88 *  - get the remote host and remote printer information
89 *  - we assume this is called by clients trying to get remote host
90 *    connection information
91 *  - we may want to get the printcap information as a side effect
92 *
93 ***************************************************************************/
94
95
96void Fix_Rm_Rp_info(char *report_conflict, int report_len )
97{
98	char *s;
99
100	DEBUG1("Fix_Rm_Rp_info: printer name '%s'", Printer_DYN );
101
102	/*
103	 * now check to see if we have a remote printer
104	 * 1. printer@host form overrides
105	 * 2. printcap entry, we use lp=pr@host
106	 * 3. printcap entry, we use remote host, remote printer
107	 * 4. no printcap entry, we use default printer, default remote host
108	 */
109	s = Printer_DYN;
110	Printer_DYN = 0;
111	Reset_config();
112	Printer_DYN = s;
113	Free_line_list(&PC_alias_line_list);
114	Free_line_list(&PC_entry_line_list);
115	Set_DYN(&Lp_device_DYN, 0 );
116	Set_DYN(&RemotePrinter_DYN, 0 );
117	Set_DYN(&RemoteHost_DYN, 0 );
118
119	if( !Is_server ){
120		if( (s = safestrchr( Printer_DYN, '@' ))  ){
121			Set_DYN(&RemotePrinter_DYN, Printer_DYN );
122			*s = 0;
123			Set_DYN(&Queue_name_DYN, Printer_DYN );
124			s = safestrchr( RemotePrinter_DYN, '@');
125			*s++ = 0;
126			Set_DYN(&RemoteHost_DYN, s );
127			if( (s = safestrchr(RemoteHost_DYN,'%')) ){
128				Set_DYN(&Unix_socket_path_DYN, 0 );
129			}
130			/* force connection via TCP/IP */
131			goto done;
132		}
133		/* we search for the values in the printcap */
134		Set_DYN(&Queue_name_DYN, Printer_DYN );
135		s = 0;
136		if(
137			(s = Select_pc_info(Printer_DYN,
138			&PC_entry_line_list,
139			&PC_alias_line_list,
140			&PC_names_line_list, &PC_order_line_list,
141			&PC_info_line_list, 0, 1 ))
142			||
143			(s = Select_pc_info("*",
144			&PC_entry_line_list,
145			&PC_alias_line_list,
146			&PC_names_line_list, &PC_order_line_list,
147			&PC_info_line_list, 0, 0 ))
148		){
149			if( !safestrcmp( s, "*" ) ){
150				s = Queue_name_DYN;
151			}
152			Set_DYN(&Printer_DYN,s);
153
154#ifdef ORIGINAL_DEBUG//JY@1020
155			DEBUG2("Fix_Rm_Rp_info: from printcap found '%s'", Printer_DYN );
156			if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_alias_line_list",
157				&PC_alias_line_list );
158			if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_entry_line_list",
159				&PC_entry_line_list );
160#endif
161		}
162#ifdef ORIGINAL_DEBUG//JY@1020
163		if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - final PC_entry_line_list",
164			&PC_entry_line_list );
165#endif
166		Find_default_tags( &PC_entry_line_list, Pc_var_list, "client." );
167		Find_tags( &PC_entry_line_list, &Config_line_list, "client." );
168		Find_tags( &PC_entry_line_list, &PC_entry_line_list, "client." );
169		Set_var_list( Pc_var_list, &PC_entry_line_list);
170		if( RemoteHost_DYN && Lp_device_DYN && report_conflict ){
171			SNPRINTF(report_conflict,report_len)
172				"conflicting printcap entries :lp=%s:rm=%s",
173				Lp_device_DYN, RemoteHost_DYN );
174		}
175		/* if a client and have direct, then we need to use
176		 * the LP values
177		 */
178		Expand_percent( &Lp_device_DYN );
179		if( Direct_DYN ){
180			DEBUG2("Fix_Rm_Rp_info: direct to '%s'", Lp_device_DYN );
181			if( strchr( "/|", cval(Lp_device_DYN)) ){
182				Set_DYN(&RemotePrinter_DYN, 0 );
183				Set_DYN(&RemoteHost_DYN, 0 );
184				goto done;
185			}
186			if( (s = safestrchr( Lp_device_DYN, '@' ))  ){
187				Set_DYN(&RemotePrinter_DYN, Lp_device_DYN );
188				*s = 0;
189				Set_DYN(&Queue_name_DYN, Printer_DYN );
190				s = safestrchr( RemotePrinter_DYN, '@');
191				*s++ = 0;
192				Set_DYN(&RemoteHost_DYN, s );
193				if( (s = safestrchr(RemoteHost_DYN,'%')) ){
194					Set_DYN(&Unix_socket_path_DYN, 0 );
195				}
196				goto done;
197			}
198		}
199		if( Force_localhost_DYN ){
200			DEBUG2("Fix_Rm_Rp_info: force_localhost to '%s'", Printer_DYN );
201			Set_DYN( &RemoteHost_DYN, LOCALHOST );
202			Set_DYN( &RemotePrinter_DYN, Printer_DYN );
203			Set_DYN( &Lp_device_DYN, 0 );
204			goto done;
205		}
206		if( (s = safestrchr( Lp_device_DYN, '@' ))  ){
207			DEBUG2("Fix_Rm_Rp_info: Lp_device_DYN is printer '%s'", Lp_device_DYN );
208			Set_DYN(&RemotePrinter_DYN, Lp_device_DYN );
209			if( (s = safestrchr( RemotePrinter_DYN,'@')) ){
210				*s++ = 0;
211				Set_DYN(&RemoteHost_DYN, s );
212				if( (s = safestrchr(RemoteHost_DYN+1,'%')) ){
213					Set_DYN(&Unix_socket_path_DYN, 0 );
214				}
215			}
216		}
217		if( RemoteHost_DYN == 0 || *RemoteHost_DYN == 0 ){
218			Set_DYN( &RemoteHost_DYN, Default_remote_host_DYN );
219		}
220		if( RemoteHost_DYN == 0 || *RemoteHost_DYN == 0 ){
221			Set_DYN( &RemoteHost_DYN, FQDNHost_FQDN );
222		}
223		if( RemotePrinter_DYN == 0 || *RemotePrinter_DYN == 0 ){
224			Set_DYN( &RemotePrinter_DYN, Printer_DYN );
225		}
226		goto done;
227	}
228	/* we are a server */
229	/* we search for the values in the printcap */
230	s = 0;
231	Set_DYN(&Queue_name_DYN, Printer_DYN );
232	if(
233		(s = Select_pc_info(Printer_DYN,
234		&PC_entry_line_list,
235		&PC_alias_line_list,
236		&PC_names_line_list, &PC_order_line_list,
237		&PC_info_line_list, 0, 1 ))
238		||
239		(s = Select_pc_info("*",
240		&PC_entry_line_list,
241		&PC_alias_line_list,
242		&PC_names_line_list, &PC_order_line_list,
243		&PC_info_line_list, 0, 0 ))
244	){
245		if( !safestrcmp( s, "*" ) ){
246			s = Queue_name_DYN;
247		}
248		Set_DYN(&Printer_DYN,s);
249		DEBUG2("Fix_Rm_Rp_info: found '%s'", Printer_DYN );
250	}
251#ifdef ORIGINAL_DEBUG//JY@1020
252	if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_alias_line_list",
253		&PC_alias_line_list );
254	if(DEBUGL2)Dump_line_list("Fix_Rm_Rp_info - PC_entry_line_list",
255		&PC_entry_line_list );
256#endif
257	/* now get the Server_xxx variables */
258	Find_default_tags( &PC_entry_line_list, Pc_var_list, "server." );
259	Find_tags( &PC_entry_line_list, &Config_line_list, "server." );
260	Find_tags( &PC_entry_line_list, &PC_entry_line_list, "server." );
261	Set_var_list( Pc_var_list, &PC_entry_line_list);
262	if( RemoteHost_DYN && Lp_device_DYN && report_conflict ){
263		SNPRINTF(report_conflict,report_len)
264			"conflicting printcap entries :lp=%s:rm=%s",
265			Lp_device_DYN, RemoteHost_DYN );
266	}
267	if( safestrchr( Lp_device_DYN, '@' ) ){
268		Set_DYN(&RemotePrinter_DYN, Lp_device_DYN );
269		s = safestrchr( RemotePrinter_DYN, '@');
270		if( s ) *s++ = 0;
271		if( *s == 0 ) s = 0;
272		Set_DYN(&RemoteHost_DYN, s );
273		if( (s = safestrchr(RemoteHost_DYN,'%')) ){
274			Set_DYN(&Unix_socket_path_DYN, 0 );
275		}
276		Set_DYN(&Lp_device_DYN,0);
277	} else if( Lp_device_DYN ){
278		Set_DYN(&RemoteHost_DYN,0);
279		Set_DYN(&RemotePrinter_DYN,0);
280	} else if( RemoteHost_DYN ){
281		; /* we use defaults */
282	} else if( Server_names_DYN == 0 ){
283		if( report_conflict ){
284			SNPRINTF(report_conflict,report_len)
285				"no :rm, :lp, or :sv entry" );
286		}
287	}
288	if( !Lp_device_DYN ){
289		if( ISNULL(RemoteHost_DYN) ){
290			Set_DYN( &RemoteHost_DYN, Default_remote_host_DYN );
291		}
292		if( ISNULL(RemoteHost_DYN) ){
293			Set_DYN( &RemoteHost_DYN, FQDNHost_FQDN );
294		}
295		if( ISNULL(RemotePrinter_DYN) ){
296			Set_DYN( &RemotePrinter_DYN, Printer_DYN );
297		}
298	}
299 done:
300
301	Expand_vars();
302	DEBUG1("Fix_Rm_Rp_info: Printer '%s', Queue '%s', Lp '%s', Rp '%s', Rh '%s'",
303		Printer_DYN, Queue_name_DYN, Lp_device_DYN,
304		RemotePrinter_DYN, RemoteHost_DYN );
305#ifdef ORIGINAL_DEBUG//JY@1020
306	if(DEBUGL2)Dump_parms("Fix_Rm_Rp_info", Pc_var_list);
307#endif
308}
309
310/***************************************************************************
311 * Get_all_printcap_entries( char *s )
312 *  - get the remote host and remote printer information
313 *  - we assume this is called by clients trying to get remote host
314 *    connection information
315 *  - we may want to get the printcap information as a side effect
316 *
317 ***************************************************************************/
318
319void Get_all_printcap_entries(void)
320{
321	char *s, *t;
322	int i;
323
324	/*
325	 * now check to see if we have an entry for the 'all:' printcap
326	 */
327	s = t = 0;
328	DEBUG1("Get_all_printcap_entries: starting");
329	Free_line_list( &All_line_list );
330	if( (s = Select_pc_info(ALL,
331			&PC_entry_line_list,
332			&PC_alias_line_list,
333			&PC_names_line_list, &PC_order_line_list,
334			&PC_info_line_list, 0, 0 )) ){
335		if( !(t = Find_str_value( &PC_entry_line_list, ALL, Value_sep )) ){
336			t = "all";
337		}
338		DEBUG1("Get_all_printcap_entries: '%s' has '%s'",s,t);
339		Split(&All_line_list,t,File_sep,0,0,0,1,0,0);
340	} else {
341		for( i = 0; i < PC_order_line_list.count; ++i ){
342			s = PC_order_line_list.list[i];
343			if( ISNULL(s) || !safestrcmp( ALL, s ) ) continue;
344			if( safestrcmp(s,"*") && !ispunct( cval( s ) ) ){
345				Add_line_list(&All_line_list,s,0,0,0);
346			}
347		}
348	}
349#ifdef ORIGINAL_DEBUG//JY@1020
350	if(DEBUGL1)Dump_line_list("Get_all_printcap_entries- All_line_list", &All_line_list );
351#endif
352}
353
354void Show_formatted_info( void )
355{
356	char *s;
357	char error[SMALLBUFFER];
358
359	DEBUG1("Show_formatted_info: getting printcap information for '%s'", Printer_DYN );
360	error[0] = 0;
361	Fix_Rm_Rp_info(error,sizeof(error));
362	if( error[0] ){
363		WARNMSG(
364			"%s: '%s'",
365			Printer_DYN, error );
366	}
367#ifdef ORIGINAL_DEBUG//JY@1020
368	if(DEBUGL1)Dump_line_list("Aliases",&PC_alias_line_list);
369#endif
370	s = Join_line_list_with_sep(&PC_alias_line_list,"|");
371	if( Write_fd_str( 1, s ) < 0 ) cleanup(0);
372	if(s) free(s); s = 0;
373	/* Escape_colons( &PC_entry_line_list ); */
374	s = Join_line_list_with_sep(&PC_entry_line_list,"\n :");
375	Expand_percent( &s );
376	if( s ){
377		if( Write_fd_str( 1, "\n :" ) < 0 ) cleanup(0);
378		if( Write_fd_str( 1, s ) < 0 ) cleanup(0);
379	}
380	if( s ) free(s); s =0;
381	if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0);
382}
383
384void Show_all_printcap_entries( void )
385{
386	char *s;
387	int i;
388
389	s = 0;
390	Get_all_printcap_entries();
391	s = Join_line_list_with_sep(&PC_names_line_list,"\n :");
392	if( Write_fd_str( 1, "\n.names\n" ) < 0 ) cleanup(0);
393	if( s && *s ){
394		if( Write_fd_str( 1, " :" ) < 0 ) cleanup(0);
395		if( Write_fd_str( 1, s ) < 0 ) cleanup(0);
396		if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0);
397	}
398	if(s) free(s); s = 0;
399
400	s = Join_line_list_with_sep(&All_line_list,"\n :");
401	if( Write_fd_str( 1, "\n.all\n" ) < 0 ) cleanup(0);
402	if( s && *s ){
403		if( Write_fd_str( 1, " :" ) < 0 ) cleanup(0);
404		if( Write_fd_str( 1, s ) < 0 ) cleanup(0);
405		if( Write_fd_str( 1, "\n" ) < 0 ) cleanup(0);
406	}
407	if( s ) free(s); s =0;
408
409	if( Write_fd_str( 1,"\n#Printcap Information\n") < 0 ) cleanup(0);
410	for( i = 0; i < All_line_list.count; ++i ){
411		Set_DYN(&Printer_DYN,All_line_list.list[i]);
412		Show_formatted_info();
413	}
414}
415#endif
416