187866Ssheldonh/*
287866Ssheldonh * Copyright (c) 2000, Boris Popov
387866Ssheldonh * All rights reserved.
487866Ssheldonh *
587866Ssheldonh * Redistribution and use in source and binary forms, with or without
687866Ssheldonh * modification, are permitted provided that the following conditions
787866Ssheldonh * are met:
887866Ssheldonh * 1. Redistributions of source code must retain the above copyright
987866Ssheldonh *    notice, this list of conditions and the following disclaimer.
1087866Ssheldonh * 2. Redistributions in binary form must reproduce the above copyright
1187866Ssheldonh *    notice, this list of conditions and the following disclaimer in the
1287866Ssheldonh *    documentation and/or other materials provided with the distribution.
1387866Ssheldonh * 3. All advertising materials mentioning features or use of this software
1487866Ssheldonh *    must display the following acknowledgement:
1587866Ssheldonh *    This product includes software developed by Boris Popov.
1687866Ssheldonh * 4. Neither the name of the author nor the names of any co-contributors
1787866Ssheldonh *    may be used to endorse or promote products derived from this software
1887866Ssheldonh *    without specific prior written permission.
1987866Ssheldonh *
2087866Ssheldonh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2187866Ssheldonh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2287866Ssheldonh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2387866Ssheldonh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2487866Ssheldonh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2587866Ssheldonh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2687866Ssheldonh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2787866Ssheldonh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2887866Ssheldonh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2987866Ssheldonh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3087866Ssheldonh * SUCH DAMAGE.
3187866Ssheldonh *
3287866Ssheldonh * $Id: print.c,v 1.4 2001/01/28 07:35:01 bp Exp $
3387866Ssheldonh */
34161207Skeramida
35161207Skeramida#include <sys/cdefs.h>
36161207Skeramida__FBSDID("$FreeBSD$");
37161207Skeramida
3887866Ssheldonh#include <sys/param.h>
3987866Ssheldonh#include <sys/errno.h>
4087866Ssheldonh#include <sys/stat.h>
4187866Ssheldonh#include <err.h>
4287866Ssheldonh#include <fcntl.h>
4387866Ssheldonh#include <stdio.h>
4487866Ssheldonh#include <unistd.h>
4587866Ssheldonh#include <strings.h>
4687866Ssheldonh#include <stdlib.h>
4787866Ssheldonh#include <sysexits.h>
4887866Ssheldonh
4987866Ssheldonh#include <cflib.h>
5087866Ssheldonh
5187866Ssheldonh#include <netsmb/smb_lib.h>
5287866Ssheldonh#include <netsmb/smb_conn.h>
5387866Ssheldonh
5487866Ssheldonh#include "common.h"
5587866Ssheldonh
5687866Ssheldonhint
5787866Ssheldonhcmd_print(int argc, char *argv[])
5887866Ssheldonh{
5987866Ssheldonh	struct smb_ctx sctx, *ctx = &sctx;
6087866Ssheldonh	smbfh fh;
6187866Ssheldonh	off_t offset;
6287866Ssheldonh	char buf[8192];
6387866Ssheldonh	char *filename;
6487866Ssheldonh	char fnamebuf[256];
6587866Ssheldonh	int error, opt, i, file, count;
6687866Ssheldonh
6787866Ssheldonh	if (argc < 2)
6887866Ssheldonh		view_usage();
6987866Ssheldonh	if (smb_ctx_init(ctx, argc, argv, SMBL_SHARE, SMBL_SHARE, SMB_ST_PRINTER) != 0)
7087866Ssheldonh		exit(1);
7187866Ssheldonh	if (smb_ctx_readrc(ctx) != 0)
7287866Ssheldonh		exit(1);
7387866Ssheldonh	if (smb_rc)
7487866Ssheldonh		rc_close(smb_rc);
7587866Ssheldonh	while ((opt = getopt(argc, argv, STDPARAM_OPT)) != EOF) {
7687866Ssheldonh		switch(opt){
7787866Ssheldonh		    case STDPARAM_ARGS:
7887866Ssheldonh			error = smb_ctx_opt(ctx, opt, optarg);
7987866Ssheldonh			if (error)
8087866Ssheldonh				exit(1);
8187866Ssheldonh			break;
8287866Ssheldonh		    default:
8387866Ssheldonh			view_usage();
8487866Ssheldonh			/*NOTREACHED*/
8587866Ssheldonh		}
8687866Ssheldonh	}
8787866Ssheldonh	if (optind + 1 >= argc)
8887866Ssheldonh		print_usage();
8987866Ssheldonh	filename = argv[optind + 1];
9087866Ssheldonh
9187866Ssheldonh	if (strcmp(filename, "-") == 0) {
9287866Ssheldonh		file = 0;	/* stdin */
9387866Ssheldonh		filename = "stdin";
9487866Ssheldonh	} else {
9587866Ssheldonh		file = open(filename, O_RDONLY, 0);
9687866Ssheldonh		if (file < 0) {
9787866Ssheldonh			smb_error("could not open file %s\n", errno, filename);
9887866Ssheldonh			exit(1);
9987866Ssheldonh		}
10087866Ssheldonh	}
10187866Ssheldonh
10287866Ssheldonh	if (smb_ctx_resolve(ctx) != 0)
10387866Ssheldonh		exit(1);
10487866Ssheldonh	error = smb_ctx_lookup(ctx, SMBL_SHARE, SMBLK_CREATE);
10587866Ssheldonh	if (error) {
10687866Ssheldonh		smb_error("could not login to server %s", error, ctx->ct_ssn.ioc_srvname);
10787866Ssheldonh		exit(1);
10887866Ssheldonh	}
10987866Ssheldonh	snprintf(fnamebuf, sizeof(fnamebuf), "%s_%s_%s", ctx->ct_ssn.ioc_user,
11087866Ssheldonh	    ctx->ct_ssn.ioc_srvname, filename);
11187866Ssheldonh	error = smb_smb_open_print_file(ctx, 0, 1, fnamebuf, &fh);
11287866Ssheldonh	if (error) {
11387866Ssheldonh		smb_error("could not open print job", error);
11487866Ssheldonh		exit(1);
11587866Ssheldonh	}
11687866Ssheldonh	offset = 0;
11787866Ssheldonh	error = 0;
11887866Ssheldonh	for(;;) {
11987866Ssheldonh		count = read(file, buf, sizeof(buf));
12087866Ssheldonh		if (count == 0)
12187866Ssheldonh			break;
12287866Ssheldonh		if (count < 0) {
12387866Ssheldonh			error = errno;
12487866Ssheldonh			smb_error("error reading input file\n", error);
12587866Ssheldonh			break;
12687866Ssheldonh		}
12787866Ssheldonh		i = smb_write(ctx, fh, offset, count, buf);
12887866Ssheldonh		if (i < 0) {
12987866Ssheldonh			error = errno;
13087866Ssheldonh			smb_error("error writing spool file\n", error);
13187866Ssheldonh			break;
13287866Ssheldonh		}
13387866Ssheldonh		if (i != count) {
13487866Ssheldonh			smb_error("incomplete write to spool file\n", 0);
13587866Ssheldonh			error = EIO;
13687866Ssheldonh			break;
13787866Ssheldonh		}
13887866Ssheldonh		offset += count;
13987866Ssheldonh	}
14087866Ssheldonh	close(file);
14187866Ssheldonh	error = smb_smb_close_print_file(ctx, fh);
14287866Ssheldonh	if (error)
14387866Ssheldonh		smb_error("an error while closing spool file\n", error);
14487866Ssheldonh	return error ? 1 : 0;
14587866Ssheldonh}
14687866Ssheldonh
14787866Ssheldonh
14887866Ssheldonhvoid
14987866Ssheldonhprint_usage(void)
15087866Ssheldonh{
15187866Ssheldonh	printf(
152161207Skeramida	"usage: smbutil print [connection options] //user@server/share\n"
15387866Ssheldonh	);
15487866Ssheldonh	exit(1);
15587866Ssheldonh}
15687866Ssheldonh
157