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