Annotation of embedaddon/dhcp/common/resolv.c, revision 1.1.1.1

1.1       misho       1: /* resolv.c
                      2: 
                      3:    Parser for /etc/resolv.conf file. */
                      4: 
                      5: /*
                      6:  * Copyright (c) 2004-2007,2009 by Internet Systems Consortium, Inc. ("ISC")
                      7:  * Copyright (c) 1996-2003 by Internet Software Consortium
                      8:  *
                      9:  * Permission to use, copy, modify, and distribute this software for any
                     10:  * purpose with or without fee is hereby granted, provided that the above
                     11:  * copyright notice and this permission notice appear in all copies.
                     12:  *
                     13:  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
                     14:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     15:  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
                     16:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     17:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     18:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
                     19:  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     20:  *
                     21:  *   Internet Systems Consortium, Inc.
                     22:  *   950 Charter Street
                     23:  *   Redwood City, CA 94063
                     24:  *   <info@isc.org>
                     25:  *   https://www.isc.org/
                     26:  *
                     27:  * This software has been written for Internet Systems Consortium
                     28:  * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
                     29:  * To learn more about Internet Systems Consortium, see
                     30:  * ``https://www.isc.org/''.  To learn more about Vixie Enterprises,
                     31:  * see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
                     32:  * ``http://www.nominum.com''.
                     33:  */
                     34: 
                     35: #include "dhcpd.h"
                     36: 
                     37: struct name_server *name_servers;
                     38: struct domain_search_list *domains;
                     39: char path_resolv_conf [] = _PATH_RESOLV_CONF;
                     40: 
                     41: void read_resolv_conf (parse_time)
                     42:        TIME parse_time;
                     43: {
                     44:        int file;
                     45:        struct parse *cfile;
                     46:        const char *val;
                     47:        int token;
                     48:        struct name_server *sp, *sl, *ns;
                     49:        struct domain_search_list *dp, *dl, *nd;
                     50:        isc_result_t status;
                     51: 
                     52:        if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
                     53:                log_error ("Can't open %s: %m", path_resolv_conf);
                     54:                return;
                     55:        }
                     56: 
                     57:        cfile = NULL;
                     58:        status = new_parse(&cfile, file, NULL, 0, path_resolv_conf, 1);
                     59:        if (status != ISC_R_SUCCESS || cfile == NULL)
                     60:                return;
                     61: 
                     62:        do {
                     63:                token = next_token (&val, (unsigned *)0, cfile);
                     64:                if (token == END_OF_FILE)
                     65:                        break;
                     66:                else if (token == EOL)
                     67:                        continue;
                     68:                else if (token == DOMAIN || token == SEARCH) {
                     69:                        do {
                     70:                                struct domain_search_list *nd, **dp;
                     71:                                char *dn;
                     72: 
                     73:                                dn = parse_host_name (cfile);
                     74:                                if (!dn)
                     75:                                        break;
                     76: 
                     77:                                dp = &domains;
                     78:                                for (nd = domains; nd; nd = nd -> next) {
                     79:                                        dp = &nd -> next;
                     80:                                        if (!strcmp (nd -> domain, dn))
                     81:                                                break;
                     82:                                }
                     83:                                if (!nd) {
                     84:                                        nd = new_domain_search_list (MDL);
                     85:                                        if (!nd)
                     86:                                                log_fatal ("No memory for %s",
                     87:                                                           dn);
                     88:                                        nd -> next =
                     89:                                                (struct domain_search_list *)0;
                     90:                                        *dp = nd;
                     91:                                        nd -> domain = dn;
                     92:                                        dn = (char *)0;
                     93:                                }
                     94:                                nd -> rcdate = parse_time;
                     95:                                token = peek_token (&val,
                     96:                                                    (unsigned *)0, cfile);
                     97:                        } while (token != EOL);
                     98:                        if (token != EOL) {
                     99:                                parse_warn (cfile,
                    100:                                            "junk after domain declaration");
                    101:                                skip_to_semi (cfile);
                    102:                        }
                    103:                        token = next_token (&val, (unsigned *)0, cfile);
                    104:                } else if (token == NAMESERVER) {
                    105:                        struct name_server *ns, **sp;
                    106:                        struct iaddr iaddr;
                    107: 
                    108:                        parse_ip_addr (cfile, &iaddr);
                    109: 
                    110:                        sp = &name_servers;
                    111:                        for (ns = name_servers; ns; ns = ns -> next) {
                    112:                                sp = &ns -> next;
                    113:                                if (!memcmp (&ns -> addr.sin_addr,
                    114:                                             iaddr.iabuf, iaddr.len))
                    115:                                        break;
                    116:                        }
                    117:                        if (!ns) {
                    118:                                ns = new_name_server (MDL);
                    119:                                if (!ns)
                    120:                                    log_fatal ("No memory for nameserver %s",
                    121:                                               piaddr (iaddr));
                    122:                                ns -> next = (struct name_server *)0;
                    123:                                *sp = ns;
                    124:                                memcpy (&ns -> addr.sin_addr,
                    125:                                        iaddr.iabuf, iaddr.len);
                    126: #ifdef HAVE_SA_LEN
                    127:                                ns -> addr.sin_len = sizeof ns -> addr;
                    128: #endif
                    129:                                ns -> addr.sin_family = AF_INET;
                    130:                                ns -> addr.sin_port = htons (53);
                    131:                                memset (ns -> addr.sin_zero, 0,
                    132:                                        sizeof ns -> addr.sin_zero);
                    133:                        }
                    134:                        ns -> rcdate = parse_time;
                    135:                        skip_to_semi (cfile);
                    136:                } else
                    137:                        skip_to_semi (cfile); /* Ignore what we don't grok. */
                    138:        } while (1);
                    139:        token = next_token (&val, (unsigned *)0, cfile);
                    140: 
                    141:        /* Lose servers that are no longer in /etc/resolv.conf. */
                    142:        sl = (struct name_server *)0;
                    143:        for (sp = name_servers; sp; sp = ns) {
                    144:                ns = sp -> next;
                    145:                if (sp -> rcdate != parse_time) {
                    146:                        if (sl)
                    147:                                sl -> next = sp -> next;
                    148:                        else
                    149:                                name_servers = sp -> next;
                    150:                        /* We can't actually free the name server structure,
                    151:                           because somebody might be hanging on to it.    If
                    152:                           your /etc/resolv.conf file changes a lot, this
                    153:                           could be a noticeable memory leak. */
                    154:                } else
                    155:                        sl = sp;
                    156:        }
                    157: 
                    158:        /* Lose domains that are no longer in /etc/resolv.conf. */
                    159:        dl = (struct domain_search_list *)0;
                    160:        for (dp = domains; dp; dp = nd) {
                    161:                nd = dp -> next;
                    162:                if (dp -> rcdate != parse_time) {
                    163:                        if (dl)
                    164:                                dl -> next = dp -> next;
                    165:                        else
                    166:                                domains = dp -> next;
                    167:                        free_domain_search_list (dp, MDL);
                    168:                } else
                    169:                        dl = dp;
                    170:        }
                    171:        end_parse (&cfile);
                    172: }
                    173: 
                    174: /* Pick a name server from the /etc/resolv.conf file. */
                    175: 
                    176: struct name_server *first_name_server ()
                    177: {
                    178:        static TIME rcdate;
                    179:        struct stat st;
                    180: 
                    181:        /* Check /etc/resolv.conf and reload it if it's changed. */
                    182:        if (cur_time > rcdate) {
                    183:                if (stat (path_resolv_conf, &st) < 0) {
                    184:                        log_error ("Can't stat %s", path_resolv_conf);
                    185:                        return (struct name_server *)0;
                    186:                }
                    187:                if (st.st_mtime > rcdate) {
                    188:                        rcdate = cur_time + 1;
                    189:                        
                    190:                        read_resolv_conf (rcdate);
                    191:                }
                    192:        }
                    193: 
                    194:        return name_servers;
                    195: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>