bin/189053: [patch] Add -b flag to lpd(8)

Ayan George ayan at ayan.net
Sun Apr 27 23:40:01 UTC 2014


The following reply was made to PR bin/189053; it has been noted by GNATS.

From: Ayan George <ayan at ayan.net>
To: bug-followup at FreeBSD.org, ayan at ayan.net
Cc:  
Subject: Re: bin/189053: [patch] Add -b flag to lpd(8)
Date: Sun, 27 Apr 2014 19:26:34 -0400

 This is a multi-part message in MIME format.
 --------------010800040304090007030100
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit
 
 
 --------------010800040304090007030100
 Content-Type: text/x-patch;
  name="lpd-2.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="lpd-2.patch"
 
 diff --git a/usr.sbin/lpr/lpd/lpd.c b/usr.sbin/lpr/lpd/lpd.c
 index 4aa49ca..4a2336c 100644
 --- a/usr.sbin/lpr/lpd/lpd.c
 +++ b/usr.sbin/lpr/lpd/lpd.c
 @@ -112,7 +112,7 @@ static void	 startup(void);
  static void	 chkhost(struct sockaddr *_f, int _ch_opts);
  static int	 ckqueue(struct printer *_pp);
  static void	 fhosterr(int _ch_opts, char *_sysmsg, char *_usermsg);
 -static int	*socksetup(int _af, int _debuglvl);
 +static int *socksetup(int af, size_t blist_size, char *blist[blist_size], int debuglvl);
  static void	 usage(void);
  
  /* XXX from libc/net/rcmd.c */
 @@ -144,14 +144,28 @@ main(int argc, char **argv)
  	socket_debug = 0;
  	gethostname(local_host, sizeof(local_host));
  
 +	char **blist = NULL;
 +	size_t blist_size = 0;
 +
  	progname = "lpd";
  
  	if (euid != 0)
  		errx(EX_NOPERM,"must run as root");
  
  	errs = 0;
 -	while ((i = getopt(argc, argv, "cdlpswW46")) != -1)
 +	while ((i = getopt(argc, argv, "b:cdlpswW46")) != -1)
  		switch (i) {
 +		case 'b':
 +			/* add bind address to list. */
 +			blist_size++;
 +			blist = realloc(blist, sizeof (char *) * blist_size);
 +
 +			if (blist == NULL)
 +				errx(EX_SOFTWARE, "Could not allocate memory for bind list.");		
 +			blist[blist_size-1] = optarg;
 +			fprintf(stderr,"made it.\n");
 +			break;
 +
  		case 'c':
  			/* log all kinds of connection-errors to syslog */
  			ch_options |= LPD_LOGCONNERR;
 @@ -204,7 +218,6 @@ main(int argc, char **argv)
  		 * listed here to "reserve" them, because the option-letters
  		 * are used by either NetBSD or OpenBSD (as of July 2001).
  		 */ 
 -		case 'b':		/* set bind-addr */
  		case 'n':		/* set max num of children */
  		case 'r':		/* allow 'of' for remote ptrs */
  					/* ...[not needed in freebsd] */
 @@ -220,12 +233,13 @@ main(int argc, char **argv)
  		usage();
  
  	if (argc == 1) {
 -		if ((i = atoi(argv[0])) == 0)
 +		int requested_port = atoi(argv[0]);
 +		if (requested_port == 0)
  			usage();
 -		if (i < 0 || i > USHRT_MAX)
 -			errx(EX_USAGE, "port # %d is invalid", i);
 +		if (requested_port < 0 || requested_port > USHRT_MAX)
 +			errx(EX_USAGE, "port # %d is invalid", requested_port);
  
 -		serv.s_port = htons(i);
 +		serv.s_port = htons(requested_port);
  		sp = &serv;
  		argc--;
  	} else {
 @@ -339,7 +353,11 @@ main(int argc, char **argv)
  	FD_SET(funix, &defreadfds);
  	listen(funix, 5);
  	if (sflag == 0) {
 -		finet = socksetup(family, socket_debug);
 +		finet = socksetup(family, blist_size, blist, socket_debug);
 +
 +		/* Now we're done with blist. */
 +		if (blist)
 +			free(blist);
  	} else
  		finet = NULL;	/* pretend we couldn't open TCP socket. */
  	if (finet) {
 @@ -855,7 +873,7 @@ fhosterr(int ch_opts, char *sysmsg, char *usermsg)
  /* if af is PF_UNSPEC more than one socket may be returned */
  /* the returned list is dynamically allocated, so caller needs to free it */
  static int *
 -socksetup(int af, int debuglvl)
 +socksetup(int af, size_t blist_size, char *blist[blist_size], int debuglvl)
  {
  	struct addrinfo hints, *res, *r;
  	int error, maxs, *s, *socks;
 @@ -865,58 +883,67 @@ socksetup(int af, int debuglvl)
  	hints.ai_flags = AI_PASSIVE;
  	hints.ai_family = af;
  	hints.ai_socktype = SOCK_STREAM;
 -	error = getaddrinfo(NULL, "printer", &hints, &res);
 -	if (error) {
 -		syslog(LOG_ERR, "%s", gai_strerror(error));
 -		mcleanup(0);
 -	}
  
 -	/* Count max number of sockets we may open */
 -	for (maxs = 0, r = res; r; r = r->ai_next, maxs++)
 -		;
 -	socks = malloc((maxs + 1) * sizeof(int));
 -	if (!socks) {
 -		syslog(LOG_ERR, "couldn't allocate memory for sockets");
 -		mcleanup(0);
 +	if (blist_size == 0 || blist == NULL) {
 +		blist_size = 1;
 +		blist = (char *[]){ "0.0.0.0" };
  	}
  
 -	*socks = 0;   /* num of sockets counter at start of array */
 -	s = socks + 1;
 -	for (r = res; r; r = r->ai_next) {
 -		*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
 -		if (*s < 0) {
 -			syslog(LOG_DEBUG, "socket(): %m");
 -			continue;
 +	for (size_t baddr = 0; baddr < blist_size; baddr++ ) {
 +		error = getaddrinfo(blist[baddr], "printer", &hints, &res);
 +		if (error) {
 +			syslog(LOG_ERR, "%s", gai_strerror(error));
 +			mcleanup(0);
  		}
 -		if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))
 -		    < 0) {
 -			syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
 -			close(*s);
 -			continue;
 +
 +		/* Count max number of sockets we may open */
 +		for (maxs = 0, r = res; r; r = r->ai_next, maxs++)
 +			;
 +		socks = malloc((maxs + 1) * sizeof(int));
 +		if (!socks) {
 +			syslog(LOG_ERR, "couldn't allocate memory for sockets");
 +			mcleanup(0);
  		}
 -		if (debuglvl)
 -			if (setsockopt(*s, SOL_SOCKET, SO_DEBUG, &debuglvl,
 -			    sizeof(debuglvl)) < 0) {
 -				syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
 +
 +		*socks = 0;   /* num of sockets counter at start of array */
 +		s = socks + 1;
 +
 +		for (r = res; r; r = r->ai_next) {
 +			*s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
 +			if (*s < 0) {
 +				syslog(LOG_DEBUG, "socket(): %m");
 +				continue;
 +			}
 +			if (setsockopt(*s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))
 +					< 0) {
 +				syslog(LOG_ERR, "setsockopt(SO_REUSEADDR): %m");
  				close(*s);
  				continue;
  			}
 -		if (r->ai_family == AF_INET6) {
 -			if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
 -				       &on, sizeof(on)) < 0) {
 -				syslog(LOG_ERR,
 -				       "setsockopt (IPV6_V6ONLY): %m");
 +			if (debuglvl)
 +				if (setsockopt(*s, SOL_SOCKET, SO_DEBUG, &debuglvl,
 +						sizeof(debuglvl)) < 0) {
 +					syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m");
 +					close(*s);
 +					continue;
 +				}
 +			if (r->ai_family == AF_INET6) {
 +				if (setsockopt(*s, IPPROTO_IPV6, IPV6_V6ONLY,
 +								 &on, sizeof(on)) < 0) {
 +					syslog(LOG_ERR,
 +								 "setsockopt (IPV6_V6ONLY): %m");
 +					close(*s);
 +					continue;
 +				}
 +			}
 +			if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
 +				syslog(LOG_DEBUG, "bind(): %m");
  				close(*s);
  				continue;
  			}
 +			(*socks)++;
 +			s++;
  		}
 -		if (bind(*s, r->ai_addr, r->ai_addrlen) < 0) {
 -			syslog(LOG_DEBUG, "bind(): %m");
 -			close(*s);
 -			continue;
 -		}
 -		(*socks)++;
 -		s++;
  	}
  
  	if (res)
 
 --------------010800040304090007030100--


More information about the freebsd-bugs mailing list