4bff34e37def8a90f9194d81bc345c52ba20086athurlow/*
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Copyright (c) 2000, Boris Popov
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * All rights reserved.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * Redistribution and use in source and binary forms, with or without
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * modification, are permitted provided that the following conditions
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * are met:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 1. Redistributions of source code must retain the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 2. Redistributions in binary form must reproduce the above copyright
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * notice, this list of conditions and the following disclaimer in the
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * documentation and/or other materials provided with the distribution.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 3. All advertising materials mentioning features or use of this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * must display the following acknowledgement:
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * This product includes software developed by Boris Popov.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * 4. Neither the name of the author nor the names of any co-contributors
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * may be used to endorse or promote products derived from this software
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * without specific prior written permission.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4bff34e37def8a90f9194d81bc345c52ba20086athurlow * SUCH DAMAGE.
4bff34e37def8a90f9194d81bc345c52ba20086athurlow *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * from: Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp
4bff34e37def8a90f9194d81bc345c52ba20086athurlow */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Use is subject to license terms.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <sys/types.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <err.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <errno.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <fcntl.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdio.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <string.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <stdlib.h>
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#include <unistd.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <libintl.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <cflib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include <netsmb/smb_lib.h>
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlow#include "common.h"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic char titlebuf[256];
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic char databuf[4096];
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic int print_file(smb_ctx_t *, char *, int);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow
4bff34e37def8a90f9194d81bc345c52ba20086athurlowvoid
4bff34e37def8a90f9194d81bc345c52ba20086athurlowprint_usage(void)
4bff34e37def8a90f9194d81bc345c52ba20086athurlow{
4bff34e37def8a90f9194d81bc345c52ba20086athurlow printf(gettext("usage: smbutil print [connection options] //"
4bff34e37def8a90f9194d81bc345c52ba20086athurlow "[workgroup;][user[:password]@]"
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross "server/share {print_file|-}\n"));
4bff34e37def8a90f9194d81bc345c52ba20086athurlow exit(1);
4bff34e37def8a90f9194d81bc345c52ba20086athurlow}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossint
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rosscmd_print(int argc, char *argv[])
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross struct smb_ctx *ctx = NULL;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross char *filename;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int error, opt;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int file = -1;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* last arg is the print file. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (argc < 3)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross print_usage();
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_alloc(&ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_scan_argv(ctx, argc-1, argv,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross SMBL_SHARE, SMBL_SHARE, USE_SPOOLDEV);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_readrc(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross while ((opt = getopt(argc-1, argv, STDPARAM_OPT)) != EOF) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (opt == '?')
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross print_usage();
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_opt(ctx, opt, optarg);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (optind != argc-2)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross print_usage();
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross filename = argv[argc-1];
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (strcmp(filename, "-") == 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross file = 0; /* stdin */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross filename = "stdin";
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross } else {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross file = open(filename, O_RDONLY, 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (file < 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error("could not open file %s\n", errno, filename);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross exit(1);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Resolve the server address,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * setup derived defaults.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_resolve(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Have server + share names, options etc.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Get the session and tree.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossagain:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_get_ssn(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error == EAUTH) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int err2 = smb_get_authentication(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (err2 == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto again;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error(gettext("//%s: login failed"),
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error, ctx->ct_fullserver);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = smb_ctx_get_tree(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (error) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error(gettext("//%s/%s: tree connect failed"),
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error, ctx->ct_fullserver, ctx->ct_origshare);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross goto out;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Have the printer share connection.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Print the file.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross snprintf(titlebuf, sizeof (titlebuf), "%s %s",
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross ctx->ct_user, filename);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = print_file(ctx, titlebuf, file);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossout:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* don't close stdin (file=0) */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (file > 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross close(file);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_ctx_free(ctx);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross/*
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Documentation for OPEN_PRINT_FILE is scarse.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * It's in a 1996 MS doc. entitled:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * SMB FILE SHARING PROTOCOL
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross *
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The extra parameters are:
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * SetupLength: what part of the file is printer setup
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Mode: text or graphics (raw data)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * IdentifierString: job title
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossenum {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross MODE_TEXT = 0, /* TAB expansion, etc. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross MODE_GRAPHICS /* raw data */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross};
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossstatic int
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossprint_file(smb_ctx_t *ctx, char *title, int file)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross{
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross off_t offset;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int rcnt, wcnt;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int setup_len = 0; /* No printer setup data */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross int mode = MODE_GRAPHICS; /* treat as raw data */
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int error = 0;
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross int pfd = -1;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross pfd = smb_open_printer(ctx, title, setup_len, mode);
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross if (pfd < 0) {
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross error = errno;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error("could not open print job", error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross offset = 0;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross for (;;) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross rcnt = read(file, databuf, sizeof (databuf));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (rcnt < 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = errno;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error("error reading input file\n", error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (rcnt == 0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross wcnt = smb_fh_write(pfd, offset, rcnt, databuf);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (wcnt < 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = errno;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error("error writing spool file\n", error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (wcnt != rcnt) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross smb_error("incomplete write to spool file\n", 0);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross error = EIO;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross break;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross offset += wcnt;
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross }
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross
430b4c467020edf2445feb0c21db01c88b86243aGordon Ross (void) smb_fh_close(pfd);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross return (error);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross}