home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume26
/
port-lpr
/
part01
/
unix-tcp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-09
|
5KB
|
198 lines
/*
* lpr interface for UNIX (i.e. BSD-ish) tcp
*/
#include "common.h"
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <errno.h>
#include <netinet/in.h>
#ifndef MAKE_EMAIL_ADDRESS
#define MAKE_EMAIL_ADDRESS(buf,user,dom) sprintf (buf, "%s@%s", user, dom)
#endif
struct hostent *
gethostbynameoraddr (hostname)
char *hostname;
{
if (isdigit (*hostname)) {
static struct hostent x;
static char *alias_list[1];
static unsigned long *addr_list[2];
static unsigned long ip_address;
ip_address = inet_addr (hostname);
addr_list[0] = &ip_address;
addr_list[1] = NULL;
alias_list[0] = NULL;
x.h_name = hostname;
x.h_aliases = alias_list;
x.h_addrtype = AF_INET;
x.h_length = sizeof (unsigned long);
x.h_addr_list = (char **) addr_list;
return &x;
}
return gethostbyname (hostname);
}
void sysdep()
{
struct passwd *pwd;
char *p;
struct hostent *hp;
char *getenv ();
gethostname (hostname, sizeof hostname);
if (pwd = getpwuid (getuid ()))
strcpy (username, pwd->pw_name);
else {
fprintf (stderr, "lpr: system problem: can't get your username!\n");
exit (1);
}
endpwent ();
hp = gethostbyname (hostname);
MAKE_EMAIL_ADDRESS(email_address, username, hp ? hp->h_name : hostname);
}
/*
* Allocate a socket and bind it to a local privileged port
* We have to be running set-uid to root to do this.
*/
int
get_priv_tcp_socket ()
{
int fd;
int port;
struct sockaddr_in s;
if ((fd = socket (AF_INET, SOCK_STREAM, 0)) == EOF) {
perror ("socket");
return EOF;
}
for (port = IPPORT_RESERVED-1; port > IPPORT_RESERVED / 2; port--) {
extern int errno;
s.sin_family = AF_INET;
s.sin_addr.s_addr = INADDR_ANY;
s.sin_port = htons (port);
if (bind (fd, (struct sockaddr *) &s, sizeof (s)) == 0)
return fd;
if (errno == EACCES) {
fprintf (stderr, "lpr warning: bind: cannot bind to privileged port\n");
return fd;
}
}
close (fd);
return EOF;
}
/*
* Open a TCP connection to an lpd-server.
* This requires that this program be run set-uid to root in order to be able
* to bind a socket to a privileged port.
*/
int
open_lpd (server)
char *server;
{
int fd;
int i;
int last_connect_failed;
struct hostent *hp;
struct servent *sp;
struct sockaddr_in s;
if (server == NULL || *server == '\0') {
fprintf (stderr, "lpr: no server host was specified.\n");
fprintf (stderr, " Supply one with the -S option, or\n");
fprintf (stderr, " by setting the LPD_SERVER environment variable\n");
return EOF;
}
if ((hp = gethostbynameoraddr (server)) == NULL) {
fprintf (stderr, "lpr: can't find network address for %s\n",
server);
fflush (stderr);
return EOF;
}
s.sin_family = AF_INET;
if ((sp = getservbyname ("printer", "tcp")) == NULL)
s.sin_port = htons (515);
else
s.sin_port = sp->s_port;
/*
* On some systems h_addr is a macro that is defined to be h_addr_list[0]
* On other (ancient) systems, h_addr is a member of the hostent structure.
* So if h_addr is defined as a macro, then we must have the list...
*/
#ifdef h_addr
for (i = 0; hp->h_addr_list[i] ; ++i) {
fd = get_priv_tcp_socket ();
disable_special_privileges ();
if (fd < 0)
return EOF;
bcopy (hp->h_addr_list[i], &s.sin_addr, sizeof (s.sin_addr));
if (debug)
fprintf (stderr, "Trying %s...", inet_ntoa (s.sin_addr));
last_connect_failed = 0; /* "I'm ashamed of this." - SMK */
if (connect (fd, &s, sizeof s) == 0) {
if (debug)
fprintf (stderr, "open\n");
break;
}
else {
close (fd); /* reuse fd */
if (debug)
perror ("");
last_connect_failed = 1;
}
}
if (last_connect_failed) {
perror ("connect");
return EOF;
}
#else
fd = get_priv_tcp_socket ();
disable_special_privileges ();
if (fd < 0)
return EOF;
bcopy (hp->h_addr, (char *) &s.sin_addr, sizeof(s.sin_addr));
if (connect (fd, &s, sizeof s) < 0) {
perror ("connect");
close (fd);
return EOF;
}
#endif
max_net_read = max_net_write = 32767;
return fd;
}
/*
* Turn off set-uid privileges.
* We have to be running set-uid to root in order to bind to a privileged
* port. In order to minimize the security risk, this function is called
* from open_job() immediately after open_lpd() returns.
*/
disable_special_privileges ()
{
setuid (getuid ());
}