xref: /titanic_51/usr/src/cmd/lp/model/netpr/bsd_misc.c (revision 7b840e52d558c34b70cbcde044d8d79852d169d2)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <libintl.h>
32 #include <signal.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <syslog.h>
36 #include "netpr.h"
37 #include "netdebug.h"
38 
39 static int job_primitive(np_bsdjob_t *, char, char *);
40 static int create_cfA_file(np_bsdjob_t *);
41 static char * create_cfname(np_bsdjob_t *);
42 static char * create_dfname(np_bsdjob_t *);
43 extern char data_file_type;
44 
45 np_bsdjob_t *
46 create_bsd_job(np_job_t * injob, int pr_order, int filesize)
47 {
48 
49 	np_bsdjob_t *job;
50 	char *id;
51 	int x;
52 	np_data_t * jobdata;
53 
54 	if ((injob->request_id == NULL) || (injob->username == NULL) ||
55 	    (injob->dest == NULL) || (injob->printer ==  NULL)) {
56 		return (NULL);
57 	}
58 
59 	job = (np_bsdjob_t *)malloc(sizeof (np_bsdjob_t));
60 	ASSERT(job, MALLOC_ERR);
61 	(void) memset(job, 0, sizeof (np_bsdjob_t));
62 	/*
63 	 * request-id comes in as printer-number
64 	 * pull apart to create number
65 	 */
66 	if ((id = strrchr(injob->request_id, (int)'-')) == NULL) {
67 		(void) fprintf(stderr,
68 		gettext("Netpr: request_id in unknown format:<%s>\n"),
69 			injob->request_id);
70 		syslog(LOG_DEBUG, "request id in unknown format: %s",
71 			injob->request_id);
72 		return (NULL);
73 	}
74 
75 	id++;
76 
77 	/*
78 	 * 4261563 - A ID collides with an existing one, it plus
79 	 * 1,000 with the ID causes breaking
80 	 * Max job id for bsd is 999.
81 	 */
82 	job->np_request_id = malloc(4);
83 	ASSERT(job->np_request_id, MALLOC_ERR);
84 	errno = 0;
85 	x = atoi(id);
86 	if ((errno != 0) || (x < 0)) {
87 		x = 0;
88 	}
89 	(void) snprintf(job->np_request_id, (size_t) 4,
90 	    "%.3d", x % 1000);
91 
92 	/* seperate the user/host from host!user or user@host */
93 	if ((id = strchr(injob->username, '@')) != NULL) {
94 		*id++ = '\0';
95 		job->np_username = strdup(injob->username);
96 		job->np_host = strdup(id);
97 		*--id = '@';
98 	} else if ((id = strrchr(injob->username, '!')) != NULL) {
99 		*id++ = '\0';
100 		job->np_username = strdup(id);
101 		job->np_host = strdup(injob->username);
102 		*--id = '!';
103 	} else {
104 		syslog(LOG_DEBUG, "using localhost for user %s",
105 			injob->username);
106 		job->np_username = strdup(injob->username);
107 		job->np_host = strdup("localhost");
108 	}
109 
110 	job->np_printer = injob->printer;
111 	job->np_filename = injob->filename;
112 
113 	job->np_df_letter = 'A';
114 
115 	/* build cfAfilename: (cfA)(np_request_id)(np_host) */
116 	if ((job->np_cfAfilename = create_cfname(job)) == NULL) {
117 		(void) fprintf(stderr,
118 			gettext("Netpr: System error creating cfAfilename\n"));
119 			syslog(LOG_DEBUG, "System error creating cfAfilename");
120 		return (NULL);
121 	}
122 
123 	job->np_timeout = injob->timeout;
124 	job->np_banner = injob->banner;
125 	job->np_print_order = pr_order;
126 
127 	if (injob->title == NULL)
128 		job->np_title = injob->filename;
129 	else
130 		job->np_title = injob->title;
131 
132 	if ((create_cfA_file(job)) == -1) {
133 		(void) fprintf(stderr,
134 		gettext("Netpr: Cannot create bsd control file\n"));
135 		syslog(LOG_DEBUG, "Cannot create bsd control file");
136 		return (NULL);
137 	}
138 
139 	/* Now we have a title, add to the control file */
140 	if (injob->banner == BANNER) {
141 		(void) job_primitive(job, 'C', job->np_host);
142 		(void) job_primitive(job, 'J', job->np_title);
143 		(void) job_primitive(job, 'L', job->np_username);
144 	}
145 
146 
147 	/* create dfname for this file */
148 
149 	/* allocate the jobdata and initialize what we have so far */
150 	jobdata = malloc(sizeof (np_data_t));
151 	ASSERT(jobdata, MALLOC_ERR);
152 	(void) memset(jobdata, 0, sizeof (np_data_t));
153 
154 	jobdata->np_path_file = malloc(strlen(job->np_filename) + 1);
155 	ASSERT(jobdata->np_path_file, MALLOC_ERR);
156 	(void) strcpy(jobdata->np_path_file, job->np_filename);
157 
158 	jobdata->np_data_size = filesize;
159 
160 	if ((jobdata->np_dfAfilename = create_dfname(job)) == NULL) {
161 		return (NULL);
162 	}
163 
164 	/*
165 	 * data_file_type should contain the RFC-1179 control file message
166 	 * type for the control file.  The is is set via the "-f" option
167 	 * to netpr, which get it from the "destination-full-control-file-type"
168 	 * option passed in.  Normally this will be either 'l' or 'f'.
169 	 */
170 	if (data_file_type != 0) {
171 		(void) job_primitive(job, data_file_type,
172 				jobdata->np_dfAfilename);
173 		(void) job_primitive(job, 'U', jobdata->np_dfAfilename);
174 		(void) job_primitive(job, 'N', "print-data");
175 	}
176 
177 	syslog(LOG_DEBUG, "data file info: %s", job->np_cfAfile);
178 
179 	/*
180 	 * attach np_data to bsdjob
181 	 */
182 	job->np_data = jobdata;
183 
184 	return (job);
185 }
186 
187 
188 /*
189  * Create df<x>name for this file
190  * df<X><nnn><hostname>
191  */
192 static char *
193 create_dfname(np_bsdjob_t *job)
194 {
195 	char * dfname;
196 
197 	if (job == NULL)
198 		return (NULL);
199 
200 	/* Trying to print too many files */
201 	if (job->np_df_letter > 'z') {
202 		errno = ENFILE;
203 		return (NULL);
204 	}
205 
206 	dfname = (char *)malloc(strlen(job->np_host) + 3 + 3 + 1);
207 	ASSERT(dfname, MALLOC_ERR);
208 	(void) memset(dfname, 0, strlen(job->np_host) + 3 + 3 + 1);
209 	(void) sprintf(dfname, "%s%c%s%s", "df", job->np_df_letter,
210 	    job->np_request_id, job->np_host);
211 
212 	/* udate np_df_letter for the next caller */
213 	job->np_df_letter += 1;
214 	if ((job->np_df_letter > 'Z') && (job->np_df_letter < 'a'))
215 		job->np_df_letter = 'a';
216 
217 	return (dfname);
218 }
219 
220 static char *
221 create_cfname(np_bsdjob_t * job)
222 {
223 	char * cfname;
224 
225 	if (job == NULL)
226 		return (NULL);
227 
228 	cfname = (char *)malloc(strlen(job->np_host) + 3 + 3 + 1);
229 	ASSERT(cfname, MALLOC_ERR);
230 	(void) memset(cfname, 0, strlen(job->np_host) + 3 + 3 + 1);
231 	(void) sprintf(cfname, "%s%s%s", "cfA",
232 	job->np_request_id, job->np_host);
233 	return (cfname);
234 }
235 
236 static int
237 create_cfA_file(np_bsdjob_t *job)
238 {
239 	/*
240 	 * Read through job structure, creating entries
241 	 * in control file as appropriate
242 	 */
243 	if ((job->np_host == NULL) || (job->np_username == NULL)) {
244 		(void) fprintf(stderr, gettext(
245 		"Netpr: Missing required data, cannot build control file\n"));
246 		return (-1);
247 	}
248 	(void) job_primitive(job, 'H', job->np_host);
249 	(void) job_primitive(job, 'P', job->np_username);
250 
251 	return (0);
252 }
253 
254 static int
255 job_primitive(np_bsdjob_t * job, char option, char *value)
256 {
257 	char buf[BUFSIZ];
258 
259 	if ((job == NULL) || (value == NULL))
260 		return (-1);
261 
262 	job->np_cfAfilesize += strlen(value) + 2; /* (opt)(value)\n */
263 	if (job->np_cfAfile == NULL) {
264 		/* Always allocate one greater than cfAfilesize for the \0 */
265 		job->np_cfAfile = calloc(1, job->np_cfAfilesize + 1);
266 		ASSERT(job->np_cfAfile, MALLOC_ERR);
267 	} else {
268 		job->np_cfAfile = realloc(job->np_cfAfile,
269 			job->np_cfAfilesize + 1);
270 		ASSERT(job->np_cfAfile, REALLOC_ERR);
271 	}
272 	(void) snprintf(buf, sizeof (buf),  "%c%s\n", option, value);
273 	(void) strcat(job->np_cfAfile, buf);
274 	syslog(LOG_DEBUG, "adding: %d %s", job->np_cfAfilesize, buf);
275 
276 	return (0);
277 }
278