xref: /onnv-gate/usr/src/cmd/fs.d/smbclnt/smbutil/print.c (revision 10023:71bf38dba3d6)
16007Sthurlow /*
26007Sthurlow  * Copyright (c) 2000, Boris Popov
36007Sthurlow  * All rights reserved.
46007Sthurlow  *
56007Sthurlow  * Redistribution and use in source and binary forms, with or without
66007Sthurlow  * modification, are permitted provided that the following conditions
76007Sthurlow  * are met:
86007Sthurlow  * 1. Redistributions of source code must retain the above copyright
96007Sthurlow  *    notice, this list of conditions and the following disclaimer.
106007Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
116007Sthurlow  *    notice, this list of conditions and the following disclaimer in the
126007Sthurlow  *    documentation and/or other materials provided with the distribution.
136007Sthurlow  * 3. All advertising materials mentioning features or use of this software
146007Sthurlow  *    must display the following acknowledgement:
156007Sthurlow  *    This product includes software developed by Boris Popov.
166007Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
176007Sthurlow  *    may be used to endorse or promote products derived from this software
186007Sthurlow  *    without specific prior written permission.
196007Sthurlow  *
206007Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
216007Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
226007Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
236007Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
246007Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
256007Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
266007Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
276007Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
286007Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
296007Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
306007Sthurlow  * SUCH DAMAGE.
316007Sthurlow  *
32*10023SGordon.Ross@Sun.COM  * from: Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp
33*10023SGordon.Ross@Sun.COM  */
34*10023SGordon.Ross@Sun.COM 
35*10023SGordon.Ross@Sun.COM /*
36*10023SGordon.Ross@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
37*10023SGordon.Ross@Sun.COM  * Use is subject to license terms.
386007Sthurlow  */
396007Sthurlow 
40*10023SGordon.Ross@Sun.COM #include <sys/types.h>
41*10023SGordon.Ross@Sun.COM #include <err.h>
42*10023SGordon.Ross@Sun.COM #include <errno.h>
436007Sthurlow #include <fcntl.h>
446007Sthurlow #include <stdio.h>
45*10023SGordon.Ross@Sun.COM #include <string.h>
46*10023SGordon.Ross@Sun.COM #include <stdlib.h>
476007Sthurlow #include <unistd.h>
486007Sthurlow #include <libintl.h>
496007Sthurlow 
506007Sthurlow #include <cflib.h>
516007Sthurlow 
526007Sthurlow #include <netsmb/smb_lib.h>
536007Sthurlow 
546007Sthurlow #include "common.h"
556007Sthurlow 
56*10023SGordon.Ross@Sun.COM static char titlebuf[256];
57*10023SGordon.Ross@Sun.COM static char databuf[4096];
586007Sthurlow 
59*10023SGordon.Ross@Sun.COM static int print_file(smb_ctx_t *, char *, int);
606007Sthurlow 
616007Sthurlow void
print_usage(void)626007Sthurlow print_usage(void)
636007Sthurlow {
646007Sthurlow 	printf(gettext("usage: smbutil print [connection options] //"
656007Sthurlow 	    "[workgroup;][user[:password]@]"
66*10023SGordon.Ross@Sun.COM 	    "server/share  {print_file|-}\n"));
676007Sthurlow 	exit(1);
686007Sthurlow }
69*10023SGordon.Ross@Sun.COM 
70*10023SGordon.Ross@Sun.COM int
cmd_print(int argc,char * argv[])71*10023SGordon.Ross@Sun.COM cmd_print(int argc, char *argv[])
72*10023SGordon.Ross@Sun.COM {
73*10023SGordon.Ross@Sun.COM 	struct smb_ctx *ctx = NULL;
74*10023SGordon.Ross@Sun.COM 	char *filename;
75*10023SGordon.Ross@Sun.COM 	int error, opt;
76*10023SGordon.Ross@Sun.COM 	int file = -1;
77*10023SGordon.Ross@Sun.COM 
78*10023SGordon.Ross@Sun.COM 	/* last arg is the print file. */
79*10023SGordon.Ross@Sun.COM 	if (argc < 3)
80*10023SGordon.Ross@Sun.COM 		print_usage();
81*10023SGordon.Ross@Sun.COM 
82*10023SGordon.Ross@Sun.COM 	error = smb_ctx_alloc(&ctx);
83*10023SGordon.Ross@Sun.COM 	if (error)
84*10023SGordon.Ross@Sun.COM 		goto out;
85*10023SGordon.Ross@Sun.COM 
86*10023SGordon.Ross@Sun.COM 	error = smb_ctx_scan_argv(ctx, argc-1, argv,
87*10023SGordon.Ross@Sun.COM 	    SMBL_SHARE, SMBL_SHARE, USE_SPOOLDEV);
88*10023SGordon.Ross@Sun.COM 	if (error)
89*10023SGordon.Ross@Sun.COM 		goto out;
90*10023SGordon.Ross@Sun.COM 
91*10023SGordon.Ross@Sun.COM 	error = smb_ctx_readrc(ctx);
92*10023SGordon.Ross@Sun.COM 	if (error)
93*10023SGordon.Ross@Sun.COM 		goto out;
94*10023SGordon.Ross@Sun.COM 
95*10023SGordon.Ross@Sun.COM 	while ((opt = getopt(argc-1, argv, STDPARAM_OPT)) != EOF) {
96*10023SGordon.Ross@Sun.COM 		if (opt == '?')
97*10023SGordon.Ross@Sun.COM 			print_usage();
98*10023SGordon.Ross@Sun.COM 		error = smb_ctx_opt(ctx, opt, optarg);
99*10023SGordon.Ross@Sun.COM 		if (error)
100*10023SGordon.Ross@Sun.COM 			goto out;
101*10023SGordon.Ross@Sun.COM 	}
102*10023SGordon.Ross@Sun.COM 	if (optind != argc-2)
103*10023SGordon.Ross@Sun.COM 		print_usage();
104*10023SGordon.Ross@Sun.COM 	filename = argv[argc-1];
105*10023SGordon.Ross@Sun.COM 
106*10023SGordon.Ross@Sun.COM 	if (strcmp(filename, "-") == 0) {
107*10023SGordon.Ross@Sun.COM 		file = 0;	/* stdin */
108*10023SGordon.Ross@Sun.COM 		filename = "stdin";
109*10023SGordon.Ross@Sun.COM 	} else {
110*10023SGordon.Ross@Sun.COM 		file = open(filename, O_RDONLY, 0);
111*10023SGordon.Ross@Sun.COM 		if (file < 0) {
112*10023SGordon.Ross@Sun.COM 			smb_error("could not open file %s\n", errno, filename);
113*10023SGordon.Ross@Sun.COM 			exit(1);
114*10023SGordon.Ross@Sun.COM 		}
115*10023SGordon.Ross@Sun.COM 	}
116*10023SGordon.Ross@Sun.COM 
117*10023SGordon.Ross@Sun.COM 	/*
118*10023SGordon.Ross@Sun.COM 	 * Resolve the server address,
119*10023SGordon.Ross@Sun.COM 	 * setup derived defaults.
120*10023SGordon.Ross@Sun.COM 	 */
121*10023SGordon.Ross@Sun.COM 	error = smb_ctx_resolve(ctx);
122*10023SGordon.Ross@Sun.COM 	if (error)
123*10023SGordon.Ross@Sun.COM 		goto out;
124*10023SGordon.Ross@Sun.COM 
125*10023SGordon.Ross@Sun.COM 	/*
126*10023SGordon.Ross@Sun.COM 	 * Have server + share names, options etc.
127*10023SGordon.Ross@Sun.COM 	 * Get the session and tree.
128*10023SGordon.Ross@Sun.COM 	 */
129*10023SGordon.Ross@Sun.COM again:
130*10023SGordon.Ross@Sun.COM 	error = smb_ctx_get_ssn(ctx);
131*10023SGordon.Ross@Sun.COM 	if (error == EAUTH) {
132*10023SGordon.Ross@Sun.COM 		int err2 = smb_get_authentication(ctx);
133*10023SGordon.Ross@Sun.COM 		if (err2 == 0)
134*10023SGordon.Ross@Sun.COM 			goto again;
135*10023SGordon.Ross@Sun.COM 	}
136*10023SGordon.Ross@Sun.COM 	if (error) {
137*10023SGordon.Ross@Sun.COM 		smb_error(gettext("//%s: login failed"),
138*10023SGordon.Ross@Sun.COM 		    error, ctx->ct_fullserver);
139*10023SGordon.Ross@Sun.COM 		goto out;
140*10023SGordon.Ross@Sun.COM 	}
141*10023SGordon.Ross@Sun.COM 
142*10023SGordon.Ross@Sun.COM 	error = smb_ctx_get_tree(ctx);
143*10023SGordon.Ross@Sun.COM 	if (error) {
144*10023SGordon.Ross@Sun.COM 		smb_error(gettext("//%s/%s: tree connect failed"),
145*10023SGordon.Ross@Sun.COM 		    error, ctx->ct_fullserver, ctx->ct_origshare);
146*10023SGordon.Ross@Sun.COM 		goto out;
147*10023SGordon.Ross@Sun.COM 	}
148*10023SGordon.Ross@Sun.COM 
149*10023SGordon.Ross@Sun.COM 	/*
150*10023SGordon.Ross@Sun.COM 	 * Have the printer share connection.
151*10023SGordon.Ross@Sun.COM 	 * Print the file.
152*10023SGordon.Ross@Sun.COM 	 */
153*10023SGordon.Ross@Sun.COM 	snprintf(titlebuf, sizeof (titlebuf), "%s_%s",
154*10023SGordon.Ross@Sun.COM 	    ctx->ct_user, filename);
155*10023SGordon.Ross@Sun.COM 
156*10023SGordon.Ross@Sun.COM 	error = print_file(ctx, titlebuf, file);
157*10023SGordon.Ross@Sun.COM 
158*10023SGordon.Ross@Sun.COM 
159*10023SGordon.Ross@Sun.COM out:
160*10023SGordon.Ross@Sun.COM 	/* don't close stdin (file=0) */
161*10023SGordon.Ross@Sun.COM 	if (file > 0)
162*10023SGordon.Ross@Sun.COM 		close(file);
163*10023SGordon.Ross@Sun.COM 
164*10023SGordon.Ross@Sun.COM 	smb_ctx_free(ctx);
165*10023SGordon.Ross@Sun.COM 
166*10023SGordon.Ross@Sun.COM 	return (error);
167*10023SGordon.Ross@Sun.COM }
168*10023SGordon.Ross@Sun.COM 
169*10023SGordon.Ross@Sun.COM /*
170*10023SGordon.Ross@Sun.COM  * Documentation for OPEN_PRINT_FILE is scarse.
171*10023SGordon.Ross@Sun.COM  * It's in a 1996 MS doc. entitled:
172*10023SGordon.Ross@Sun.COM  * SMB FILE SHARING PROTOCOL
173*10023SGordon.Ross@Sun.COM  *
174*10023SGordon.Ross@Sun.COM  * The extra parameters are:
175*10023SGordon.Ross@Sun.COM  *   SetupLength: what part of the file is printer setup
176*10023SGordon.Ross@Sun.COM  *   Mode: text or graphics (raw data)
177*10023SGordon.Ross@Sun.COM  *   IdentifierString:  job title
178*10023SGordon.Ross@Sun.COM  */
179*10023SGordon.Ross@Sun.COM enum {
180*10023SGordon.Ross@Sun.COM 	MODE_TEXT = 0,	/* TAB expansion, etc. */
181*10023SGordon.Ross@Sun.COM 	MODE_GRAPHICS	/* raw data */
182*10023SGordon.Ross@Sun.COM };
183*10023SGordon.Ross@Sun.COM 
184*10023SGordon.Ross@Sun.COM static int
print_file(smb_ctx_t * ctx,char * title,int file)185*10023SGordon.Ross@Sun.COM print_file(smb_ctx_t *ctx, char *title, int file)
186*10023SGordon.Ross@Sun.COM {
187*10023SGordon.Ross@Sun.COM 	off_t offset;
188*10023SGordon.Ross@Sun.COM 	int error, rcnt, wcnt;
189*10023SGordon.Ross@Sun.COM 	int setup_len = 0;		/* No printer setup data */
190*10023SGordon.Ross@Sun.COM 	int mode = MODE_GRAPHICS;	/* treat as raw data */
191*10023SGordon.Ross@Sun.COM 	int fh = -1;
192*10023SGordon.Ross@Sun.COM 
193*10023SGordon.Ross@Sun.COM 	error = smb_printer_open(ctx, setup_len, mode, title, &fh);
194*10023SGordon.Ross@Sun.COM 	if (error) {
195*10023SGordon.Ross@Sun.COM 		smb_error("could not open print job", error);
196*10023SGordon.Ross@Sun.COM 		return (error);
197*10023SGordon.Ross@Sun.COM 	}
198*10023SGordon.Ross@Sun.COM 
199*10023SGordon.Ross@Sun.COM 	offset = 0;
200*10023SGordon.Ross@Sun.COM 	for (;;) {
201*10023SGordon.Ross@Sun.COM 		rcnt = read(file, databuf, sizeof (databuf));
202*10023SGordon.Ross@Sun.COM 		if (rcnt < 0) {
203*10023SGordon.Ross@Sun.COM 			error = errno;
204*10023SGordon.Ross@Sun.COM 			smb_error("error reading input file\n", error);
205*10023SGordon.Ross@Sun.COM 			break;
206*10023SGordon.Ross@Sun.COM 		}
207*10023SGordon.Ross@Sun.COM 		if (rcnt == 0)
208*10023SGordon.Ross@Sun.COM 			break;
209*10023SGordon.Ross@Sun.COM 
210*10023SGordon.Ross@Sun.COM 		wcnt = smb_fh_write(ctx, fh, offset, rcnt, databuf);
211*10023SGordon.Ross@Sun.COM 		if (wcnt < 0) {
212*10023SGordon.Ross@Sun.COM 			error = errno;
213*10023SGordon.Ross@Sun.COM 			smb_error("error writing spool file\n", error);
214*10023SGordon.Ross@Sun.COM 			break;
215*10023SGordon.Ross@Sun.COM 		}
216*10023SGordon.Ross@Sun.COM 		if (wcnt != rcnt) {
217*10023SGordon.Ross@Sun.COM 			smb_error("incomplete write to spool file\n", 0);
218*10023SGordon.Ross@Sun.COM 			error = EIO;
219*10023SGordon.Ross@Sun.COM 			break;
220*10023SGordon.Ross@Sun.COM 		}
221*10023SGordon.Ross@Sun.COM 		offset += wcnt;
222*10023SGordon.Ross@Sun.COM 	}
223*10023SGordon.Ross@Sun.COM 
224*10023SGordon.Ross@Sun.COM 	(void) smb_printer_close(ctx, fh);
225*10023SGordon.Ross@Sun.COM 	return (error);
226*10023SGordon.Ross@Sun.COM }
227