main.c revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libintl.h>
#include <sys/systeminfo.h>
#include <ctype.h>
#include <netdb.h>
#include <fcntl.h>
#include <string.h>
#include <syslog.h>
#include <errno.h>
#include <libintl.h>
#include <adaptor.h>
/*
* This file contains the front-end of the BSD Print Protocol adaptor. This
* code assumes a BSD Socket interface to the networking side.
*/
/*
* strsplit() splits a string into a NULL terminated array of substrings
* determined by a seperator. The original string is modified, and newly
* allocated space is only returned for the array itself. If more than
* 1024 substrings exist, they will be ignored.
*/
static char **
{
**result;
int length = 0;
return (NULL);
length++;
return (result);
}
/*
* remote_host_name() gets the hostname of the "peer" on the socket
* connection.
*/
static char *
{
struct sockaddr_in6 peer;
int error_num;
char *hostname;
/* who is our peer ? */
return (NULL);
else
return (strdup("localhost"));
}
/* get their name or return a string containing their address */
}
/* is it "localhost" ? */
return (strdup("localhost"));
/* duplicate the name because gethostbyXXXX() is not reentrant */
/* is it from one of my addresses ? */
int i = 0;
== 0) {
return (strdup("localhost"));
}
}
}
/* It must be someone else */
return (hostname);
}
static int
request_id_no(const char *filename)
{
int id = -1;
/* get the first number embedded in the string */
filename++;
return (id);
}
static void
abort_transfer(char **files)
{
}
static int lock_fd = -1;
static int lock_job_id = -1;
static void
{
if (lock_fd != -1) {
char name[12];
lock_fd = -1;
lock_job_id = -1;
}
}
static void
{
int try = 5;
char name[12];
unlock_job();
sleep(3);
}
}
try--;
}
"failed to lock job: %d, file(%s), fd(%d): %m",
}
}
/*
* transfer_job() retrieves jobs being sent from a remote system and
* submits them as they are completely received.
*/
static int
{
*tmp;
int file_no = 0;
int current_request = -1;
int tmp_id;
int psize;
if (adaptor_spooler_accepting_jobs(printer) < 0) {
"attempt to transfer job(s) to disabled printer"
" or unknown printer %s", printer);
return (-1);
}
/* start to receive job(s) */
int size = 0;
char *ptr;
int fd;
int count;
/*
* When receiving jobs, buf[0] can only be 1,2 or 3
* Anything else, abort transfer - rfc1179
*/
"protocol error - bad message from client");
unlock_job();
return (-1);
}
continue;
/* for security */
"Attempt to tranfer Absolute path: %s",
tmp);
name++;
} else
(tmp_id != current_request)) {
df_list) != 0) {
unlock_job();
return (-1);
}
while (file_no-- > 0)
file_no = 0;
}
if (tmp_id != current_request)
} else if (buf[0] != 1) {
buf[0]);
unlock_job();
return (-1);
}
switch (buf[0]) {
case '\1': /* Abort Transfer */
/* remove files on file_list */
unlock_job();
return (-1);
case '\2': /* Transfer Control File */
break;
}
while (count > 0)
"connection closed(%s): %m",
name);
unlock_job();
return (-1);
} else {
}
unlock_job();
return (-1);
}
break;
case '\3': /* Transfer Data File */
0640)) < 0) {
unlock_job();
return (-1);
}
unlock_job();
return (-1);
}
if ((size > 0) &&
(MAP_SHARED | MAP_NORESERVE),
unlock_job();
return (-1);
}
/* Make sure that there is adequate space */
"pwrite(,, %d ,) returns:(%d) %m",
unlock_job();
return (-1);
}
while (count > 0)
"connection closed(%s): %m",
name);
unlock_job();
return (-1);
} else {
}
unlock_job();
return (-1);
}
/*
* make sure we don't overflow df_list.
*/
"prevented in.lpd exploit from host %s",
host);
return (-1);
}
break;
default:
unlock_job();
return (-1);
}
}
unlock_job();
return (-1);
}
while (file_no-- > 0)
} else
unlock_job();
return (0);
}
/*
* This is the entry point for this program. The program takes the
* following options:
* (none)
*/
int
{
int c,
rc;
**args,
*host,
*dir,
*printer,
switch (c) {
case 'd':
default:
;
}
exit(1);
}
#ifdef DEBUG
buf[0] -= '0';
#endif
gettext("Invalid protocol request (%d): %c%s\n"),
exit(1);
}
gettext("Can't determine requested printer"));
exit(1);
}
gettext("Can't determine requesting host\n"));
exit(1);
}
if (adaptor_available(printer) < 0) {
"request to %s (unknown printer) from %s",
} else {
"Can't locate protocol adaptor for %s from %s",
"Can't locate protocol adaptor for %s\n"),
printer);
}
exit(1);
}
if (adaptor_spooler_available(printer) < 0) {
printer);
gettext("Can't communicate with spooler for %s\n"),
printer);
exit(1);
}
gettext("%s doesn't have permission to talk to %s\n"),
exit(1);
}
return (1);
}
return (1);
}
switch (buf[0]) {
case '\1': /* restart printer */
} else {
}
break;
case '\2': /* transfer job(s) */
break;
case '\3': /* show queue (short) */
case '\4': /* show queue (long) */
break;
case '\5': /* cancel job(s) */
break;
default:
/* NOTREACHED */
/* your system would have to be completely hosed */
rc = -1;
}
"protocol request(%d) for %s completed with status %d",
exit(0);
}