367 lines
6.9 KiB
C
367 lines
6.9 KiB
C
/*
|
|
* nwprint.c
|
|
*
|
|
* Copyright (C) 1995 by Volker Lendecke
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <pwd.h>
|
|
#include <grp.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/param.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/ioctl.h>
|
|
/* #include <sys/wait.h> */ /* generates a warning here */
|
|
extern pid_t waitpid(pid_t, int *, int);
|
|
#include <sys/errno.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <errno.h>
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <sys/mount.h>
|
|
#include <mntent.h>
|
|
#include <linux/ipx.h>
|
|
|
|
#include <linux/fs.h>
|
|
#include <linux/ncp.h>
|
|
#include <linux/ncp_fs.h>
|
|
#include <linux/ncp_mount.h>
|
|
#include "ncplib.h"
|
|
|
|
static char *progname;
|
|
static void
|
|
usage(void);
|
|
|
|
void
|
|
main(int argc, char *argv[])
|
|
{
|
|
struct ncp_conn conn;
|
|
|
|
char *server = NULL;
|
|
char *user = NULL;
|
|
char *password = NULL;
|
|
struct ncp_conn_spec *spec;
|
|
|
|
char *queue = "*";
|
|
|
|
int opt;
|
|
|
|
struct ncp_bindery_object q;
|
|
struct queue_job j;
|
|
struct print_job_record pj;
|
|
|
|
int written, read_this_time;
|
|
|
|
char buf[8192];
|
|
|
|
char *file_name;
|
|
int file;
|
|
|
|
progname = argv[0];
|
|
|
|
memset(&spec, 0, sizeof(spec));
|
|
memset(&j, 0, sizeof(j));
|
|
|
|
/*
|
|
* Fill in default values for print job
|
|
*/
|
|
j.j.TargetServerID = 0xffffffff; /* any server */
|
|
/* at once */
|
|
memset(&(j.j.TargetExecTime), 0xff, sizeof(j.j.TargetExecTime));
|
|
j.j.JobType = htons(0);
|
|
strcpy(j.j.JobTextDescription, "Test Job");
|
|
|
|
memset(&pj, 0, sizeof(pj));
|
|
|
|
pj.Version = 0;
|
|
pj.TabSize = 8;
|
|
pj.Copies = htons(1);
|
|
pj.CtrlFlags = 0;
|
|
pj.Lines = htons(66);
|
|
pj.Rows = htons(80);
|
|
strcpy(pj.FnameHeader, "stdin");
|
|
|
|
while ((opt = getopt(argc, argv,
|
|
"S:U:P:nq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
|
|
{
|
|
switch (opt) {
|
|
case 'p':
|
|
/* Path */
|
|
pj.CtrlFlags |= PRINT_BANNER;
|
|
if (strlen(optarg) >= sizeof(pj.Path))
|
|
{
|
|
strncpy(pj.Path, optarg,
|
|
sizeof(pj.Path));
|
|
}
|
|
else
|
|
{
|
|
strcpy(pj.Path, optarg);
|
|
}
|
|
break;
|
|
case 'b':
|
|
/* Banner Name */
|
|
pj.CtrlFlags |= PRINT_BANNER;
|
|
if (strlen(optarg) >= sizeof(pj.BannerName))
|
|
{
|
|
strncpy(pj.BannerName, optarg,
|
|
sizeof(pj.BannerName));
|
|
}
|
|
else
|
|
{
|
|
strcpy(pj.BannerName, optarg);
|
|
}
|
|
break;
|
|
case 'f':
|
|
/* File Name in Banner */
|
|
pj.CtrlFlags |= PRINT_BANNER;
|
|
if (strlen(optarg) >= sizeof(pj.FnameBanner))
|
|
{
|
|
strncpy(pj.FnameBanner, optarg,
|
|
sizeof(pj.FnameBanner));
|
|
}
|
|
else
|
|
{
|
|
strcpy(pj.FnameBanner, optarg);
|
|
}
|
|
break;
|
|
case 'l':
|
|
/* lines, default: 66 */
|
|
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535))
|
|
{
|
|
fprintf(stderr,
|
|
"invalid line number: %s\n", optarg);
|
|
break;
|
|
}
|
|
pj.Lines = htons(atoi(optarg));
|
|
pj.CtrlFlags |= EXPAND_TABS;
|
|
break;
|
|
case 'r':
|
|
/* rows, default: 80 */
|
|
if ((atoi(optarg) < 0) || (atoi(optarg) > 65535))
|
|
{
|
|
fprintf(stderr,
|
|
"invalid row number: %s\n", optarg);
|
|
break;
|
|
}
|
|
pj.Rows = htons(atoi(optarg));
|
|
pj.CtrlFlags |= EXPAND_TABS;
|
|
break;
|
|
case 'c':
|
|
/* copies, default: 1 */
|
|
if ((atoi(optarg) < 0) || (atoi(optarg) > 65000))
|
|
{
|
|
fprintf(stderr,
|
|
"invalid copies: %s\n", optarg);
|
|
break;
|
|
}
|
|
pj.Copies = htons(atoi(optarg));
|
|
pj.CtrlFlags |= EXPAND_TABS;
|
|
break;
|
|
case 't':
|
|
/* tab size, default: 8 */
|
|
if ((atoi(optarg) < 0) || (atoi(optarg) > 255))
|
|
{
|
|
fprintf(stderr,
|
|
"invalid tab size: %s\n", optarg);
|
|
break;
|
|
}
|
|
pj.TabSize = atoi(optarg);
|
|
pj.CtrlFlags |= EXPAND_TABS;
|
|
break;
|
|
case 'T':
|
|
/* expand tabs, default tabsize: 8 */
|
|
pj.CtrlFlags |= EXPAND_TABS;
|
|
break;
|
|
case 'N':
|
|
/* no form feed */
|
|
pj.CtrlFlags |= NO_FORM_FEED;
|
|
break;
|
|
case 'F':
|
|
/* Form number, default: 0 */
|
|
if ((atoi(optarg) < 0) || (atoi(optarg) > 255))
|
|
{
|
|
fprintf(stderr,
|
|
"invalid form number: %s\n", optarg);
|
|
break;
|
|
}
|
|
j.j.JobType = htons(atoi(optarg));
|
|
break;
|
|
case 'S':
|
|
/* File Server */
|
|
if (strlen(optarg) >= sizeof(spec->server))
|
|
{
|
|
fprintf(stderr, "Servername too long:%s\n",
|
|
optarg);
|
|
exit(1);
|
|
}
|
|
server = optarg;
|
|
break;
|
|
case 'U':
|
|
/* User to use */
|
|
if (strlen(optarg) >= sizeof(spec->user))
|
|
{
|
|
fprintf(stderr, "Username too long: %s\n",
|
|
optarg);
|
|
exit(1);
|
|
}
|
|
user = optarg;
|
|
break;
|
|
case 'P':
|
|
/* Password */
|
|
if (strlen(optarg) >= sizeof(spec->password))
|
|
{
|
|
printf("password too long\n");
|
|
exit(1);
|
|
}
|
|
password = optarg;
|
|
break;
|
|
case 'n':
|
|
/* use no password */
|
|
password = "";
|
|
break;
|
|
case 'q':
|
|
/* Queue name to print on, default: '*' */
|
|
if (strlen(optarg) >= NCP_BINDERY_NAME_LEN)
|
|
{
|
|
printf("queue name too long: %s\n",
|
|
optarg);
|
|
exit(1);
|
|
}
|
|
queue = optarg;
|
|
break;
|
|
case 'd':
|
|
/* Job Description */
|
|
pj.CtrlFlags |= PRINT_BANNER;
|
|
if (strlen(optarg) >= sizeof(j.j.JobTextDescription))
|
|
{
|
|
strncpy(j.j.JobTextDescription, optarg,
|
|
sizeof(j.j.JobTextDescription));
|
|
}
|
|
else
|
|
{
|
|
strcpy(j.j.JobTextDescription, optarg);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
usage();
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
if (optind != argc-1)
|
|
{
|
|
usage();
|
|
exit(1);
|
|
}
|
|
|
|
file_name = argv[optind];
|
|
|
|
if (strcmp(file_name, "-") == 0)
|
|
{
|
|
file = 0; /* stdin */
|
|
}
|
|
else
|
|
{
|
|
file = open(file_name, O_RDONLY, 0);
|
|
if (file < 0)
|
|
{
|
|
perror("could not open file");
|
|
exit(1);
|
|
}
|
|
|
|
if (strlen(file_name) >= sizeof(pj.FnameHeader))
|
|
{
|
|
strncpy(pj.FnameHeader, file_name,
|
|
sizeof(pj.FnameHeader));
|
|
}
|
|
else
|
|
{
|
|
strcpy(pj.FnameHeader, file_name);
|
|
}
|
|
|
|
if (strlen(pj.FnameBanner) == 0)
|
|
{
|
|
if (strlen(file_name) >= sizeof(pj.FnameBanner))
|
|
{
|
|
strncpy(pj.FnameBanner, file_name,
|
|
sizeof(pj.FnameBanner));
|
|
}
|
|
else
|
|
{
|
|
strcpy(pj.FnameBanner, file_name);
|
|
}
|
|
}
|
|
}
|
|
|
|
memcpy(j.j.ClientRecordArea, &pj, sizeof(pj));
|
|
|
|
if ((spec = ncp_find_conn_spec(server, user, password, 0)) == NULL)
|
|
{
|
|
perror("could not find connection");
|
|
exit(1);
|
|
}
|
|
|
|
if (ncp_open(&conn, spec) != 0)
|
|
{
|
|
perror("could not open connection");
|
|
exit(1);
|
|
}
|
|
|
|
if (ncp_scan_bindery_object(&conn, 0xffffffff, NCP_BINDERY_PQUEUE,
|
|
queue, &q) != 0)
|
|
{
|
|
printf("could not find queue %s\n", queue);
|
|
return;
|
|
}
|
|
|
|
if (ncp_create_queue_job_and_file(&conn, q.object_id, &j) != 0)
|
|
{
|
|
printf("create error\n");
|
|
return;
|
|
}
|
|
|
|
written = 0;
|
|
do
|
|
{
|
|
read_this_time = read(file, buf, sizeof(buf));
|
|
if (read_this_time < 0)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (ncp_write(&conn, j.file_handle,
|
|
written, read_this_time, buf) < read_this_time)
|
|
{
|
|
break;
|
|
}
|
|
|
|
written += read_this_time;
|
|
} while (read_this_time == sizeof(buf));
|
|
|
|
close(file);
|
|
|
|
if (ncp_close_file_and_start_job(&conn, q.object_id, &j) != 0) {
|
|
printf("close error\n");
|
|
return;
|
|
}
|
|
|
|
ncp_close(&conn);
|
|
}
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
fprintf(stderr, "usage: %s [options] file\n", progname);
|
|
exit(1);
|
|
}
|