16751Swpaul/*
26751Swpaul
38857SrgrimesThis code is not copyright, and is placed in the public domain. Feel free to
46751Swpauluse and modify. Please send modifications and/or suggestions + bug fixes to
56751Swpaul
66751Swpaul        Klas Heggemann <klas@nada.kth.se>
76751Swpaul
829102Scharnier*/
96751Swpaul
1029102Scharnier#ifndef lint
1129102Scharnierstatic const char rcsid[] =
1250479Speter  "$FreeBSD$";
1329102Scharnier#endif /* not lint */
146751Swpaul
1529102Scharnier#include <ctype.h>
1629102Scharnier#include <err.h>
1729102Scharnier#include <netdb.h>
189718Swpaul#include <stdio.h>
1929102Scharnier#include <stdlib.h>
209718Swpaul#include <string.h>
216751Swpaul#include <syslog.h>
2229102Scharnier#include <unistd.h>
2329102Scharnier#include <rpc/rpc.h>
2429102Scharnier#include <rpc/pmap_clnt.h>
256751Swpaul#include <sys/ioctl.h>
2629102Scharnier#include <sys/socket.h>
2729102Scharnier#include <sys/stat.h>
2829102Scharnier#include <sys/types.h>
2936917Speter#include <netinet/in.h>
3036917Speter#include <arpa/inet.h>
316751Swpaul#include "bootparam_prot.h"
326751Swpaul
336751Swpaulint debug = 0;
346751Swpaulint dolog = 0;
35175823Srinkin_addr_t route_addr = -1;
366751Swpaulstruct sockaddr_in my_addr;
376751Swpaulchar *bootpfile = "/etc/bootparams";
386751Swpaul
39173412Skevlostatic void usage(void);
406751Swpaul
4129102Scharnierint
42291042Sngiemain(int argc, char **argv)
436751Swpaul{
446751Swpaul	SVCXPRT *transp;
456751Swpaul	struct hostent *he;
466751Swpaul	struct stat buf;
47181125Scognet	int c;
486751Swpaul
4924428Simp	while ((c = getopt(argc, argv,"dsr:f:")) != -1)
50181143Scognet	  switch (c) {
516751Swpaul	  case 'd':
526751Swpaul	    debug = 1;
536751Swpaul	    break;
546751Swpaul	  case 'r':
55130243Sstefanf	      if (isdigit((unsigned char)*optarg)) {
566751Swpaul		route_addr = inet_addr(optarg);
576751Swpaul		break;
586751Swpaul	      } else {
596751Swpaul		he = gethostbyname(optarg);
606751Swpaul		if (he) {
616751Swpaul		   bcopy(he->h_addr, (char *)&route_addr, sizeof(route_addr));
626751Swpaul		   break;
6329102Scharnier		} else {
64130243Sstefanf		   errx(1, "no such host %s", optarg);
6529102Scharnier		}
666751Swpaul	      }
676751Swpaul	  case 'f':
686751Swpaul	    bootpfile = optarg;
696751Swpaul	    break;
706751Swpaul	  case 's':
716751Swpaul	    dolog = 1;
728857Srgrimes#ifndef LOG_DAEMON
7329102Scharnier	    openlog("bootparamd", 0 , 0);
746751Swpaul#else
7529102Scharnier	    openlog("bootparamd", 0 , LOG_DAEMON);
766751Swpaul	    setlogmask(LOG_UPTO(LOG_NOTICE));
776751Swpaul#endif
786751Swpaul	    break;
796751Swpaul	  default:
8029102Scharnier	    usage();
816751Swpaul	  }
826751Swpaul
8329102Scharnier	if ( stat(bootpfile, &buf ) )
8429102Scharnier	  err(1, "%s", bootpfile);
856751Swpaul
866751Swpaul	if (route_addr == -1) {
876751Swpaul	  get_myaddress(&my_addr);
886751Swpaul	  bcopy(&my_addr.sin_addr.s_addr, &route_addr, sizeof (route_addr));
896751Swpaul	}
906751Swpaul
916751Swpaul	if (!debug) {
9229102Scharnier	  if (daemon(0,0))
9329102Scharnier	    err(1, "fork");
946751Swpaul	}
956751Swpaul
968857Srgrimes
976751Swpaul	(void)pmap_unset(BOOTPARAMPROG, BOOTPARAMVERS);
986751Swpaul
996751Swpaul	transp = svcudp_create(RPC_ANYSOCK);
10029102Scharnier	if (transp == NULL)
10129102Scharnier		errx(1, "cannot create udp service");
10229102Scharnier	if (!svc_register(transp, BOOTPARAMPROG, BOOTPARAMVERS, bootparamprog_1, IPPROTO_UDP))
10329102Scharnier		errx(1, "unable to register (BOOTPARAMPROG, BOOTPARAMVERS, udp)");
1046751Swpaul
1056751Swpaul	svc_run();
10629102Scharnier	errx(1, "svc_run returned");
10729102Scharnier}
10829102Scharnier
10929102Scharnierstatic void
110291042Sngieusage(void)
11129102Scharnier{
11229102Scharnier	fprintf(stderr,
11329102Scharnier		"usage: bootparamd [-d] [-s] [-r router] [-f bootparmsfile]\n");
1146751Swpaul	exit(1);
1156751Swpaul}
116