home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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 ());
- }
-