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