Annotation of embedaddon/dhcp/common/resolv.c, revision 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>