diff options
Diffstat (limited to 'usr/src/cmd/fs.d/smbclnt/smbutil/print.c')
| -rw-r--r-- | usr/src/cmd/fs.d/smbclnt/smbutil/print.c | 182 |
1 files changed, 172 insertions, 10 deletions
diff --git a/usr/src/cmd/fs.d/smbclnt/smbutil/print.c b/usr/src/cmd/fs.d/smbclnt/smbutil/print.c index dd986e1b49..7379acfd90 100644 --- a/usr/src/cmd/fs.d/smbclnt/smbutil/print.c +++ b/usr/src/cmd/fs.d/smbclnt/smbutil/print.c @@ -29,21 +29,22 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: print.c,v 1.7 2004/03/19 01:49:48 lindak Exp $ + * from: Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp */ -#pragma ident "%Z%%M% %I% %E% SMI" +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ -#include <sys/param.h> -#include <sys/errno.h> -#include <sys/stat.h> +#include <sys/types.h> +#include <err.h> +#include <errno.h> #include <fcntl.h> #include <stdio.h> -#include <err.h> -#include <unistd.h> -#include <strings.h> +#include <string.h> #include <stdlib.h> -#include <sysexits.h> +#include <unistd.h> #include <libintl.h> #include <cflib.h> @@ -52,13 +53,174 @@ #include "common.h" +static char titlebuf[256]; +static char databuf[4096]; +static int print_file(smb_ctx_t *, char *, int); void print_usage(void) { printf(gettext("usage: smbutil print [connection options] //" "[workgroup;][user[:password]@]" - "server/share\n")); + "server/share {print_file|-}\n")); exit(1); } + +int +cmd_print(int argc, char *argv[]) +{ + struct smb_ctx *ctx = NULL; + char *filename; + int error, opt; + int file = -1; + + /* last arg is the print file. */ + if (argc < 3) + print_usage(); + + error = smb_ctx_alloc(&ctx); + if (error) + goto out; + + error = smb_ctx_scan_argv(ctx, argc-1, argv, + SMBL_SHARE, SMBL_SHARE, USE_SPOOLDEV); + if (error) + goto out; + + error = smb_ctx_readrc(ctx); + if (error) + goto out; + + while ((opt = getopt(argc-1, argv, STDPARAM_OPT)) != EOF) { + if (opt == '?') + print_usage(); + error = smb_ctx_opt(ctx, opt, optarg); + if (error) + goto out; + } + if (optind != argc-2) + print_usage(); + filename = argv[argc-1]; + + if (strcmp(filename, "-") == 0) { + file = 0; /* stdin */ + filename = "stdin"; + } else { + file = open(filename, O_RDONLY, 0); + if (file < 0) { + smb_error("could not open file %s\n", errno, filename); + exit(1); + } + } + + /* + * Resolve the server address, + * setup derived defaults. + */ + error = smb_ctx_resolve(ctx); + if (error) + goto out; + + /* + * Have server + share names, options etc. + * Get the session and tree. + */ +again: + error = smb_ctx_get_ssn(ctx); + if (error == EAUTH) { + int err2 = smb_get_authentication(ctx); + if (err2 == 0) + goto again; + } + if (error) { + smb_error(gettext("//%s: login failed"), + error, ctx->ct_fullserver); + goto out; + } + + error = smb_ctx_get_tree(ctx); + if (error) { + smb_error(gettext("//%s/%s: tree connect failed"), + error, ctx->ct_fullserver, ctx->ct_origshare); + goto out; + } + + /* + * Have the printer share connection. + * Print the file. + */ + snprintf(titlebuf, sizeof (titlebuf), "%s_%s", + ctx->ct_user, filename); + + error = print_file(ctx, titlebuf, file); + + +out: + /* don't close stdin (file=0) */ + if (file > 0) + close(file); + + smb_ctx_free(ctx); + + return (error); +} + +/* + * Documentation for OPEN_PRINT_FILE is scarse. + * It's in a 1996 MS doc. entitled: + * SMB FILE SHARING PROTOCOL + * + * The extra parameters are: + * SetupLength: what part of the file is printer setup + * Mode: text or graphics (raw data) + * IdentifierString: job title + */ +enum { + MODE_TEXT = 0, /* TAB expansion, etc. */ + MODE_GRAPHICS /* raw data */ +}; + +static int +print_file(smb_ctx_t *ctx, char *title, int file) +{ + off_t offset; + int error, rcnt, wcnt; + int setup_len = 0; /* No printer setup data */ + int mode = MODE_GRAPHICS; /* treat as raw data */ + int fh = -1; + + error = smb_printer_open(ctx, setup_len, mode, title, &fh); + if (error) { + smb_error("could not open print job", error); + return (error); + } + + offset = 0; + for (;;) { + rcnt = read(file, databuf, sizeof (databuf)); + if (rcnt < 0) { + error = errno; + smb_error("error reading input file\n", error); + break; + } + if (rcnt == 0) + break; + + wcnt = smb_fh_write(ctx, fh, offset, rcnt, databuf); + if (wcnt < 0) { + error = errno; + smb_error("error writing spool file\n", error); + break; + } + if (wcnt != rcnt) { + smb_error("incomplete write to spool file\n", 0); + error = EIO; + break; + } + offset += wcnt; + } + + (void) smb_printer_close(ctx, fh); + return (error); +} |
