122700Sdist /* 234920Sbostic * Copyright (c) 1983 Eric P. Allman 333780Sbostic * Copyright (c) 1988 Regents of the University of California. 433780Sbostic * All rights reserved. 533780Sbostic * 642825Sbostic * %sccs.include.redist.c% 733780Sbostic */ 822700Sdist 933932Sbostic #include <errno.h> 1040962Sbostic #include "sendmail.h" 114535Seric 1233780Sbostic #ifndef lint 1333780Sbostic #ifdef DAEMON 14*55019Seric static char sccsid[] = "@(#)daemon.c 5.47 (Berkeley) 07/12/92 (with daemon mode)"; 1533780Sbostic #else 16*55019Seric static char sccsid[] = "@(#)daemon.c 5.47 (Berkeley) 07/12/92 (without daemon mode)"; 1733780Sbostic #endif 1833780Sbostic #endif /* not lint */ 194535Seric 2033780Sbostic #ifdef DAEMON 2133780Sbostic 2223120Seric # include <netdb.h> 2324945Seric # include <sys/signal.h> 2423120Seric # include <sys/wait.h> 2523120Seric # include <sys/time.h> 2623120Seric # include <sys/resource.h> 275978Seric 284535Seric /* 294535Seric ** DAEMON.C -- routines to use when running as a daemon. 307556Seric ** 317556Seric ** This entire file is highly dependent on the 4.2 BSD 327556Seric ** interprocess communication primitives. No attempt has 337556Seric ** been made to make this file portable to Version 7, 347556Seric ** Version 6, MPX files, etc. If you should try such a 357556Seric ** thing yourself, I recommend chucking the entire file 367556Seric ** and starting from scratch. Basic semantics are: 377556Seric ** 387556Seric ** getrequests() 397556Seric ** Opens a port and initiates a connection. 407556Seric ** Returns in a child. Must set InChannel and 417556Seric ** OutChannel appropriately. 4210206Seric ** clrdaemon() 4310206Seric ** Close any open files associated with getting 4410206Seric ** the connection; this is used when running the queue, 4510206Seric ** etc., to avoid having extra file descriptors during 4610206Seric ** the queue run and to avoid confusing the network 4710206Seric ** code (if it cares). 4852106Seric ** makeconnection(host, port, outfile, infile, usesecureport) 497556Seric ** Make a connection to the named host on the given 507556Seric ** port. Set *outfile and *infile to the files 517556Seric ** appropriate for communication. Returns zero on 527556Seric ** success, else an exit status describing the 537556Seric ** error. 54*55019Seric ** maphostname(hbuf, hbufsize, avp) 5525699Seric ** Convert the entry in hbuf into a canonical form. It 5625699Seric ** may not be larger than hbufsize. 574535Seric */ 584535Seric /* 594535Seric ** GETREQUESTS -- open mail IPC port and get requests. 604535Seric ** 614535Seric ** Parameters: 624535Seric ** none. 634535Seric ** 644535Seric ** Returns: 654535Seric ** none. 664535Seric ** 674535Seric ** Side Effects: 684535Seric ** Waits until some interesting activity occurs. When 694535Seric ** it does, a child is created to process it, and the 704535Seric ** parent waits for completion. Return from this 719886Seric ** routine is always in the child. The file pointers 729886Seric ** "InChannel" and "OutChannel" should be set to point 739886Seric ** to the communication channel. 744535Seric */ 754535Seric 7616144Seric int DaemonSocket = -1; /* fd describing socket */ 7716144Seric 784535Seric getrequests() 794535Seric { 809610Seric int t; 819610Seric register struct servent *sp; 8225027Seric int on = 1; 8353751Seric bool refusingconnections = TRUE; 8452106Seric struct sockaddr_in srvraddr; 8546928Sbostic extern void reapchild(); 867117Seric 879610Seric /* 889610Seric ** Set up the address for the mailer. 899610Seric */ 909610Seric 919610Seric sp = getservbyname("smtp", "tcp"); 929610Seric if (sp == NULL) 939610Seric { 949610Seric syserr("server \"smtp\" unknown"); 9510167Seric goto severe; 969610Seric } 9752106Seric srvraddr.sin_family = AF_INET; 9852106Seric srvraddr.sin_addr.s_addr = INADDR_ANY; 9952106Seric srvraddr.sin_port = sp->s_port; 1009610Seric 1019610Seric /* 1029610Seric ** Try to actually open the connection. 1039610Seric */ 1049610Seric 1059610Seric if (tTd(15, 1)) 10652106Seric printf("getrequests: port 0x%x\n", srvraddr.sin_port); 1079610Seric 1089610Seric /* get a socket for the SMTP connection */ 10923120Seric DaemonSocket = socket(AF_INET, SOCK_STREAM, 0); 11010206Seric if (DaemonSocket < 0) 1119610Seric { 1129610Seric /* probably another daemon already */ 1139610Seric syserr("getrequests: can't create socket"); 1149610Seric severe: 1159610Seric # ifdef LOG 1169610Seric if (LogLevel > 0) 11724858Seric syslog(LOG_ALERT, "cannot get connection"); 1189610Seric # endif LOG 1199610Seric finis(); 1209610Seric } 12110347Seric 12210347Seric /* turn on network debugging? */ 12310347Seric if (tTd(15, 15)) 12424945Seric (void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof on); 12510347Seric 12625027Seric (void) setsockopt(DaemonSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on); 12725027Seric (void) setsockopt(DaemonSocket, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof on); 12825027Seric 12952106Seric if (bind(DaemonSocket, (struct sockaddr *)&srvraddr, sizeof srvraddr) < 0) 1309610Seric { 1319610Seric syserr("getrequests: cannot bind"); 13210206Seric (void) close(DaemonSocket); 1339610Seric goto severe; 1349610Seric } 1359610Seric 13624955Seric (void) signal(SIGCHLD, reapchild); 13724945Seric 1389610Seric if (tTd(15, 1)) 13910206Seric printf("getrequests: %d\n", DaemonSocket); 1409610Seric 1414631Seric for (;;) 1424631Seric { 14314875Seric register int pid; 14411147Seric auto int lotherend; 14553751Seric extern bool refuseconnections(); 14611147Seric 14714875Seric /* see if we are rejecting connections */ 14853751Seric CurrentLA = getla(); 14953751Seric if (refuseconnections()) 15036584Sbostic { 15153751Seric if (!refusingconnections) 15253751Seric { 15353751Seric /* don't queue so peer will fail quickly */ 15453751Seric (void) listen(DaemonSocket, 0); 15553751Seric refusingconnections = TRUE; 15653751Seric } 15753751Seric setproctitle("rejecting connections: load average: %.2f", 15853751Seric (double)CurrentLA); 15914875Seric sleep(5); 16053751Seric continue; 16136584Sbostic } 16214875Seric 16353751Seric if (refusingconnections) 16453751Seric { 16553751Seric /* start listening again */ 16653751Seric if (listen(DaemonSocket, 10) < 0) 16753751Seric { 16853751Seric syserr("getrequests: cannot listen"); 16953751Seric (void) close(DaemonSocket); 17053751Seric goto severe; 17153751Seric } 17253751Seric setproctitle("accepting connections"); 17353751Seric refusingconnections = FALSE; 17453751Seric } 17553751Seric 1769610Seric /* wait for a connection */ 1779610Seric do 1789610Seric { 1799610Seric errno = 0; 18036230Skarels lotherend = sizeof RealHostAddr; 18146928Sbostic t = accept(DaemonSocket, 18246928Sbostic (struct sockaddr *)&RealHostAddr, &lotherend); 1839610Seric } while (t < 0 && errno == EINTR); 1849610Seric if (t < 0) 1855978Seric { 1869610Seric syserr("getrequests: accept"); 1879610Seric sleep(5); 1889610Seric continue; 1895978Seric } 1904631Seric 1915978Seric /* 1925978Seric ** Create a subprocess to process the mail. 1935978Seric */ 1945978Seric 1957677Seric if (tTd(15, 2)) 1969610Seric printf("getrequests: forking (fd = %d)\n", t); 1975978Seric 1984636Seric pid = fork(); 1994636Seric if (pid < 0) 2004631Seric { 2014636Seric syserr("daemon: cannot fork"); 2024636Seric sleep(10); 2039610Seric (void) close(t); 2044636Seric continue; 2054631Seric } 2064631Seric 2074636Seric if (pid == 0) 2084631Seric { 20911147Seric extern struct hostent *gethostbyaddr(); 21011147Seric register struct hostent *hp; 21111147Seric char buf[MAXNAME]; 21211147Seric 2134636Seric /* 2144636Seric ** CHILD -- return to caller. 21511147Seric ** Collect verified idea of sending host. 2164636Seric ** Verify calling user id if possible here. 2174636Seric */ 2184631Seric 21924955Seric (void) signal(SIGCHLD, SIG_DFL); 22024950Seric 22111147Seric /* determine host name */ 22236230Skarels hp = gethostbyaddr((char *) &RealHostAddr.sin_addr, sizeof RealHostAddr.sin_addr, AF_INET); 22311147Seric if (hp != NULL) 22423104Seric (void) strcpy(buf, hp->h_name); 22511147Seric else 22616884Seric { 22716884Seric extern char *inet_ntoa(); 22816884Seric 22916884Seric /* produce a dotted quad */ 23016884Seric (void) sprintf(buf, "[%s]", 23136230Skarels inet_ntoa(RealHostAddr.sin_addr)); 23216884Seric } 23316884Seric 23416884Seric /* should we check for illegal connection here? XXX */ 23516884Seric 23611147Seric RealHostName = newstr(buf); 23711147Seric 23810206Seric (void) close(DaemonSocket); 2399610Seric InChannel = fdopen(t, "r"); 24021062Seric OutChannel = fdopen(dup(t), "w"); 2417677Seric if (tTd(15, 2)) 2425978Seric printf("getreq: returning\n"); 2437876Seric # ifdef LOG 2447876Seric if (LogLevel > 11) 2457876Seric syslog(LOG_DEBUG, "connected, pid=%d", getpid()); 2467876Seric # endif LOG 2474636Seric return; 2484631Seric } 2494631Seric 2507117Seric /* close the port so that others will hang (for a while) */ 2519610Seric (void) close(t); 2524631Seric } 2539886Seric /*NOTREACHED*/ 2544631Seric } 2555978Seric /* 25610206Seric ** CLRDAEMON -- reset the daemon connection 25710206Seric ** 25810206Seric ** Parameters: 25910206Seric ** none. 26010206Seric ** 26110206Seric ** Returns: 26210206Seric ** none. 26310206Seric ** 26410206Seric ** Side Effects: 26510206Seric ** releases any resources used by the passive daemon. 26610206Seric */ 26710206Seric 26810206Seric clrdaemon() 26910206Seric { 27010206Seric if (DaemonSocket >= 0) 27110206Seric (void) close(DaemonSocket); 27210206Seric DaemonSocket = -1; 27310206Seric } 27410206Seric /* 2756039Seric ** MAKECONNECTION -- make a connection to an SMTP socket on another machine. 2766039Seric ** 2776039Seric ** Parameters: 2786039Seric ** host -- the name of the host. 2796633Seric ** port -- the port number to connect to. 28053739Seric ** mci -- a pointer to the mail connection information 28153739Seric ** structure to be filled in. 28252106Seric ** usesecureport -- if set, use a low numbered (reserved) 28352106Seric ** port to provide some rudimentary authentication. 2846039Seric ** 2856039Seric ** Returns: 2866039Seric ** An exit code telling whether the connection could be 2876039Seric ** made and if not why not. 2886039Seric ** 2896039Seric ** Side Effects: 2906039Seric ** none. 2916039Seric */ 2925978Seric 29354967Seric int 29453739Seric makeconnection(host, port, mci, usesecureport) 2956039Seric char *host; 2967286Seric u_short port; 29754967Seric register MCI *mci; 29852106Seric bool usesecureport; 2996039Seric { 30029430Sbloom register int i, s; 30129430Sbloom register struct hostent *hp = (struct hostent *)NULL; 30252106Seric struct sockaddr_in addr; 30352106Seric int sav_errno; 30429430Sbloom extern char *inet_ntoa(); 30535651Seric #ifdef NAMED_BIND 30635651Seric extern int h_errno; 30735651Seric #endif 3086039Seric 3096039Seric /* 3106039Seric ** Set up the address for the mailer. 3119308Seric ** Accept "[a.b.c.d]" syntax for host name. 3126039Seric */ 3136039Seric 31435651Seric #ifdef NAMED_BIND 31525475Smiriam h_errno = 0; 31635651Seric #endif 31725475Smiriam errno = 0; 31825475Smiriam 3199308Seric if (host[0] == '[') 3209308Seric { 32111147Seric long hid; 32211147Seric register char *p = index(host, ']'); 3239308Seric 32411147Seric if (p != NULL) 3259308Seric { 32611147Seric *p = '\0'; 32711147Seric hid = inet_addr(&host[1]); 32811147Seric *p = ']'; 3299308Seric } 33011147Seric if (p == NULL || hid == -1) 3319308Seric { 3329308Seric usrerr("Invalid numeric domain spec \"%s\"", host); 3339308Seric return (EX_NOHOST); 3349308Seric } 33552106Seric addr.sin_addr.s_addr = hid; 3369308Seric } 3379610Seric else 3389610Seric { 33929430Sbloom hp = gethostbyname(host); 34025475Smiriam if (hp == NULL) 34124945Seric { 34235651Seric #ifdef NAMED_BIND 34325475Smiriam if (errno == ETIMEDOUT || h_errno == TRY_AGAIN) 34425475Smiriam return (EX_TEMPFAIL); 34525657Seric 34635651Seric /* if name server is specified, assume temp fail */ 34735651Seric if (errno == ECONNREFUSED && UseNameServer) 34835651Seric return (EX_TEMPFAIL); 34935651Seric #endif 35035651Seric 35125657Seric /* 35225657Seric ** XXX Should look for mail forwarder record here 35325657Seric ** XXX if (h_errno == NO_ADDRESS). 35425657Seric */ 35525657Seric 35625475Smiriam return (EX_NOHOST); 35724945Seric } 35852106Seric bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); 35929430Sbloom i = 1; 3609610Seric } 3619610Seric 3629610Seric /* 3639610Seric ** Determine the port number. 3649610Seric */ 3659610Seric 36610011Seric if (port != 0) 36752106Seric addr.sin_port = htons(port); 36810011Seric else 3699610Seric { 3709610Seric register struct servent *sp = getservbyname("smtp", "tcp"); 3719610Seric 3729610Seric if (sp == NULL) 3739610Seric { 3749610Seric syserr("makeconnection: server \"smtp\" unknown"); 3759610Seric return (EX_OSFILE); 3769610Seric } 37752106Seric addr.sin_port = sp->s_port; 3789610Seric } 3796039Seric 3806039Seric /* 3816039Seric ** Try to actually open the connection. 3826039Seric */ 3836039Seric 38429430Sbloom again: 3857677Seric if (tTd(16, 1)) 38629430Sbloom printf("makeconnection (%s [%s])\n", host, 38752106Seric inet_ntoa(addr.sin_addr)); 3886039Seric 38952106Seric if (usesecureport) 39052106Seric { 39152106Seric int rport = IPPORT_RESERVED - 1; 39252106Seric 39352106Seric s = rresvport(&rport); 39452106Seric } 39552106Seric else 39652106Seric { 39752106Seric s = socket(AF_INET, SOCK_STREAM, 0); 39852106Seric } 3996039Seric if (s < 0) 4006039Seric { 40152106Seric sav_errno = errno; 4026039Seric syserr("makeconnection: no socket"); 4036039Seric goto failure; 4046039Seric } 4056039Seric 4067677Seric if (tTd(16, 1)) 40754967Seric printf("makeconnection: fd=%d\n", s); 40810347Seric 40910347Seric /* turn on network debugging? */ 41010347Seric if (tTd(16, 14)) 41124945Seric { 41224945Seric int on = 1; 41324945Seric (void) setsockopt(DaemonSocket, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof on); 41424945Seric } 41540932Srick if (CurEnv->e_xfp != NULL) 41640932Srick (void) fflush(CurEnv->e_xfp); /* for debugging */ 41714383Seric errno = 0; /* for debugging */ 41852106Seric addr.sin_family = AF_INET; 41952106Seric if (connect(s, (struct sockaddr *) &addr, sizeof addr) < 0) 4206039Seric { 42127744Sbloom sav_errno = errno; 42227744Sbloom (void) close(s); 42329430Sbloom if (hp && hp->h_addr_list[i]) 42429430Sbloom { 42552106Seric bcopy(hp->h_addr_list[i++], (char *) &addr.sin_addr, 42652106Seric hp->h_length); 42729430Sbloom goto again; 42829430Sbloom } 42929430Sbloom 4306039Seric /* failure, decide if temporary or not */ 4316039Seric failure: 43227744Sbloom switch (sav_errno) 4336039Seric { 4346039Seric case EISCONN: 4356039Seric case ETIMEDOUT: 4366897Seric case EINPROGRESS: 4376897Seric case EALREADY: 4386897Seric case EADDRINUSE: 43910123Seric case EHOSTDOWN: 4406897Seric case ENETDOWN: 4416897Seric case ENETRESET: 4426897Seric case ENOBUFS: 4437204Seric case ECONNREFUSED: 44411546Seric case ECONNRESET: 44510081Seric case EHOSTUNREACH: 44610098Seric case ENETUNREACH: 44751995Seric #ifdef ENOSR 44851995Seric case ENOSR: 44951995Seric #endif 4506039Seric /* there are others, I'm sure..... */ 4516039Seric return (EX_TEMPFAIL); 4526039Seric 45311147Seric case EPERM: 45411147Seric /* why is this happening? */ 45511147Seric syserr("makeconnection: funny failure, addr=%lx, port=%x", 45652106Seric addr.sin_addr.s_addr, addr.sin_port); 45714383Seric return (EX_TEMPFAIL); 45811147Seric 4596039Seric default: 46040932Srick { 46140932Srick extern char *errstring(); 46240932Srick 46340932Srick message(Arpa_Info, "%s", errstring(sav_errno)); 46440932Srick return (EX_UNAVAILABLE); 46540932Srick } 4666039Seric } 4676039Seric } 4686039Seric 4696039Seric /* connection ok, put it into canonical form */ 47053739Seric mci->mci_out = fdopen(s, "w"); 47153739Seric mci->mci_in = fdopen(dup(s), "r"); 4726039Seric 47310098Seric return (EX_OK); 4746039Seric } 47510758Seric /* 47610758Seric ** MYHOSTNAME -- return the name of this host. 47710758Seric ** 47810758Seric ** Parameters: 47910758Seric ** hostbuf -- a place to return the name of this host. 48012313Seric ** size -- the size of hostbuf. 48110758Seric ** 48210758Seric ** Returns: 48310758Seric ** A list of aliases for this host. 48410758Seric ** 48510758Seric ** Side Effects: 48610758Seric ** none. 48710758Seric */ 4886039Seric 48910758Seric char ** 49012313Seric myhostname(hostbuf, size) 49110758Seric char hostbuf[]; 49212313Seric int size; 49310758Seric { 49410758Seric extern struct hostent *gethostbyname(); 49511147Seric struct hostent *hp; 49610758Seric 49723120Seric if (gethostname(hostbuf, size) < 0) 49823120Seric { 49923120Seric (void) strcpy(hostbuf, "localhost"); 50023120Seric } 50111147Seric hp = gethostbyname(hostbuf); 50211147Seric if (hp != NULL) 50316877Seric { 50423104Seric (void) strcpy(hostbuf, hp->h_name); 50511147Seric return (hp->h_aliases); 50616877Seric } 50710758Seric else 50810758Seric return (NULL); 50910758Seric } 51051315Seric /* 51153751Seric ** MAPHOSTNAME -- turn a hostname into canonical form 51253751Seric ** 51353751Seric ** Parameters: 51453751Seric ** hbuf -- a buffer containing a hostname. 51553751Seric ** hbsize -- the size of hbuf. 516*55019Seric ** avp -- unused -- for compatibility with other mapping 517*55019Seric ** functions. 51853751Seric ** 51953751Seric ** Returns: 52053751Seric ** The mapping, if found. 52153751Seric ** NULL if no mapping found. 52253751Seric ** 52353751Seric ** Side Effects: 52453751Seric ** Looks up the host specified in hbuf. If it is not 52553751Seric ** the canonical name for that host, return the canonical 52653751Seric ** name. 52753751Seric */ 52851315Seric 52953751Seric char * 53053751Seric maphostname(hbuf, hbsize, avp) 53116911Seric char *hbuf; 53216911Seric int hbsize; 53353751Seric char **avp; 53416911Seric { 53516911Seric register struct hostent *hp; 53633932Sbostic u_long in_addr; 53740994Sbostic char ptr[256], *cp; 53833932Sbostic struct hostent *gethostbyaddr(); 53916911Seric 54053751Seric /* allow room for trailing dot on correct match */ 54153751Seric if (ConfigLevel >= 2) 54253751Seric hbsize--; 54353751Seric 54425574Smiriam /* 54533932Sbostic * If first character is a bracket, then it is an address 54633932Sbostic * lookup. Address is copied into a temporary buffer to 54733932Sbostic * strip the brackets and to preserve hbuf if address is 54833932Sbostic * unknown. 54933932Sbostic */ 55053751Seric 55151315Seric if (*hbuf != '[') 55253751Seric { 553*55019Seric extern bool getcanonname(); 554*55019Seric 55553751Seric if (getcanonname(hbuf, hbsize)) 55653751Seric { 55753751Seric /* found a match -- add the trailing dot */ 55853751Seric if (ConfigLevel >= 2) 55953751Seric (void) strcat(hbuf, "."); 56053751Seric return hbuf; 56153751Seric } 56253751Seric else 56353751Seric return NULL; 56453751Seric } 56540994Sbostic if ((cp = index(strcpy(ptr, hbuf), ']')) == NULL) 56653751Seric return (NULL); 56740994Sbostic *cp = '\0'; 56833932Sbostic in_addr = inet_addr(&ptr[1]); 56933932Sbostic hp = gethostbyaddr((char *)&in_addr, sizeof(struct in_addr), AF_INET); 57033932Sbostic if (hp == NULL) 57153751Seric return (NULL); 57253751Seric 57353751Seric /* found a match -- copy and dot terminate */ 57433932Sbostic if (strlen(hp->h_name) >= hbsize) 57533932Sbostic hp->h_name[hbsize - 1] = '\0'; 57653751Seric (void) strcpy(hbuf, hp->h_name); 57753751Seric if (ConfigLevel >= 2) 57853751Seric (void) strcat(hbuf, "."); 57953751Seric return hbuf; 58033932Sbostic } 58116911Seric 58210758Seric # else DAEMON 58316911Seric /* code for systems without sophisticated networking */ 58410758Seric 58510758Seric /* 58610758Seric ** MYHOSTNAME -- stub version for case of no daemon code. 58711297Seric ** 58811297Seric ** Can't convert to upper case here because might be a UUCP name. 58912313Seric ** 59012313Seric ** Mark, you can change this to be anything you want...... 59110758Seric */ 59210758Seric 59310758Seric char ** 59412313Seric myhostname(hostbuf, size) 59510758Seric char hostbuf[]; 59612313Seric int size; 59710758Seric { 59810758Seric register FILE *f; 59910758Seric 60010758Seric hostbuf[0] = '\0'; 60110758Seric f = fopen("/usr/include/whoami", "r"); 60210758Seric if (f != NULL) 60310758Seric { 60412313Seric (void) fgets(hostbuf, size, f); 60510758Seric fixcrlf(hostbuf, TRUE); 60610758Seric (void) fclose(f); 60710758Seric } 60810758Seric return (NULL); 60910758Seric } 61016911Seric /* 61116911Seric ** MAPHOSTNAME -- turn a hostname into canonical form 61216911Seric ** 61316911Seric ** Parameters: 61416911Seric ** hbuf -- a buffer containing a hostname. 61516911Seric ** hbsize -- the size of hbuf. 61653751Seric ** avp -- a pointer to a (cf file defined) argument vector. 61716911Seric ** 61816911Seric ** Returns: 61953751Seric ** mapped host name 62051315Seric ** FALSE otherwise. 62116911Seric ** 62216911Seric ** Side Effects: 62316911Seric ** Looks up the host specified in hbuf. If it is not 62416911Seric ** the canonical name for that host, replace it with 62516911Seric ** the canonical name. If the name is unknown, or it 62616911Seric ** is already the canonical name, leave it unchanged. 62716911Seric */ 62810758Seric 62916911Seric /*ARGSUSED*/ 63053751Seric char * 63153751Seric maphostname(hbuf, hbsize, avp) 63216911Seric char *hbuf; 63316911Seric int hbsize; 63453751Seric char **avp; 63516911Seric { 63653751Seric return NULL; 63716911Seric } 63816911Seric 6395978Seric #endif DAEMON 640