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