/usr/src/cmd/lp/model/lp.tsol_separator.c
C | 528 lines | 398 code | 65 blank | 65 comment | 53 complexity | 3ec12b96f5eca77b10ea66bae9c3e869 MD5 | raw file
- /*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
- /*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
- #pragma ident "%Z%%M% %I% %E% SMI"
- /*
- * Add TSOL banner, trailer, page header/footers to a print job
- */
- /* system header files */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <limits.h>
- #include <errno.h>
- #include <signal.h>
- #include <locale.h>
- #include <tsol/label.h>
- /* typedefs */
- typedef int BOOL;
- /* constants */
- #ifndef FALSE
- #define FALSE 0
- #endif
- #ifndef TRUE
- #define TRUE 1
- #endif
- #define ME "lp.tsol_separator"
- #define POSTSCRIPTLIB "/usr/lib/lp/postscript"
- #define SEPARATORPS "tsol_separator.ps"
- #define BANNERPS "tsol_banner.ps"
- #define TRAILERPS "tsol_trailer.ps"
- #define MAXUSERLEN 32
- #define MAXHOSTLEN 32
- /* external variables */
- int optind; /* Used by getopt */
- char *optarg; /* Used by getopt */
- /* prototypes for static functions */
- static int ProcessArgs(int argc, char **argv);
- static void Usage(void);
- static void ParseUsername(char *input, char *user, char *host);
- static void EmitPSFile(const char *name);
- static BOOL EmitFile(FILE *file);
- static void EmitJobData(void);
- static void EmitPrologue(void);
- static void EmitCommandLineInfo(void);
- static void EmitClockBasedInfo(void);
- static void EmitLabelInfo(void);
- static void CopyStdin(void);
- /* static variables */
- static char *ArgSeparatorPS;
- static char *ArgBannerPS;
- static char *ArgTrailerPS;
- static char *ArgPSLib;
- static char *ArgPrinter;
- static char *ArgJobID;
- static char *ArgUser;
- static char *ArgTitle;
- static char *ArgFile;
- static BOOL ArgReverse;
- static BOOL ArgNoPageLabels;
- static int ArgDebugLevel;
- static FILE *ArgLogFile;
- static m_label_t *FileLabel;
- static char *remoteLabel;
- int
- main(int argc, char *argv[])
- {
- int err;
- /*
- * Run immune from typical interruptions, so that
- * we stand a chance to get the fault message.
- * EOF (or startup error) is the only way out.
- */
- (void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
- (void) signal(SIGTERM, SIG_IGN);
- (void) setlocale(LC_ALL, "");
- #if !defined(TEXT_DOMAIN)
- #define TEXT_DOMAIN "SYS_TEST"
- #endif
- (void) textdomain(TEXT_DOMAIN);
- if (ProcessArgs(argc, argv) != 0)
- exit(1);
- if ((FileLabel = m_label_alloc(MAC_LABEL)) == NULL)
- exit(1);
- /*
- * If the job was submitted via remotely, the label of the
- * remote peer will be set in the SLABEL environment variable
- * by copying it out of the SECURE structure.
- *
- * If there is no SLABEL value, the job was submitted locally
- * via the named pipe, and the file label can be determined
- * from its pathname.
- */
- if ((remoteLabel = getenv("SLABEL")) != NULL) {
- m_label_free(FileLabel);
- FileLabel = NULL;
- if (str_to_label(remoteLabel, &FileLabel, MAC_LABEL,
- L_NO_CORRECTION, &err) == -1) {
- perror("str_to_label");
- exit(1);
- }
- } else if (getlabel(ArgFile, FileLabel) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%1$s: cannot get label of %2$s: %3$s\n"),
- ME, ArgFile, strerror(errno));
- exit(1);
- }
- /* All of these functions exit if they encounter an error */
- EmitJobData();
- EmitPSFile(ArgSeparatorPS);
- if (ArgReverse)
- EmitPSFile(ArgTrailerPS);
- else
- EmitPSFile(ArgBannerPS);
- CopyStdin();
- if (ArgReverse)
- EmitPSFile(ArgBannerPS);
- else
- EmitPSFile(ArgTrailerPS);
- if (ArgDebugLevel >= 1)
- (void) fprintf(ArgLogFile, gettext("Done.\n"));
- m_label_free(FileLabel);
- return (0);
- }
- static void
- EmitJobData(void)
- {
- EmitPrologue();
- EmitCommandLineInfo();
- EmitClockBasedInfo();
- EmitLabelInfo();
- /* Emit ending PostScript code */
- (void) printf("end\n\n");
- (void) printf("%%%% End of code generated by lp.tsol_separator\n\n");
- }
- static void
- EmitPrologue(void)
- {
- /* Emit preliminary PostScript code */
- (void) printf("%%!\n\n");
- (void) printf("%%%% Begin code generated by lp.tsol_separator\n\n");
- (void) printf("%%%% Create JobDict if it doesn't exist\n");
- (void) printf("userdict /JobDict known not {\n");
- (void) printf(" userdict /JobDict 100 dict put\n");
- (void) printf("} if\n\n");
- (void) printf("%%%% Define job parameters, including TSOL security "
- "info\n");
- (void) printf("JobDict\n");
- (void) printf("begin\n");
- }
- /* Emit parameters obtained from command line options */
- static void
- EmitCommandLineInfo(void)
- {
- char user[MAXUSERLEN + 1];
- char host[MAXHOSTLEN + 1];
- (void) printf("\t/Job_Printer (%s) def\n", ArgPrinter);
- ParseUsername(ArgUser, user, host);
- (void) printf("\t/Job_Host (%s) def\n", host);
- (void) printf("\t/Job_User (%s) def\n", user);
- (void) printf("\t/Job_JobID (%s) def\n", ArgJobID);
- (void) printf("\t/Job_Title (%s) def\n", ArgTitle);
- (void) printf("\t/Job_DoPageLabels (%s) def\n",
- ArgNoPageLabels ? "NO" : "YES");
- (void) printf("\n");
- }
- /* Emit parameters generated from the system clock */
- static void
- EmitClockBasedInfo(void)
- {
- char timebuf[80];
- struct timeval clockval;
- (void) gettimeofday(&clockval, NULL);
- (void) strftime(timebuf, sizeof (timebuf), NULL,
- localtime(&clockval.tv_sec));
- (void) printf("\t/Job_Date (%s) def\n", timebuf);
- (void) printf("\t/Job_Hash (%ld) def\n", clockval.tv_usec % 100000L);
- (void) printf("\n");
- }
- /* Emit parameters derived from the SL and IL of the file being printed. */
- static void
- EmitLabelInfo(void)
- {
- char *header = NULL; /* DIA banner page fields */
- char *label = NULL;
- char *caveats = NULL;
- char *channels = NULL;
- char *page_label = NULL; /* interior pages label */
- if (label_to_str(FileLabel, &header, PRINTER_TOP_BOTTOM,
- DEF_NAMES) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%s: label_to_str PRINTER_TOP_BOTTOM: %s.\n"),
- ME, strerror(errno));
- exit(1);
- }
- if (label_to_str(FileLabel, &label, PRINTER_LABEL,
- DEF_NAMES) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%s: label_to_str PRINTER_LABEL: %s.\n"),
- ME, strerror(errno));
- exit(1);
- }
- if (label_to_str(FileLabel, &caveats, PRINTER_CAVEATS,
- DEF_NAMES) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%s: label_to_str PRINTER_CAVEATS: %s.\n"),
- ME, strerror(errno));
- exit(1);
- }
- if (label_to_str(FileLabel, &channels, PRINTER_CHANNELS,
- DEF_NAMES) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%s: label_to_str PRINTER_CHANNELS: %s.\n"),
- ME, strerror(errno));
- exit(1);
- }
- if (label_to_str(FileLabel, &page_label, M_LABEL,
- LONG_NAMES) != 0) {
- (void) fprintf(ArgLogFile,
- gettext("%s: label_to_str M_LABEL: %s.\n"),
- ME, strerror(errno));
- exit(1);
- }
- (void) printf("\t/Job_Classification (%s) def\n", header);
- (void) printf("\t/Job_Protect (%s) def\n", label);
- (void) printf("\t/Job_Caveats (%s) def\n", caveats);
- (void) printf("\t/Job_Channels (%s) def\n", channels);
- (void) printf("\t/Job_SL_Internal (%s) def\n", page_label);
- /* Free memory allocated label_to_str */
- free(header);
- free(label);
- free(caveats);
- free(channels);
- free(page_label);
- }
- /*
- * Parse input "host!user" to separate host and user names.
- */
- static void
- ParseUsername(char *input, char *user, char *host)
- {
- char *cp;
- if ((cp = strchr(input, '@')) != NULL) {
- /* user@host */
- (void) strlcpy(host, cp + 1, MAXHOSTLEN + 1);
- *cp = '\0';
- (void) strlcpy(user, input, MAXUSERLEN + 1);
- *cp = '@';
- } else if ((cp = strchr(input, '!')) != NULL) {
- /* host!user */
- (void) strlcpy(user, cp + 1, MAXUSERLEN + 1);
- *cp = '\0';
- (void) strlcpy(host, input, MAXHOSTLEN + 1);
- *cp = '!';
- } else {
- /* user */
- (void) strlcpy(user, input, MAXUSERLEN + 1);
- host[0] = '\0';
- }
- }
- static void
- CopyStdin(void)
- {
- if (!EmitFile(stdin)) {
- (void) fprintf(ArgLogFile,
- gettext("%s: Error copying stdin to stdout\n"), ME);
- exit(1);
- }
- }
- static BOOL
- EmitFile(FILE *file)
- {
- int len;
- #define BUFLEN 1024
- char buf[BUFLEN];
- while ((len = fread(buf, 1, BUFLEN, file)) > 0) {
- if (fwrite(buf, 1, len, stdout) != len)
- return (FALSE);
- }
- if (!feof(file))
- return (FALSE);
- return (TRUE);
- }
- static void
- EmitPSFile(const char *name)
- {
- char path[PATH_MAX];
- FILE *file;
- BOOL emitted;
- if (name[0] != '/') {
- (void) strlcpy(path, ArgPSLib, sizeof (path));
- (void) strlcat(path, "/", sizeof (path));
- (void) strlcat(path, name, sizeof (path));
- } else {
- (void) strlcpy(path, name, sizeof (path));
- }
- file = fopen(path, "r");
- if (file == NULL) {
- (void) fprintf(ArgLogFile,
- gettext("%s: Error opening PostScript file %s. %s.\n"),
- ME, path, strerror(errno));
- exit(1);
- }
- emitted = EmitFile(file);
- (void) fclose(file);
- if (!emitted) {
- (void) fprintf(ArgLogFile, gettext(
- "%s: Error copying PostScript file %s to stdout.\n"),
- ME, path);
- exit(1);
- }
- }
- static int
- ProcessArgs(int argc, char *argv[])
- {
- int option_letter;
- char *options_string = "lrd:e:s:b:t:L:";
- /* set default values for arguments */
- ArgSeparatorPS = SEPARATORPS;
- ArgBannerPS = BANNERPS;
- ArgTrailerPS = TRAILERPS;
- ArgPSLib = POSTSCRIPTLIB;
- ArgNoPageLabels = ArgReverse = FALSE;
- ArgDebugLevel = 0;
- ArgLogFile = stderr;
- /* read switch arguments once to get error log file */
- while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
- switch (option_letter) {
- case 'd':
- ArgDebugLevel = atoi(optarg);
- break;
- case 'e':
- ArgLogFile = fopen(optarg, "a");
- if (ArgLogFile == NULL) {
- (void) fprintf(stderr,
- gettext("Cannot open log file %s\n"),
- optarg);
- return (-1);
- }
- break;
- case '?': /* ? or unrecognized option */
- Usage();
- return (-1);
- }
- }
- if (ArgDebugLevel > 0)
- (void) fprintf(ArgLogFile,
- gettext("Processing switch arguments\n"));
- /* re-read switch arguments */
- optind = 1;
- while ((option_letter = getopt(argc, argv, options_string)) != EOF) {
- switch (option_letter) {
- case 'd':
- ArgDebugLevel = atoi(optarg);
- break;
- case 'e':
- /* This was handled in earlier pass through args */
- break;
- case 'l':
- ArgNoPageLabels = TRUE;
- break;
- case 'r':
- ArgReverse = TRUE;
- break;
- case 's':
- ArgSeparatorPS = optarg;
- break;
- case 'b':
- ArgBannerPS = optarg;
- break;
- case 't':
- ArgTrailerPS = optarg;
- break;
- case 'L':
- ArgPSLib = optarg;
- break;
- case '?': /* ? or unrecognized option */
- Usage();
- return (-1);
- }
- }
- /* Adjust arguments to skip over options */
- argc -= optind; /* Number of remaining(non-switch) args */
- argv += optind; /* argv[0] is first(non-switch) args */
- if (argc != 5) {
- (void) fprintf(ArgLogFile,
- gettext("Wrong number of arguments.\n\n"));
- Usage();
- return (-1);
- }
- ArgPrinter = argv++[0];
- ArgJobID = argv++[0];
- ArgUser = argv++[0];
- ArgTitle = argv++[0];
- ArgFile = argv++[0];
- if (ArgDebugLevel >= 1) {
- (void) fprintf(ArgLogFile, gettext("Arguments processed\n"));
- (void) fprintf(ArgLogFile, gettext("Printer: %s\n"),
- ArgPrinter);
- (void) fprintf(ArgLogFile, gettext("Job ID: %s\n"), ArgJobID);
- (void) fprintf(ArgLogFile, gettext("User: %s\n"), ArgUser);
- (void) fprintf(ArgLogFile, gettext("Title: %s\n"), ArgTitle);
- (void) fprintf(ArgLogFile, gettext("File: %s\n"), ArgFile);
- }
- return (0);
- }
- static void
- Usage(void)
- {
- static const char *OPTFMT = " %-8s %-9s %s\n";
- (void) fprintf(ArgLogFile,
- gettext("Usage: lp.tsol_separator [OPTIONS] %s\n"),
- gettext("PRINTER JOBID HOST!USER TITLE FILE"));
- (void) fprintf(ArgLogFile, gettext(" OPTIONS:\n"));
- (void) fprintf(ArgLogFile, OPTFMT, "-r", gettext("Reverse"),
- gettext("Reverse banner/trailer order"));
- (void) fprintf(ArgLogFile, OPTFMT, "-l", gettext("Labels"),
- gettext("Suppress page header/footer labels"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-b FILE"),
- gettext("Banner"),
- gettext("PostScript program for banner (default tsol_banner.ps)"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-s FILE"),
- gettext("Separator"),
- gettext("PostScript program for separator "
- "(default tsol_separator.ps)"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-t FILE"),
- gettext("Trailer"),
- gettext("PostScript program for trailer "
- "(default tsol_trailer.ps)"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-L DIR"),
- gettext("Library"),
- gettext("Directory to search for PostScript programs"));
- (void) fprintf(ArgLogFile, OPTFMT, "", "",
- gettext("(default /usr/lib/lp/postscript)"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-d N"), gettext("Debug"),
- gettext("Set debug level to N"));
- (void) fprintf(ArgLogFile, OPTFMT, gettext("-e FILE"),
- gettext("Error File"),
- gettext("Append error and debugging output to FILE"));
- }