xref: /illumos-gate/usr/src/cmd/lp/model/lp.tsol_separator.c (revision f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01)
1*f875b4ebSrica /*
2*f875b4ebSrica  * CDDL HEADER START
3*f875b4ebSrica  *
4*f875b4ebSrica  * The contents of this file are subject to the terms of the
5*f875b4ebSrica  * Common Development and Distribution License (the "License").
6*f875b4ebSrica  * You may not use this file except in compliance with the License.
7*f875b4ebSrica  *
8*f875b4ebSrica  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f875b4ebSrica  * or http://www.opensolaris.org/os/licensing.
10*f875b4ebSrica  * See the License for the specific language governing permissions
11*f875b4ebSrica  * and limitations under the License.
12*f875b4ebSrica  *
13*f875b4ebSrica  * When distributing Covered Code, include this CDDL HEADER in each
14*f875b4ebSrica  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f875b4ebSrica  * If applicable, add the following below this CDDL HEADER, with the
16*f875b4ebSrica  * fields enclosed by brackets "[]" replaced with your own identifying
17*f875b4ebSrica  * information: Portions Copyright [yyyy] [name of copyright owner]
18*f875b4ebSrica  *
19*f875b4ebSrica  * CDDL HEADER END
20*f875b4ebSrica  */
21*f875b4ebSrica 
22*f875b4ebSrica /*
23*f875b4ebSrica  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*f875b4ebSrica  * Use is subject to license terms.
25*f875b4ebSrica  */
26*f875b4ebSrica 
27*f875b4ebSrica #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*f875b4ebSrica 
29*f875b4ebSrica /*
30*f875b4ebSrica  * Add TSOL banner, trailer, page header/footers to a print job
31*f875b4ebSrica  */
32*f875b4ebSrica 
33*f875b4ebSrica /* system header files */
34*f875b4ebSrica 
35*f875b4ebSrica #include <stdio.h>
36*f875b4ebSrica #include <stdlib.h>
37*f875b4ebSrica #include <string.h>
38*f875b4ebSrica #include <time.h>
39*f875b4ebSrica #include <limits.h>
40*f875b4ebSrica #include <errno.h>
41*f875b4ebSrica #include <signal.h>
42*f875b4ebSrica #include <locale.h>
43*f875b4ebSrica #include <tsol/label.h>
44*f875b4ebSrica 
45*f875b4ebSrica /* typedefs */
46*f875b4ebSrica 
47*f875b4ebSrica typedef int BOOL;
48*f875b4ebSrica 
49*f875b4ebSrica /* constants */
50*f875b4ebSrica 
51*f875b4ebSrica #ifndef FALSE
52*f875b4ebSrica #define	FALSE 0
53*f875b4ebSrica #endif
54*f875b4ebSrica #ifndef TRUE
55*f875b4ebSrica #define	TRUE 1
56*f875b4ebSrica #endif
57*f875b4ebSrica 
58*f875b4ebSrica #define	ME "lp.tsol_separator"
59*f875b4ebSrica #define	POSTSCRIPTLIB "/usr/lib/lp/postscript"
60*f875b4ebSrica #define	SEPARATORPS "tsol_separator.ps"
61*f875b4ebSrica #define	BANNERPS "tsol_banner.ps"
62*f875b4ebSrica #define	TRAILERPS "tsol_trailer.ps"
63*f875b4ebSrica #define	MAXUSERLEN 32
64*f875b4ebSrica #define	MAXHOSTLEN 32
65*f875b4ebSrica 
66*f875b4ebSrica /* external variables */
67*f875b4ebSrica 
68*f875b4ebSrica int	optind;			/* Used by getopt */
69*f875b4ebSrica char    *optarg;		/* Used by getopt */
70*f875b4ebSrica 
71*f875b4ebSrica /* prototypes for static functions */
72*f875b4ebSrica 
73*f875b4ebSrica static int ProcessArgs(int argc, char **argv);
74*f875b4ebSrica static void Usage(void);
75*f875b4ebSrica static void ParseUsername(char *input, char *user, char *host);
76*f875b4ebSrica static void EmitPSFile(const char *name);
77*f875b4ebSrica static BOOL EmitFile(FILE *file);
78*f875b4ebSrica static void EmitJobData(void);
79*f875b4ebSrica static void EmitPrologue(void);
80*f875b4ebSrica static void EmitCommandLineInfo(void);
81*f875b4ebSrica static void EmitClockBasedInfo(void);
82*f875b4ebSrica static void EmitLabelInfo(void);
83*f875b4ebSrica static void CopyStdin(void);
84*f875b4ebSrica 
85*f875b4ebSrica /* static variables */
86*f875b4ebSrica 
87*f875b4ebSrica static char *ArgSeparatorPS;
88*f875b4ebSrica static char *ArgBannerPS;
89*f875b4ebSrica static char *ArgTrailerPS;
90*f875b4ebSrica static char *ArgPSLib;
91*f875b4ebSrica static char *ArgPrinter;
92*f875b4ebSrica static char *ArgJobID;
93*f875b4ebSrica static char *ArgUser;
94*f875b4ebSrica static char *ArgTitle;
95*f875b4ebSrica static char *ArgFile;
96*f875b4ebSrica static BOOL ArgReverse;
97*f875b4ebSrica static BOOL ArgNoPageLabels;
98*f875b4ebSrica static int ArgDebugLevel;
99*f875b4ebSrica static FILE *ArgLogFile;
100*f875b4ebSrica static m_label_t *FileLabel;
101*f875b4ebSrica static char *remoteLabel;
102*f875b4ebSrica 
103*f875b4ebSrica int
104*f875b4ebSrica main(int argc, char *argv[])
105*f875b4ebSrica {
106*f875b4ebSrica 	int	err;
107*f875b4ebSrica 	/*
108*f875b4ebSrica 	 * Run immune from typical interruptions, so that
109*f875b4ebSrica 	 * we stand a chance to get the fault message.
110*f875b4ebSrica 	 * EOF (or startup error) is the only way out.
111*f875b4ebSrica 	 */
112*f875b4ebSrica 	(void) signal(SIGHUP, SIG_IGN);
113*f875b4ebSrica 	(void) signal(SIGINT, SIG_IGN);
114*f875b4ebSrica 	(void) signal(SIGQUIT, SIG_IGN);
115*f875b4ebSrica 	(void) signal(SIGTERM, SIG_IGN);
116*f875b4ebSrica 
117*f875b4ebSrica 	(void) setlocale(LC_ALL, "");
118*f875b4ebSrica #if !defined(TEXT_DOMAIN)
119*f875b4ebSrica #define	TEXT_DOMAIN "SYS_TEST"
120*f875b4ebSrica #endif
121*f875b4ebSrica 	(void) textdomain(TEXT_DOMAIN);
122*f875b4ebSrica 
123*f875b4ebSrica 	if (ProcessArgs(argc, argv) != 0)
124*f875b4ebSrica 		exit(1);
125*f875b4ebSrica 
126*f875b4ebSrica 	if ((FileLabel = m_label_alloc(MAC_LABEL)) == NULL)
127*f875b4ebSrica 		exit(1);
128*f875b4ebSrica 	/*
129*f875b4ebSrica 	 * If the job was submitted via remotely, the label of the
130*f875b4ebSrica 	 * remote peer will be set in the SLABEL environment variable
131*f875b4ebSrica 	 * by copying it out of the SECURE structure.
132*f875b4ebSrica 	 *
133*f875b4ebSrica 	 * If there is no SLABEL value, the job was submitted locally
134*f875b4ebSrica 	 * via the named pipe, and the file label can be determined
135*f875b4ebSrica 	 * from its pathname.
136*f875b4ebSrica 	 */
137*f875b4ebSrica 	if ((remoteLabel = getenv("SLABEL")) != NULL) {
138*f875b4ebSrica 		m_label_free(FileLabel);
139*f875b4ebSrica 		FileLabel = NULL;
140*f875b4ebSrica 		if (str_to_label(remoteLabel, &FileLabel, MAC_LABEL,
141*f875b4ebSrica 		    L_NO_CORRECTION, &err) == -1) {
142*f875b4ebSrica 			perror("str_to_label");
143*f875b4ebSrica 			exit(1);
144*f875b4ebSrica 		}
145*f875b4ebSrica 	} else if (getlabel(ArgFile, FileLabel) != 0) {
146*f875b4ebSrica 		(void) fprintf(ArgLogFile,
147*f875b4ebSrica 		    gettext("%1$s: cannot get label of %2$s: %3$s\n"),
148*f875b4ebSrica 		    ME, ArgFile, strerror(errno));
149*f875b4ebSrica 		exit(1);
150*f875b4ebSrica 	}
151*f875b4ebSrica 
152*f875b4ebSrica 	/* All of these functions exit if they encounter an error */
153*f875b4ebSrica 	EmitJobData();
154*f875b4ebSrica 	EmitPSFile(ArgSeparatorPS);
155*f875b4ebSrica 	if (ArgReverse)
156*f875b4ebSrica 		EmitPSFile(ArgTrailerPS);
157*f875b4ebSrica 	else
158*f875b4ebSrica 		EmitPSFile(ArgBannerPS);
159*f875b4ebSrica 	CopyStdin();
160*f875b4ebSrica 	if (ArgReverse)
161*f875b4ebSrica 		EmitPSFile(ArgBannerPS);
162*f875b4ebSrica 	else
163*f875b4ebSrica 		EmitPSFile(ArgTrailerPS);
164*f875b4ebSrica 	if (ArgDebugLevel >= 1)
165*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("Done.\n"));
166*f875b4ebSrica 	m_label_free(FileLabel);
167*f875b4ebSrica 	return (0);
168*f875b4ebSrica }
169*f875b4ebSrica 
170*f875b4ebSrica static void
171*f875b4ebSrica EmitJobData(void)
172*f875b4ebSrica {
173*f875b4ebSrica 	EmitPrologue();
174*f875b4ebSrica 	EmitCommandLineInfo();
175*f875b4ebSrica 	EmitClockBasedInfo();
176*f875b4ebSrica 	EmitLabelInfo();
177*f875b4ebSrica 
178*f875b4ebSrica 	/* Emit ending PostScript code */
179*f875b4ebSrica 	(void) printf("end\n\n");
180*f875b4ebSrica 	(void) printf("%%%% End of code generated by lp.tsol_separator\n\n");
181*f875b4ebSrica 
182*f875b4ebSrica }
183*f875b4ebSrica 
184*f875b4ebSrica static void
185*f875b4ebSrica EmitPrologue(void)
186*f875b4ebSrica {
187*f875b4ebSrica 	/* Emit preliminary PostScript code */
188*f875b4ebSrica 	(void) printf("%%!\n\n");
189*f875b4ebSrica 	(void) printf("%%%% Begin code generated by lp.tsol_separator\n\n");
190*f875b4ebSrica 
191*f875b4ebSrica 	(void) printf("%%%% Create JobDict if it doesn't exist\n");
192*f875b4ebSrica 	(void) printf("userdict /JobDict known not {\n");
193*f875b4ebSrica 	(void) printf("  userdict /JobDict 100 dict put\n");
194*f875b4ebSrica 	(void) printf("} if\n\n");
195*f875b4ebSrica 
196*f875b4ebSrica 	(void) printf("%%%% Define job parameters, including TSOL security "
197*f875b4ebSrica 	    "info\n");
198*f875b4ebSrica 	(void) printf("JobDict\n");
199*f875b4ebSrica 	(void) printf("begin\n");
200*f875b4ebSrica }
201*f875b4ebSrica 
202*f875b4ebSrica /* Emit parameters obtained from command line options */
203*f875b4ebSrica 
204*f875b4ebSrica static void
205*f875b4ebSrica EmitCommandLineInfo(void)
206*f875b4ebSrica {
207*f875b4ebSrica 	char user[MAXUSERLEN + 1];
208*f875b4ebSrica 	char host[MAXHOSTLEN + 1];
209*f875b4ebSrica 
210*f875b4ebSrica 	(void) printf("\t/Job_Printer (%s) def\n", ArgPrinter);
211*f875b4ebSrica 	ParseUsername(ArgUser, user, host);
212*f875b4ebSrica 	(void) printf("\t/Job_Host (%s) def\n", host);
213*f875b4ebSrica 	(void) printf("\t/Job_User (%s) def\n", user);
214*f875b4ebSrica 	(void) printf("\t/Job_JobID (%s) def\n", ArgJobID);
215*f875b4ebSrica 	(void) printf("\t/Job_Title (%s) def\n", ArgTitle);
216*f875b4ebSrica 	(void) printf("\t/Job_DoPageLabels (%s) def\n",
217*f875b4ebSrica 	    ArgNoPageLabels ? "NO" : "YES");
218*f875b4ebSrica 	(void) printf("\n");
219*f875b4ebSrica }
220*f875b4ebSrica 
221*f875b4ebSrica /* Emit parameters generated from the system clock */
222*f875b4ebSrica 
223*f875b4ebSrica static void
224*f875b4ebSrica EmitClockBasedInfo(void)
225*f875b4ebSrica {
226*f875b4ebSrica 	char timebuf[80];
227*f875b4ebSrica 	struct timeval clockval;
228*f875b4ebSrica 
229*f875b4ebSrica 	(void) gettimeofday(&clockval, NULL);
230*f875b4ebSrica 	(void) strftime(timebuf, sizeof (timebuf), NULL,
231*f875b4ebSrica 	    localtime(&clockval.tv_sec));
232*f875b4ebSrica 	(void) printf("\t/Job_Date (%s) def\n", timebuf);
233*f875b4ebSrica 	(void) printf("\t/Job_Hash (%ld) def\n", clockval.tv_usec % 100000L);
234*f875b4ebSrica 	(void) printf("\n");
235*f875b4ebSrica }
236*f875b4ebSrica 
237*f875b4ebSrica /* Emit parameters derived from the SL and IL of the file being printed. */
238*f875b4ebSrica 
239*f875b4ebSrica static void
240*f875b4ebSrica EmitLabelInfo(void)
241*f875b4ebSrica {
242*f875b4ebSrica 	char	*header = NULL;		/* DIA banner page fields */
243*f875b4ebSrica 	char	*label = NULL;
244*f875b4ebSrica 	char	*caveats = NULL;
245*f875b4ebSrica 	char	*channels = NULL;
246*f875b4ebSrica 	char	*page_label = NULL;	/* interior pages label */
247*f875b4ebSrica 
248*f875b4ebSrica 	if (label_to_str(FileLabel, &header, PRINTER_TOP_BOTTOM,
249*f875b4ebSrica 	    DEF_NAMES) != 0) {
250*f875b4ebSrica 		(void) fprintf(ArgLogFile,
251*f875b4ebSrica 		    gettext("%s: label_to_str PRINTER_TOP_BOTTOM: %s.\n"),
252*f875b4ebSrica 		    ME, strerror(errno));
253*f875b4ebSrica 		exit(1);
254*f875b4ebSrica 	}
255*f875b4ebSrica 	if (label_to_str(FileLabel, &label, PRINTER_LABEL,
256*f875b4ebSrica 	    DEF_NAMES) != 0) {
257*f875b4ebSrica 		(void) fprintf(ArgLogFile,
258*f875b4ebSrica 		    gettext("%s: label_to_str PRINTER_LABEL: %s.\n"),
259*f875b4ebSrica 		    ME, strerror(errno));
260*f875b4ebSrica 		exit(1);
261*f875b4ebSrica 	}
262*f875b4ebSrica 	if (label_to_str(FileLabel, &caveats, PRINTER_CAVEATS,
263*f875b4ebSrica 	    DEF_NAMES) != 0) {
264*f875b4ebSrica 		(void) fprintf(ArgLogFile,
265*f875b4ebSrica 		    gettext("%s: label_to_str PRINTER_CAVEATS: %s.\n"),
266*f875b4ebSrica 		    ME, strerror(errno));
267*f875b4ebSrica 		exit(1);
268*f875b4ebSrica 	}
269*f875b4ebSrica 	if (label_to_str(FileLabel, &channels, PRINTER_CHANNELS,
270*f875b4ebSrica 	    DEF_NAMES) != 0) {
271*f875b4ebSrica 		(void) fprintf(ArgLogFile,
272*f875b4ebSrica 		    gettext("%s: label_to_str PRINTER_CHANNELS: %s.\n"),
273*f875b4ebSrica 		    ME, strerror(errno));
274*f875b4ebSrica 		exit(1);
275*f875b4ebSrica 	}
276*f875b4ebSrica 	if (label_to_str(FileLabel, &page_label, M_LABEL,
277*f875b4ebSrica 	    LONG_NAMES) != 0) {
278*f875b4ebSrica 		(void) fprintf(ArgLogFile,
279*f875b4ebSrica 		    gettext("%s: label_to_str M_LABEL: %s.\n"),
280*f875b4ebSrica 		    ME, strerror(errno));
281*f875b4ebSrica 		exit(1);
282*f875b4ebSrica 	}
283*f875b4ebSrica 
284*f875b4ebSrica 	(void) printf("\t/Job_Classification (%s) def\n", header);
285*f875b4ebSrica 	(void) printf("\t/Job_Protect (%s) def\n", label);
286*f875b4ebSrica 	(void) printf("\t/Job_Caveats (%s) def\n", caveats);
287*f875b4ebSrica 	(void) printf("\t/Job_Channels (%s) def\n", channels);
288*f875b4ebSrica 	(void) printf("\t/Job_SL_Internal (%s) def\n", page_label);
289*f875b4ebSrica 
290*f875b4ebSrica 	/* Free memory allocated label_to_str */
291*f875b4ebSrica 	free(header);
292*f875b4ebSrica 	free(label);
293*f875b4ebSrica 	free(caveats);
294*f875b4ebSrica 	free(channels);
295*f875b4ebSrica 	free(page_label);
296*f875b4ebSrica }
297*f875b4ebSrica 
298*f875b4ebSrica /*
299*f875b4ebSrica  * Parse input "host!user" to separate host and user names.
300*f875b4ebSrica  */
301*f875b4ebSrica 
302*f875b4ebSrica static void
303*f875b4ebSrica ParseUsername(char *input, char *user, char *host)
304*f875b4ebSrica {
305*f875b4ebSrica 	char *cp;
306*f875b4ebSrica 
307*f875b4ebSrica 	if ((cp = strchr(input, '@')) != NULL) {
308*f875b4ebSrica 		/* user@host */
309*f875b4ebSrica 		(void) strlcpy(host, cp + 1, MAXHOSTLEN + 1);
310*f875b4ebSrica 		*cp = '\0';
311*f875b4ebSrica 		(void) strlcpy(user, input, MAXUSERLEN + 1);
312*f875b4ebSrica 		*cp = '@';
313*f875b4ebSrica 	} else if ((cp = strchr(input, '!')) != NULL) {
314*f875b4ebSrica 		/* host!user */
315*f875b4ebSrica 		(void) strlcpy(user, cp + 1, MAXUSERLEN + 1);
316*f875b4ebSrica 		*cp = '\0';
317*f875b4ebSrica 		(void) strlcpy(host, input, MAXHOSTLEN + 1);
318*f875b4ebSrica 		*cp = '!';
319*f875b4ebSrica 	} else {
320*f875b4ebSrica 		/* user */
321*f875b4ebSrica 		(void) strlcpy(user, input, MAXUSERLEN + 1);
322*f875b4ebSrica 		host[0] = '\0';
323*f875b4ebSrica 	}
324*f875b4ebSrica }
325*f875b4ebSrica 
326*f875b4ebSrica 
327*f875b4ebSrica static void
328*f875b4ebSrica CopyStdin(void)
329*f875b4ebSrica {
330*f875b4ebSrica 	if (!EmitFile(stdin)) {
331*f875b4ebSrica 		(void) fprintf(ArgLogFile,
332*f875b4ebSrica 		    gettext("%s: Error copying stdin to stdout\n"), ME);
333*f875b4ebSrica 		exit(1);
334*f875b4ebSrica 	}
335*f875b4ebSrica }
336*f875b4ebSrica 
337*f875b4ebSrica 
338*f875b4ebSrica static BOOL
339*f875b4ebSrica EmitFile(FILE *file)
340*f875b4ebSrica {
341*f875b4ebSrica 	int len;
342*f875b4ebSrica #define	BUFLEN 1024
343*f875b4ebSrica 	char buf[BUFLEN];
344*f875b4ebSrica 
345*f875b4ebSrica 	while ((len = fread(buf, 1, BUFLEN, file)) > 0) {
346*f875b4ebSrica 		if (fwrite(buf, 1, len, stdout) != len)
347*f875b4ebSrica 			return (FALSE);
348*f875b4ebSrica 	}
349*f875b4ebSrica 	if (!feof(file))
350*f875b4ebSrica 		return (FALSE);
351*f875b4ebSrica 	return (TRUE);
352*f875b4ebSrica }
353*f875b4ebSrica 
354*f875b4ebSrica 
355*f875b4ebSrica static void
356*f875b4ebSrica EmitPSFile(const char *name)
357*f875b4ebSrica {
358*f875b4ebSrica 	char path[PATH_MAX];
359*f875b4ebSrica 	FILE *file;
360*f875b4ebSrica 	BOOL emitted;
361*f875b4ebSrica 
362*f875b4ebSrica 	if (name[0] != '/') {
363*f875b4ebSrica 		(void) strlcpy(path, ArgPSLib, sizeof (path));
364*f875b4ebSrica 		(void) strlcat(path, "/", sizeof (path));
365*f875b4ebSrica 		(void) strlcat(path, name, sizeof (path));
366*f875b4ebSrica 	} else {
367*f875b4ebSrica 		(void) strlcpy(path, name, sizeof (path));
368*f875b4ebSrica 	}
369*f875b4ebSrica 
370*f875b4ebSrica 	file = fopen(path, "r");
371*f875b4ebSrica 	if (file == NULL) {
372*f875b4ebSrica 		(void) fprintf(ArgLogFile,
373*f875b4ebSrica 		    gettext("%s: Error opening PostScript file %s. %s.\n"),
374*f875b4ebSrica 		    ME, path, strerror(errno));
375*f875b4ebSrica 		exit(1);
376*f875b4ebSrica 	}
377*f875b4ebSrica 
378*f875b4ebSrica 	emitted = EmitFile(file);
379*f875b4ebSrica 	(void) fclose(file);
380*f875b4ebSrica 	if (!emitted) {
381*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext(
382*f875b4ebSrica 		    "%s: Error copying PostScript file %s to stdout.\n"),
383*f875b4ebSrica 		    ME, path);
384*f875b4ebSrica 		exit(1);
385*f875b4ebSrica 	}
386*f875b4ebSrica }
387*f875b4ebSrica 
388*f875b4ebSrica 
389*f875b4ebSrica static int
390*f875b4ebSrica ProcessArgs(int argc, char *argv[])
391*f875b4ebSrica {
392*f875b4ebSrica 	int	option_letter;
393*f875b4ebSrica 	char	*options_string = "lrd:e:s:b:t:L:";
394*f875b4ebSrica 
395*f875b4ebSrica 	/* set default values for arguments */
396*f875b4ebSrica 	ArgSeparatorPS = SEPARATORPS;
397*f875b4ebSrica 	ArgBannerPS = BANNERPS;
398*f875b4ebSrica 	ArgTrailerPS = TRAILERPS;
399*f875b4ebSrica 	ArgPSLib = POSTSCRIPTLIB;
400*f875b4ebSrica 	ArgNoPageLabels = ArgReverse = FALSE;
401*f875b4ebSrica 	ArgDebugLevel = 0;
402*f875b4ebSrica 	ArgLogFile = stderr;
403*f875b4ebSrica 
404*f875b4ebSrica 	/* read switch arguments once to get error log file */
405*f875b4ebSrica 	while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
406*f875b4ebSrica 		switch (option_letter) {
407*f875b4ebSrica 		case 'd':
408*f875b4ebSrica 			ArgDebugLevel = atoi(optarg);
409*f875b4ebSrica 			break;
410*f875b4ebSrica 		case 'e':
411*f875b4ebSrica 			ArgLogFile = fopen(optarg, "a");
412*f875b4ebSrica 			if (ArgLogFile == NULL) {
413*f875b4ebSrica 				(void) fprintf(stderr,
414*f875b4ebSrica 				    gettext("Cannot open log file %s\n"),
415*f875b4ebSrica 				    optarg);
416*f875b4ebSrica 				return (-1);
417*f875b4ebSrica 			}
418*f875b4ebSrica 			break;
419*f875b4ebSrica 		case '?':	/* ? or unrecognized option */
420*f875b4ebSrica 			Usage();
421*f875b4ebSrica 			return (-1);
422*f875b4ebSrica 		}
423*f875b4ebSrica 	}
424*f875b4ebSrica 
425*f875b4ebSrica 	if (ArgDebugLevel > 0)
426*f875b4ebSrica 		(void) fprintf(ArgLogFile,
427*f875b4ebSrica 		    gettext("Processing switch arguments\n"));
428*f875b4ebSrica 
429*f875b4ebSrica 	/* re-read switch arguments */
430*f875b4ebSrica 	optind = 1;
431*f875b4ebSrica 	while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
432*f875b4ebSrica 		switch (option_letter) {
433*f875b4ebSrica 		case 'd':
434*f875b4ebSrica 			ArgDebugLevel = atoi(optarg);
435*f875b4ebSrica 			break;
436*f875b4ebSrica 		case 'e':
437*f875b4ebSrica 			/* This was handled in earlier pass through args */
438*f875b4ebSrica 			break;
439*f875b4ebSrica 		case 'l':
440*f875b4ebSrica 			ArgNoPageLabels = TRUE;
441*f875b4ebSrica 			break;
442*f875b4ebSrica 		case 'r':
443*f875b4ebSrica 			ArgReverse = TRUE;
444*f875b4ebSrica 			break;
445*f875b4ebSrica 		case 's':
446*f875b4ebSrica 			ArgSeparatorPS = optarg;
447*f875b4ebSrica 			break;
448*f875b4ebSrica 		case 'b':
449*f875b4ebSrica 			ArgBannerPS = optarg;
450*f875b4ebSrica 			break;
451*f875b4ebSrica 		case 't':
452*f875b4ebSrica 			ArgTrailerPS = optarg;
453*f875b4ebSrica 			break;
454*f875b4ebSrica 		case 'L':
455*f875b4ebSrica 			ArgPSLib = optarg;
456*f875b4ebSrica 			break;
457*f875b4ebSrica 		case '?':	/* ? or unrecognized option */
458*f875b4ebSrica 			Usage();
459*f875b4ebSrica 			return (-1);
460*f875b4ebSrica 		}
461*f875b4ebSrica 	}
462*f875b4ebSrica 
463*f875b4ebSrica 	/* Adjust arguments to skip over options */
464*f875b4ebSrica 	argc -= optind;		/* Number of remaining(non-switch) args */
465*f875b4ebSrica 	argv += optind;		/* argv[0] is first(non-switch) args */
466*f875b4ebSrica 
467*f875b4ebSrica 	if (argc != 5) {
468*f875b4ebSrica 		(void) fprintf(ArgLogFile,
469*f875b4ebSrica 		    gettext("Wrong number of arguments.\n\n"));
470*f875b4ebSrica 		Usage();
471*f875b4ebSrica 		return (-1);
472*f875b4ebSrica 	}
473*f875b4ebSrica 
474*f875b4ebSrica 	ArgPrinter = argv++[0];
475*f875b4ebSrica 	ArgJobID = argv++[0];
476*f875b4ebSrica 	ArgUser = argv++[0];
477*f875b4ebSrica 	ArgTitle = argv++[0];
478*f875b4ebSrica 	ArgFile = argv++[0];
479*f875b4ebSrica 
480*f875b4ebSrica 	if (ArgDebugLevel >= 1) {
481*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("Arguments processed\n"));
482*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("Printer: %s\n"),
483*f875b4ebSrica 		    ArgPrinter);
484*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("Job ID: %s\n"), ArgJobID);
485*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("User: %s\n"), ArgUser);
486*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("Title: %s\n"), ArgTitle);
487*f875b4ebSrica 		(void) fprintf(ArgLogFile, gettext("File: %s\n"), ArgFile);
488*f875b4ebSrica 	}
489*f875b4ebSrica 
490*f875b4ebSrica 	return (0);
491*f875b4ebSrica }
492*f875b4ebSrica 
493*f875b4ebSrica 
494*f875b4ebSrica static void
495*f875b4ebSrica Usage(void)
496*f875b4ebSrica {
497*f875b4ebSrica 	static const char *OPTFMT = "    %-8s %-9s %s\n";
498*f875b4ebSrica 
499*f875b4ebSrica 	(void) fprintf(ArgLogFile,
500*f875b4ebSrica 	    gettext("Usage:  lp.tsol_separator [OPTIONS] %s\n"),
501*f875b4ebSrica 	    gettext("PRINTER JOBID HOST!USER TITLE FILE"));
502*f875b4ebSrica 	(void) fprintf(ArgLogFile, gettext("  OPTIONS:\n"));
503*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, "-r", gettext("Reverse"),
504*f875b4ebSrica 	    gettext("Reverse banner/trailer order"));
505*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, "-l", gettext("Labels"),
506*f875b4ebSrica 	    gettext("Suppress page header/footer labels"));
507*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-b FILE"),
508*f875b4ebSrica 	    gettext("Banner"),
509*f875b4ebSrica 	    gettext("PostScript program for banner (default tsol_banner.ps)"));
510*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-s FILE"),
511*f875b4ebSrica 	    gettext("Separator"),
512*f875b4ebSrica 	    gettext("PostScript program for separator "
513*f875b4ebSrica 	    "(default tsol_separator.ps)"));
514*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-t FILE"),
515*f875b4ebSrica 	    gettext("Trailer"),
516*f875b4ebSrica 	    gettext("PostScript program for trailer "
517*f875b4ebSrica 	    "(default tsol_trailer.ps)"));
518*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-L DIR"),
519*f875b4ebSrica 	    gettext("Library"),
520*f875b4ebSrica 	    gettext("Directory to search for PostScript programs"));
521*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, "", "",
522*f875b4ebSrica 	    gettext("(default /usr/lib/lp/postscript)"));
523*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-d N"), gettext("Debug"),
524*f875b4ebSrica 	    gettext("Set debug level to N"));
525*f875b4ebSrica 	(void) fprintf(ArgLogFile, OPTFMT, gettext("-e FILE"),
526*f875b4ebSrica 	    gettext("Error File"),
527*f875b4ebSrica 	    gettext("Append error and debugging output to FILE"));
528*f875b4ebSrica }
529