Import ncpfs 0.14
This commit is contained in:
@@ -2,11 +2,12 @@
|
||||
# Makefile for the linux ncp-filesystem routines.
|
||||
#
|
||||
|
||||
UTIL_EXECS = ncpmount ncpumount nprint slist pqlist
|
||||
UTIL_EXECS = ncpmount ncpumount nprint slist pqlist fsinfo pserver
|
||||
UTILS = $(addprefix $(INTERM_BINDIR)/,$(UTIL_EXECS))
|
||||
UIDUTILS = ncpmount ncpumount
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) -O2 $(KERNELD)
|
||||
# CFLAGS = -Wall $(INCLUDES) -O2 $(KERNELD)
|
||||
CFLAGS = -Wall $(INCLUDES) $(KERNELD) -O2
|
||||
CC = gcc
|
||||
|
||||
all: $(UTILS) ncptest
|
||||
@@ -17,7 +18,7 @@ install: all
|
||||
for i in $(UIDUTILS); do chmod 4755 $(BINDIR)/$$i; done
|
||||
|
||||
$(UTILS): $(addsuffix .o,$(UTIL_EXECS)) ncplib.o
|
||||
$(CC) -s -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
|
||||
$(CC) -o $@ $(addsuffix .o,$(notdir $@)) ncplib.o
|
||||
|
||||
ncplib.o: ncplib.c ncplib.h
|
||||
$(CC) $(CFLAGS) -finline-functions -c ncplib.c
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include "ncplib.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct ncp_conn conn;
|
||||
char strings[512];
|
||||
char *s;
|
||||
int opt;
|
||||
|
||||
if (ncp_initialize(&conn, &argc, argv, 0) != 0)
|
||||
{
|
||||
@@ -23,22 +23,54 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ncp_get_file_server_description_strings(&conn, strings) != 0)
|
||||
while ((opt = getopt(argc, argv, "dt")) != EOF)
|
||||
{
|
||||
perror("could not get strings");
|
||||
ncp_close(&conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = strings;
|
||||
while (s < strings+512)
|
||||
{
|
||||
if (strlen(s) == 0)
|
||||
switch(opt)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
char strings[512];
|
||||
char *s;
|
||||
|
||||
if (ncp_get_file_server_description_strings(&conn,
|
||||
strings)
|
||||
!= 0)
|
||||
{
|
||||
perror("could not get strings");
|
||||
ncp_close(&conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = strings;
|
||||
while (s < strings+512)
|
||||
{
|
||||
if (strlen(s) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
puts(s);
|
||||
s += strlen(s)+1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
{
|
||||
time_t t;
|
||||
|
||||
if (ncp_get_file_server_time(&conn, &t) != 0)
|
||||
{
|
||||
perror("could not get server time");
|
||||
ncp_close(&conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fputs(ctime(&t), stdout);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("unknown option: %c\n", opt);
|
||||
break;
|
||||
}
|
||||
puts(s);
|
||||
s += strlen(s)+1;
|
||||
}
|
||||
|
||||
ncp_close(&conn);
|
||||
|
||||
221
util/ncplib.c
221
util/ncplib.c
@@ -34,8 +34,13 @@ extern pid_t wait(int *);
|
||||
static int
|
||||
ncp_negotiate_buffersize(struct ncp_conn *conn,
|
||||
int size, int *target);
|
||||
static int
|
||||
ncp_login_object(struct ncp_conn *conn,
|
||||
const unsigned char *username,
|
||||
int login_type,
|
||||
const unsigned char *password);
|
||||
|
||||
static void
|
||||
void
|
||||
str_upper(char *name)
|
||||
{
|
||||
while (*name) {
|
||||
@@ -837,7 +842,8 @@ ncp_open_temporary(struct ncp_conn *conn,
|
||||
|
||||
if (strlen(spec->user) != 0)
|
||||
{
|
||||
if (ncp_login_user(conn, spec->user, spec->password) != 0)
|
||||
if (ncp_login_object(conn, spec->user, spec->login_type,
|
||||
spec->password) != 0)
|
||||
{
|
||||
ncp_close(conn);
|
||||
errno = EACCES;
|
||||
@@ -1269,9 +1275,9 @@ ncp_find_conn_spec(const char *server, const char *user, const char *password,
|
||||
}
|
||||
|
||||
int
|
||||
ncp_initialize(struct ncp_conn *conn,
|
||||
int *argc, char **argv,
|
||||
int login_necessary)
|
||||
ncp_initialize_as(struct ncp_conn *conn,
|
||||
int *argc, char **argv,
|
||||
int login_necessary, int login_type)
|
||||
{
|
||||
char *server = NULL;
|
||||
char *user = NULL;
|
||||
@@ -1361,9 +1367,20 @@ ncp_initialize(struct ncp_conn *conn,
|
||||
|
||||
errno = 0;
|
||||
|
||||
spec->login_type = login_type;
|
||||
|
||||
return ncp_open(conn, spec);
|
||||
}
|
||||
|
||||
int
|
||||
ncp_initialize(struct ncp_conn *conn,
|
||||
int *argc, char **argv,
|
||||
int login_necessary)
|
||||
{
|
||||
return ncp_initialize_as(conn, argc, argv, login_necessary,
|
||||
NCP_BINDERY_USER);
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_request(struct ncp_conn *conn, int function)
|
||||
{
|
||||
@@ -1377,12 +1394,49 @@ ncp_request(struct ncp_conn *conn, int function)
|
||||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* */
|
||||
/* Helper functions */
|
||||
/* */
|
||||
/****************************************************************************/
|
||||
|
||||
static inline int
|
||||
min(int a, int b)
|
||||
{
|
||||
return (a<b) ? a : b;
|
||||
}
|
||||
|
||||
struct nw_time_buffer {
|
||||
__u8 year __attribute__ ((packed));
|
||||
__u8 month __attribute__ ((packed));
|
||||
__u8 day __attribute__ ((packed));
|
||||
__u8 hour __attribute__ ((packed));
|
||||
__u8 minute __attribute__ ((packed));
|
||||
__u8 second __attribute__ ((packed));
|
||||
__u8 wday __attribute__ ((packed));
|
||||
};
|
||||
|
||||
static time_t
|
||||
nw_to_ctime(struct nw_time_buffer *source)
|
||||
{
|
||||
struct tm u_time;
|
||||
|
||||
memzero(u_time);
|
||||
u_time.tm_sec = source->second;
|
||||
u_time.tm_min = source->minute;
|
||||
u_time.tm_hour = source->hour;
|
||||
u_time.tm_mday = source->day;
|
||||
u_time.tm_mon = source->month - 1;
|
||||
u_time.tm_year = source->year;
|
||||
|
||||
if (u_time.tm_year < 80)
|
||||
{
|
||||
u_time.tm_year += 100;
|
||||
}
|
||||
|
||||
return mktime(&u_time);
|
||||
}
|
||||
|
||||
static void
|
||||
assert_conn_locked(struct ncp_conn *conn)
|
||||
{
|
||||
@@ -1528,6 +1582,50 @@ ncp_get_file_server_description_strings(struct ncp_conn *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request(conn);
|
||||
|
||||
if ((result = ncp_request(conn, 20)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
*target= nw_to_ctime((struct nw_time_buffer *)ncp_reply_data(conn, 0));
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_get_connlist(struct ncp_conn *conn, __u32 last_id,
|
||||
__u16 object_type, const char *object_name,
|
||||
int *returned_no, __u16 conn_numbers[256])
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 27);
|
||||
ncp_add_dword(conn, htonl(last_id));
|
||||
ncp_add_word(conn, htons(object_type));
|
||||
ncp_add_pstring(conn, object_name);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0)
|
||||
{
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
*returned_no = ncp_reply_byte(conn, 0);
|
||||
memcpy(conn_numbers, ncp_reply_data(conn, 1),
|
||||
sizeof(__u16) * (*returned_no));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* result is a 8-byte buffer
|
||||
*/
|
||||
@@ -1672,6 +1770,15 @@ int
|
||||
ncp_login_user(struct ncp_conn *conn,
|
||||
const unsigned char *username,
|
||||
const unsigned char *password)
|
||||
{
|
||||
return ncp_login_object(conn, username, NCP_BINDERY_USER, password);
|
||||
}
|
||||
|
||||
static int
|
||||
ncp_login_object(struct ncp_conn *conn,
|
||||
const unsigned char *username,
|
||||
int login_type,
|
||||
const unsigned char *password)
|
||||
{
|
||||
int result;
|
||||
unsigned char ncp_key[8];
|
||||
@@ -1681,7 +1788,7 @@ ncp_login_user(struct ncp_conn *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((result = ncp_get_bindery_object_id(conn, NCP_BINDERY_USER,
|
||||
if ((result = ncp_get_bindery_object_id(conn, login_type,
|
||||
username, &user)) != 0) {
|
||||
return result;
|
||||
}
|
||||
@@ -2394,7 +2501,6 @@ ncp_create_queue_job_and_file(struct ncp_conn *conn,
|
||||
}
|
||||
|
||||
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
|
||||
|
||||
ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle);
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
@@ -2419,7 +2525,106 @@ ncp_close_file_and_start_job(struct ncp_conn *conn,
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ncp_attach_to_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 111);
|
||||
ncp_add_dword(conn, htonl(queue_id));
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0) {
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ncp_detach_from_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 112);
|
||||
ncp_add_dword(conn, htonl(queue_id));
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0) {
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
|
||||
struct queue_job *job)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 124);
|
||||
ncp_add_dword(conn, htonl(queue_id));
|
||||
ncp_add_word(conn, htons(job_type));
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0) {
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
memcpy(&(job->j), ncp_reply_data(conn, 0), 78);
|
||||
ConvertToNWfromDWORD(job->j.JobFileHandle, job->file_handle);
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number, __u32 charge_info)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 131);
|
||||
ncp_add_dword(conn, htonl(queue_id));
|
||||
ncp_add_dword(conn, job_number);
|
||||
ncp_add_dword(conn, htonl(charge_info));
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0) {
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number)
|
||||
{
|
||||
int result;
|
||||
|
||||
ncp_init_request_s(conn, 132);
|
||||
ncp_add_dword(conn, htonl(queue_id));
|
||||
ncp_add_dword(conn, job_number);
|
||||
|
||||
if ((result = ncp_request(conn, 23)) != 0) {
|
||||
ncp_unlock_conn(conn);
|
||||
return result;
|
||||
}
|
||||
|
||||
ncp_unlock_conn(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ncp_do_read(struct ncp_conn *conn, const char *file_id,
|
||||
|
||||
@@ -14,13 +14,18 @@
|
||||
#include <linux/ipx.h>
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "ipxlib.h"
|
||||
|
||||
#ifndef memzero
|
||||
#include <string.h>
|
||||
#define memzero(object) memset(&(object), 0, sizeof(object))
|
||||
#endif
|
||||
|
||||
void
|
||||
str_upper(char *name);
|
||||
|
||||
enum connect_state {
|
||||
NOT_CONNECTED = 0,
|
||||
CONN_PERMANENT,
|
||||
@@ -64,6 +69,7 @@ struct ncp_conn_spec {
|
||||
char server[NCP_BINDERY_NAME_LEN];
|
||||
char user[NCP_BINDERY_NAME_LEN];
|
||||
uid_t uid;
|
||||
int login_type; /* NCP_BINDERY_USER / NCP_BINDERY_PSERVER */
|
||||
char password[NCP_BINDERY_NAME_LEN];
|
||||
};
|
||||
|
||||
@@ -82,6 +88,14 @@ ncp_initialize(struct ncp_conn *conn,
|
||||
int *argc, char **argv,
|
||||
int login_necessary);
|
||||
|
||||
/* You can login as another object by this procedure. As a first use
|
||||
pserver comes to mind. */
|
||||
int
|
||||
ncp_initialize_as(struct ncp_conn *conn,
|
||||
int *argc, char **argv,
|
||||
int login_necessary, int login_type);
|
||||
|
||||
|
||||
/* Open an existing permanent connection */
|
||||
int
|
||||
ncp_open(struct ncp_conn *conn,
|
||||
@@ -132,6 +146,14 @@ int
|
||||
ncp_get_file_server_description_strings(struct ncp_conn *conn,
|
||||
char target[512]);
|
||||
|
||||
int
|
||||
ncp_get_file_server_time(struct ncp_conn *conn, time_t *target);
|
||||
|
||||
int
|
||||
ncp_get_connlist(struct ncp_conn *conn, __u32 last_id,
|
||||
__u16 object_type, const char *object_name,
|
||||
int *returned_no, __u16 conn_numbers[256]);
|
||||
|
||||
int
|
||||
ncp_get_encryption_key(struct ncp_conn *conn,
|
||||
char *target);
|
||||
@@ -286,4 +308,24 @@ ncp_close_file_and_start_job(struct ncp_conn *conn,
|
||||
__u32 queue_id,
|
||||
struct queue_job *job);
|
||||
|
||||
int
|
||||
ncp_attach_to_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id);
|
||||
|
||||
int
|
||||
ncp_detach_from_queue(struct ncp_conn *conn,
|
||||
__u32 queue_id);
|
||||
|
||||
int
|
||||
ncp_service_queue_job(struct ncp_conn *conn, __u32 queue_id, __u16 job_type,
|
||||
struct queue_job *job);
|
||||
|
||||
int
|
||||
ncp_finish_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number, __u32 charge_info);
|
||||
|
||||
int
|
||||
ncp_abort_servicing_job(struct ncp_conn *conn, __u32 queue_id,
|
||||
__u32 job_number);
|
||||
|
||||
#endif /* _NCPLIB_H */
|
||||
|
||||
@@ -47,7 +47,6 @@ extern pid_t waitpid(pid_t, int *, int);
|
||||
#include "ncplib.h"
|
||||
|
||||
static char *progname;
|
||||
static void str_upper(char *name);
|
||||
static void usage(void);
|
||||
static void help(void);
|
||||
|
||||
@@ -492,15 +491,6 @@ main(int argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
str_upper(char *name)
|
||||
{
|
||||
while (*name) {
|
||||
*name = toupper(*name);
|
||||
name = name + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
|
||||
@@ -137,6 +137,16 @@ test_ls(struct ncp_conn *server)
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
test_connlist(struct ncp_conn *conn)
|
||||
{
|
||||
__u16 conn_list[256];
|
||||
int no;
|
||||
|
||||
ncp_get_connlist(conn, 0, NCP_BINDERY_USER, "*", &no, conn_list);
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
@@ -148,8 +158,7 @@ main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
test_ls(&conn);
|
||||
|
||||
test_connlist(&conn);
|
||||
ncp_close(&conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
static char *progname;
|
||||
static void
|
||||
usage(void);
|
||||
static void
|
||||
str_upper(char *name);
|
||||
static void help(void);
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
@@ -48,6 +47,13 @@ main(int argc, char *argv[])
|
||||
|
||||
memzero(j); memzero(pj); memzero(q); memzero(conn);
|
||||
|
||||
if ( (argc == 2)
|
||||
&& (strcmp(argv[1], "-h") == 0))
|
||||
{
|
||||
help();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (ncp_initialize(&conn, &argc, argv, 1) != 0)
|
||||
{
|
||||
perror("Could not open connection");
|
||||
@@ -71,9 +77,13 @@ main(int argc, char *argv[])
|
||||
pj.Rows = htons(80);
|
||||
strcpy(pj.FnameHeader, "stdin");
|
||||
|
||||
while ((opt = getopt(argc, argv, "q:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
|
||||
while ((opt = getopt(argc, argv, "hq:d:p:b:f:l:r:c:t:F:TN"))!=EOF)
|
||||
{
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
help();
|
||||
ncp_close(&conn);
|
||||
exit(1);
|
||||
case 'p':
|
||||
/* Path */
|
||||
pj.CtrlFlags |= PRINT_BANNER;
|
||||
@@ -303,10 +313,27 @@ usage(void)
|
||||
}
|
||||
|
||||
static void
|
||||
str_upper(char *name)
|
||||
help(void)
|
||||
{
|
||||
while (*name) {
|
||||
*name = toupper(*name);
|
||||
name = name + 1;
|
||||
}
|
||||
printf("\n");
|
||||
printf("usage: %s [options] mount-point\n", progname);
|
||||
printf("\n"
|
||||
"-S server Server name to be used\n"
|
||||
"-U username Username sent to server\n"
|
||||
"-P password Use this password\n"
|
||||
"-n Do not use any password\n"
|
||||
"-C Don't convert password to uppercase\n"
|
||||
"-q queue name Name of the printing queue to use\n"
|
||||
"-d job desc Job description\n"
|
||||
"-p path name Path name to appear on banner\n"
|
||||
"-b bannername Banner name (up to 12 chars)\n"
|
||||
"-f filename Filename to appear on banner\n"
|
||||
"-l lines Number of lines per page\n"
|
||||
"-r rows Number of rows per page\n"
|
||||
"-t tab Number of spaces per tab\n"
|
||||
"-T Print server tab expantion\n"
|
||||
"-N Surpress print server form feeds\n"
|
||||
"-F form # Form number to print on\n"
|
||||
"-h print this help text\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ main(int argc, char **argv)
|
||||
{
|
||||
found = 1;
|
||||
printf("%-52s", q.object_name);
|
||||
printf("%08lx\n", q.object_id);
|
||||
printf("%08x\n", q.object_id);
|
||||
}
|
||||
|
||||
if ((found == 0) && (isatty(1)))
|
||||
|
||||
282
util/pserver.c
Normal file
282
util/pserver.c
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
* pserver.c
|
||||
*
|
||||
* Copyright (C) 1996 by Volker Lendecke
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <signal.h>
|
||||
#include "ncplib.h"
|
||||
|
||||
struct nw_queue {
|
||||
struct ncp_conn *conn;
|
||||
|
||||
char queue_name[NCP_BINDERY_NAME_LEN];
|
||||
__u32 queue_id;
|
||||
__u16 job_type;
|
||||
|
||||
char *command;
|
||||
};
|
||||
|
||||
static struct nw_queue q;
|
||||
|
||||
static int term_request;
|
||||
|
||||
static int
|
||||
init_queue(struct ncp_conn *conn, char *queue_name,
|
||||
char *command, struct nw_queue *q);
|
||||
|
||||
static int
|
||||
poll_queue(struct nw_queue *q);
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
/* Obviously, there's more to do */
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef NCP_BINDERY_PSERVER
|
||||
#define NCP_BINDERY_PSERVER (0x0007)
|
||||
#endif
|
||||
|
||||
static void
|
||||
terminate_handler()
|
||||
{
|
||||
signal(SIGTERM,terminate_handler);
|
||||
term_request=1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
daemonize()
|
||||
{
|
||||
int fd,c;
|
||||
|
||||
if ((c = fork()) > 0) exit(0);
|
||||
if (c < 0)
|
||||
{
|
||||
fprintf(stderr, "ipxripd: can't fork: %s\n",strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
if ((fd = open("/dev/tty", O_RDWR)) >= 0)
|
||||
{
|
||||
ioctl(fd, TIOCNOTTY, NULL);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct ncp_conn conn;
|
||||
int poll_timeout = 30;
|
||||
int opt;
|
||||
int job_type = 0xffff;
|
||||
int debug = 0;
|
||||
|
||||
char *queue_name = NULL;
|
||||
|
||||
char default_command[] = "lpr";
|
||||
char *command = default_command;
|
||||
|
||||
if (ncp_initialize_as(&conn, &argc, argv, 1, NCP_BINDERY_PSERVER) != 0)
|
||||
{
|
||||
perror("Could not open connection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "q:c:j:t:d")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'q':
|
||||
queue_name = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
command = optarg;
|
||||
break;
|
||||
case 'j':
|
||||
job_type = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
poll_timeout = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memzero(q);
|
||||
|
||||
if (debug == 0)
|
||||
{
|
||||
/* We can not daemonize after ncp_initialize, sorry */
|
||||
/* daemonize(); */
|
||||
}
|
||||
|
||||
if (init_queue(&conn, queue_name, command, &q) != 0)
|
||||
{
|
||||
perror("Could not init queue");
|
||||
ncp_close(&conn);
|
||||
return 1;
|
||||
}
|
||||
|
||||
q.job_type = job_type;
|
||||
|
||||
term_request = 0;
|
||||
signal(SIGTERM,terminate_handler);
|
||||
|
||||
while (1)
|
||||
{
|
||||
if ( (poll_queue(&q) != 0)
|
||||
&& (term_request == 0))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (term_request != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
sleep(poll_timeout);
|
||||
}
|
||||
|
||||
ncp_detach_from_queue(&conn, q.queue_id);
|
||||
|
||||
ncp_close(&conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
init_queue(struct ncp_conn *conn, char *queue_name, char *command,
|
||||
struct nw_queue *q)
|
||||
{
|
||||
struct ncp_bindery_object obj;
|
||||
|
||||
str_upper(queue_name);
|
||||
|
||||
q->conn = conn;
|
||||
q->command = command;
|
||||
|
||||
if (ncp_get_bindery_object_id(conn, NCP_BINDERY_PQUEUE,
|
||||
queue_name, &obj) != 0)
|
||||
{
|
||||
fprintf(stderr, "Queue %s not found\n", queue_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
q->queue_id = obj.object_id;
|
||||
memcpy(q->queue_name, obj.object_name, sizeof(q->queue_name));
|
||||
|
||||
if (ncp_attach_to_queue(conn, q->queue_id) != 0)
|
||||
{
|
||||
fprintf(stderr, "Could not attach to queue %s\n",
|
||||
queue_name);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
poll_queue(struct nw_queue *q)
|
||||
{
|
||||
struct queue_job job;
|
||||
int fd[2];
|
||||
int pid;
|
||||
|
||||
if (ncp_service_queue_job(q->conn, q->queue_id, q->job_type,
|
||||
&job) != 0)
|
||||
{
|
||||
/* No job for us */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pipe(fd) < 0)
|
||||
{
|
||||
perror("pipe");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((pid = fork()) < 0)
|
||||
{
|
||||
perror("fork");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (pid > 0)
|
||||
{
|
||||
/* parent */
|
||||
char buf[1024];
|
||||
size_t result;
|
||||
off_t offset = 0;
|
||||
|
||||
close(fd[0]); /* close read end */
|
||||
|
||||
while ((result = ncp_read(q->conn, job.file_handle, offset,
|
||||
sizeof(buf), buf)) > 0)
|
||||
{
|
||||
offset += result;
|
||||
if (write(fd[1], buf, result) != result)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd[1]); /* and close write end */
|
||||
|
||||
if (waitpid(pid, NULL, 0) < 0)
|
||||
{
|
||||
perror("waitpid");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* child */
|
||||
|
||||
close(fd[1]); /* close write end */
|
||||
|
||||
if (fd[0] != STDIN_FILENO)
|
||||
{
|
||||
if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO)
|
||||
{
|
||||
perror("dup2");
|
||||
close(fd[0]);
|
||||
exit(1);
|
||||
}
|
||||
close(fd[0]);
|
||||
}
|
||||
|
||||
execl("/bin/sh", "sh", "-c", q->command, NULL);
|
||||
perror("exec");
|
||||
close(fd[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ncp_finish_servicing_job(q->conn, q->queue_id, job.j.JobNumber,0);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
ncp_abort_servicing_job(q->conn, q->queue_id, job.j.JobNumber);
|
||||
/* We tell that we did not have a job to avoid overloading
|
||||
when something's wrong */
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user